C language implements several operations of linked list [Advanced version]

    Simple linked list operations can no longer satisfy my computer's desire for programming, and its keyboard is already thirsty. The roar of the fan made me feel like I was in Schumacher's car.

    In order to appease my computer, I wrote some more complex linked list operations for it to run. It is also written in C language. code show as below:

#include <stdio.h>
#include <stdlib.h>
typedef char LinkType;

typedef struct LinkNode {
    LinkType data;
    struct LinkNode* next;
} LinkNode;
LinkNode* creat(LinkNode* head,LinkType data){
    LinkNode* l = (LinkNode*)malloc(sizeof(LinkNode));
    l->next = NULL;
    head->next = l;
    head = l;
    l->data = data;
    return l;
}
/**
* @brief 逆序打印单链表. 
* 
* @param head 
*/
void LinkListReversePrint(LinkNode* head){
    if (head == NULL)//非法输入
        return;
    else{
        printf("%d",head->data);
        LinkListReversePrint(head->next);
        }
}

/** 
* @brief 不允许遍历链表, 在 pos之前插入 
* 
* @param head 
* @param pos 
* @param value 
*/
void LinkListInsertBefore(LinkNode** head, LinkNode* pos, LinkType value){
    if (head == NULL)
        return;
    //在pos之前插入value值
    //可以转化为在pos之后插入value
    LinkNode* node = (LinkNode*)malloc((sizeof(LinkNode)));
    node->next = pos->next;
    pos->next = node;
    node->data = pos->data;
    pos->data = value;
    return;
}
/**
* @brief JosephCycle问题
*
* @param head
* @param food
*/
LinkNode* JosephCycle(LinkNode* head, size_t food){
    //判断环是否为空;
    //head->data是每个人的号码
    if (head == NULL)
        return NULL;
    LinkNode* tmp = head;
    LinkNode* add =tmp;
    int count = 1;
    while(tmp->next != head){
        ++count;
        tmp = tmp->next;
    }
    tmp = head;
    while(tmp){
        for (int i = 1; i < food; ++i) {
            if (tmp->data == '0'){
                for (int j = 0; j < count; ++j) {
                    tmp = tmp->next;
                    if (tmp->data != '0')
                        break;
                }
                if (tmp->data == '0'){
                    return add;
                }
            }
            tmp = tmp->next;
        }
        add = tmp;
        tmp->data = '0';
    }
}

/** 
* @brief 单链表逆置 
* 
* @param head 
*/
void LinkListReverse(LinkNode* head){
    if (head == NULL)
        return;
    LinkNode*tmp = NULL;
    LinkNode* p = head->next;
    LinkNode* new = head;
    while(p){
        //头插元素
        tmp = p->next;
        p->next = new->next;
        new->next = p;
        p = tmp;
    }
}
LinkNode* LinkListReverse2(LinkNode* head){
    if (head->next == NULL)
        return head;
    LinkNode *Preturn = LinkListReverse2(head->next);
    head->next->next = head;
    head->next = NULL;
    return Preturn;
}

/** 
* @brief 单链表的冒泡排序 
* 
* @param head 
*/
void LinkListBubbleSort(LinkNode* head,int n){
    if (head == NULL)
        return;
    LinkNode* t = head->next;
    for (int i = 0; i < n -1; ++i) {
        LinkNode* l = t;
        for (int j = 0; j < n-i; ++j) {

            if (l->data > l->next->data){
                LinkType tmp = l->data;
                l->data = l->next->data;
                l->next->data = tmp;
            }
            l = l->next;
        }
        t = t->next;
    }
}

/** 
* @brief 将两个有序链表, 合并成一个有序链表 
* 
* @param head1 
* @param head2 
* 
* @return 
*/
LinkNode* LinkListMerge(LinkNode* head1, LinkNode* head2){
    if (head1 == NULL)
        return head2;
    if (head2 == NULL)
        return head1;
    //创建一个新的头节点指针。
    LinkNode* new_head = (LinkNode*)malloc(sizeof(LinkNode));
    LinkNode* p1 = head1;
    LinkNode* p2 = head2;
    LinkNode* HH = new_head;
    while ((p1 != NULL) && (p2 != NULL)){
        if (p1->data > p2->data){
            new_head->next = p2;
            p2 = p2->next;
            new_head = new_head->next;
        }else if (p1->data < p2->data){
            new_head->next = p1;
            p1 = p1->next;
            new_head = new_head->next;
        } else{
            new_head->next = p2;
            p2 = p2->next;
            new_head = new_head->next;

            new_head->next = p1;
            p1 = p1->next;
            new_head = new_head->next;
        }
    }
    if (p1 != NULL){
        new_head->next = p1;
    }
    if (p2 != NULL){
        new_head->next = p2;
    }
    free(head1);
    free(head2);
    return HH;
}

LinkNode* FindMidNode(LinkNode* head){
    if (head == NULL)
        return NULL;
    LinkNode* fast = head;
    LinkNode* slow = head;
    while((fast != NULL) && (fast->next != NULL)){
        fast == fast->next->next;
        slow == slow->next;
    }
    return slow;
}

/** 
* @brief 找到倒数第 K 个节点. 
* 
* @param head 
* 
* @return 
*/
LinkNode* FindLastKNode(LinkNode* head, size_t K){
    if (head == NULL)
        return NULL;
    LinkNode* fast = head;
    LinkNode* slow = head;
    for (int i = 1; i < K; ++i) {
        if (fast == NULL)
            return NULL;
        fast = fast->next;
    }
    while(fast != NULL){
        fast = fast->next;
        slow = slow->next;
    }
    return slow;
}

