美文网首页数据结构
线性表 - 循环链表

线性表 - 循环链表

作者: 挽弓如月_80dc | 来源:发表于2019-10-30 11:06 被阅读0次
    1.引子
    单链表解决了从A 查找到E的过程,假设现在要求从E 查找到A,用时最短,
    因为单链表是单向的,只能从前往后,无法解决这个问题。因此引出了循环链表。
    
    思路图
    将单链表的终端结点的指针由空指针改为头结点,就使整个单链表形成一个环。
    这种头尾相接的单链表成为单循环链表,简称循环链表
    
    循环链表和单链表的主要差异就在于循环判断条件上,原来是判断p->next 是否为空,
    现在则是p->next 不等于头结点。则循环未结束
    
    2.循环链表的使用
    #include <stdio.h>
    #include <stdlib.h>
    
    
    #define OK 1
    #define ERROR 0
    #define TRUE 1
    #define FALSE 0
    
    typedef int Status;
    typedef int ElemType;
    typedef struct node {
        ElemType data;
        struct node *next;
    } Node,*LinkList;
    
    
    /** 初始化链表 next指向自身*/
    void Init_circleList(LinkList *list) {
        (*list) = (LinkList)malloc(sizeof(Node));
        (*list)->next = *list;
    }
    
    
    /** 从1开始 创建n个数据 */
    void create_circlrList(LinkList list, int n) {
        LinkList rear, s;
        rear = list;
    
        for (int i = 1; i <= n; i++) {
            s = (LinkList) malloc(sizeof(Node));
            s->data = I;
            rear->next = s;
            rear = s;
        }
        rear->next = list;
    }
    
    
    /** 获得链表的长度 */
    int get_circle_list_Length(LinkList list) {
        LinkList headr = list->next;
        int count =0;
        while (headr != list) {
            headr = headr->next;
            count++;
        }
        return count;
    }
    
    
    /** 在某个位置插入某个元素*/
    Status insert_circleList(LinkList list, int i, ElemType e) {
        
        if (i < 0 ) {
            return ERROR;
        }
        
        LinkList headr = list;
        LinkList node = (LinkList)malloc(sizeof(Node));
        node->data = e;
        
        //区分中间插入 or  尾部插入 or 头插
        if (i == 0) {
            node->next = headr->next;
            headr->next = node;
        } else if(i == get_circle_list_Length(list)+1) {
            
            while (headr->next != list) {
                headr = headr->next;
            }
            headr->next = node;
            node->next = list;
            
        } else {
            for (int k = 1; k < i; k++) {
                headr = headr->next;
            }
            node->next = headr->next;
            headr->next = node;
        }
        return OK;
    }
    
    /** 删除某一个元素 需要考虑头、尾、中间*/
    Status delete_Node_circleList(LinkList list, int kill) {
        LinkList header = list;
        LinkList deleteNodel;
        
        int currentAllCount = get_circle_list_Length(list);
        
        if (kill > currentAllCount) {
            return ERROR;
        }
        if (kill == 0) {
            deleteNodel = header->next;
            header->next = deleteNodel->next;
            free(deleteNodel);
        } else if (kill == currentAllCount) {
            
            for (int i = 1; i < currentAllCount; i++) {
                header = header->next;
            }
            deleteNodel = header->next;
            header->next = deleteNodel->next;
            
            free(deleteNodel);
            
        } else {
            
            for (int i = 1; i < kill; i++) {
                header = header->next;
            }
            deleteNodel = header->next;
            header->next = deleteNodel->next;
            free(deleteNodel);
        }
        return OK;
    }
    
    
    /** 遍历链表*/
    void Iteretor_circleList(LinkList list) {
        
        LinkList headr = list->next;
        while (headr != list) {
            printf("+++ current data is %d\n",headr->data);
            headr = headr->next;
        }
    }
    
    
    #pragma mark - 使用
    void k_circleNodel(void) {
        LinkList list;
        Init_circleList(&list);
        create_circlrList(list, 10);
        Iteretor_circleList(list);
        
        printf("\n\n");
        insert_circleList(list, 4, 13);
        Iteretor_circleList(list);
        
        printf("\n\n");
        delete_Node_circleList(list, 10);
        Iteretor_circleList(list);
    }
    
    
    3.将两个单链表合并成一个循环链表
    两个单链表 合并流程
    整个过程需要借助一个指针作为临时变量,并祛除一个的头结点
    
    1.p = rearA -> next;    //保存A的头结点
    2.rearA->next = rearB->next-next;
    //将本是指向B的第一个结点(不是头结点) 赋值给rearA->next
    3.rearB->next = p; //将原A表的头结点赋值给rearB->next
    4.free(p);
    

    相关文章

      网友评论

        本文标题:线性表 - 循环链表

        本文链接:https://www.haomeiwen.com/subject/snanvctx.html