/** 
* @brief 删除倒数第K个节点 
* 
* @param head 
* @param K 
*/
void EraseLastKNode(LinkNode** head, size_t K){
    if (head == NULL)
        return ;
    LinkNode* fast = head;
    LinkNode* slow = head;
    for (int i = 0; i < K; ++i) {
        if (fast == NULL)
            return ;
        fast = fast->next;
    }
    while(fast->next != NULL){
        fast = fast->next;
        slow = slow->next;
    }
    LinkNode* to_delete = slow->next;
    slow->next = slow->next->next;
    free(to_delete);
    return;
}

/** 
* @brief 判定单链表是否带环. 如果带环返回1 
* 
* @param head 
* 
* @return 
*/
LinkNode* HasCycle(LinkNode* head){
    if (head == NULL)
        return NULL;
    LinkNode* fast = head;
    LinkNode* slow = head;
    while((fast->next != NULL) && (fast != NULL)){
        fast = fast->next->next;
        slow = slow->next;
        if (slow == fast)
            return slow;
    }
    return NULL;
}

/** 
* @brief 如果链表带环, 求出环的长度 
* 
* @param head 
* 
* @return 
*/
size_t GetCycleLen(LinkNode* head){
    LinkNode* L = HasCycle(head);
    if (L == NULL)
        return 0;
    LinkNode* p = L->next;
    size_t count = 1;
    while(p != L){
        ++count;
        p = p->next;
    }
    return count;
}

/** 
* @brief 如果链表带环, 求出环的入口 
* 
* @param head 
* 
* @return 
*/
LinkNode* GetCycleEntry(LinkNode* head){
    LinkNode* L = HasCycle(head);
    if (L == NULL)
        return 0;
    LinkNode* star = head;
    LinkNode* entr = L;
    while(star != entr){
        star = star->next;
        entr = entr->next;
    }
    return star;
}

/** 
* @brief 判定两个链表是否相交, 并求出交点 
* 
* @param head1 
* @param head2 
* 
* @return 
*/
LinkNode* HasCross(LinkNode* head1, LinkNode* head2){//本次仅讨论两个链表非环的情况
    if (head1 == NULL)
        return head2;
    if (head2 == NULL)
        return head1;
    //两个非环链表的相交仅有y的样子一种情况
    LinkNode* p = head1;
    while (p->next != NULL){
        p = p->next;
    }
    LinkNode* tmp = p;
    p->next = head2;
    LinkNode* intersection = GetCycleEntry(head1);
    tmp->next = NULL;
    return intersection;
}
/**
* @brief 判定两个链表是否相交. 但是链表可能带环
*
* @param head1
* @param head2
*
* @return 如果相交, 返回1, 否则返回0
*/
int HasCrossWithCycle(LinkNode* head1, LinkNode* head2){
    LinkNode* star1 = GetCycleEntry(head1);
    LinkNode* star2 = GetCycleEntry(head2);
    if ((star1 != NULL)&&(star2 != NULL)){//如果两个都带环
        if (star1 == star2)//两环入口相等时
            return 1;

        LinkNode* p = star1->next;//两环入口不等时
        while (p != star1){
            if (p == star2)
                return 1;
        }
        return 0;
    } else{//只有一个带环不可能相交
        return 0;
    }
}

/**
* @brief 求两个有序链表的交集
*
* @param head1
* @param head2
*
* @return 返回表示交集的新链表
*/
LinkNode* UnionSet(LinkNode* head1, LinkNode* head2){
    if (head1 == NULL)
        return head2;
    if (head2 == NULL)
        return head1;
    //创建一个新的头节点指针。
    LinkNode* new_head = (LinkNode*)malloc(sizeof(LinkNode));
    LinkNode* p1 = head1;
    LinkNode* p2 = head2;
    LinkNode* HH = new_head;
    while ((p1 != NULL) && (p2 != NULL)){
        if (p1->data > p2->data){
            p2 = p2->next;
        }else if (p1->data < p2->data){
            p1 = p1->next;
        } else{
            new_head->next = p2;
            p2 = p2->next;
            new_head = new_head->next;
            p1 = p1->next;
        }
    }
    return HH;
}

typedef struct ComplexNode {
    LinkType data;
    struct ComplexNode* next;
    struct ComplexNode* random;
} ComplexNode;

/**
* @brief 拷贝复杂链表
*
* @param head
*
* @return
*/
ComplexNode* CopyComplex(ComplexNode* head){
    //创建一个链表的每个节点的复制
    if (head == NULL)
        return NULL;
    ComplexNode* p = head;
    while(p != NULL){//完成复制
        ComplexNode* L = (ComplexNode*)malloc(sizeof(ComplexNode));
        L->next = p->next;
        L->data = p->data;
        p->random = NULL;
        ComplexNode* tmp = p->next;
        p->next = L;
        p = tmp;
    }
    p = head;
    while(p->next != NULL){//完成赋值
        p->next->random = p->random->next;
        p = p->next->next;
    }
    ComplexNode* new_head = (ComplexNode*)malloc(sizeof(ComplexNode));
    ComplexNode* fast = new_head;
    p = head;
    while(p->next == NULL){
        fast->next =  p->next->next;
        fast = fast->next;
        p = p->next->next;
    }
    return new_head;

}


Guess you like

Origin blog.csdn.net/xiagu_jinchengwu/article/details/79846797