美文网首页
单循环链表

单循环链表

作者: lxr_ | 来源:发表于2022-03-05 15:50 被阅读0次

    单循环链表:将单链表中终端结点的next域由空指针改为指向头结点,就使得整个单链表形成一个环,这种头尾相接的单链表称为单循环链表。
    如下图所示

    单循环链表
    1.循环链表和单链表的主要差异在于循环的判断条件上,原来是判断p->next是否为空,现在则是p->next是否为头结点
    2.选择不用头指针,而是用指向终端结点的尾指针rear来表示循环链表,则查找开始结点和终端结点都很方便快捷

    LinkList_cycle.h

    #pragma once
    
    // 函数结果状态代码
    #define OK      1
    #define ERROR   0
    #define INFEASIBLE  -1
    #define OVERFLOW    -2
    
    //Status 是函数的类型,其值是函数结果状态代码
    typedef int Status;
    
    //数据类型
    typedef int ElemType;
    
    typedef struct LNode
    {
        ElemType data;
        LNode* next;
    
    }LNode, * LinkList_cycle;
    
    //初始化链表
    Status InitList_cycle(LinkList_cycle& L);
    
    //判空
    bool ListEmpty_cycle(LinkList_cycle L);
    
    //销毁单链表(包括头结点在内的所有结点)
    Status DestroyList_cycle(LinkList_cycle& L);
    
    //遍历单循环链表
    void ListTraverse_cycle(LinkList_cycle L);
    
    //头插法建立单循环链表(返回尾指针)
    LinkList_cycle CreateList_cycle_H(LinkList_cycle& L_H, int n);
    
    //尾插法建立单循环链表(返回尾指针)
    LinkList_cycle CreateList_cycle_T(LinkList_cycle& L_T, int  n);
    
    //合并两个用尾指针表示的单循环链表,合并后将另一个销毁
    void Connect(LinkList_cycle& rear_H, LinkList_cycle& rear_T);
    

    LinkList_cycle.cpp

    #include "LinkList_cycle.h"
    #include <iostream>
    using namespace std;
    
    //初始化链表
    Status InitList_cycle(LinkList_cycle& L)
    {
        L = new LNode;
        L->next = L;    //与单链表不同的是其头结点的next域指向头结点,而单链表的情况是指向NULL
    
        cout << "初始化循环链表成功" << endl;
        return OK;
    }
    
    //判空
    bool ListEmpty_cycle(LinkList_cycle L)
    {
        if (L)                  //头结点存在
        {
            if (L->next == L)   //第一个结点不存在
            {
                cout << "循环链表为空" << endl;
                return true;
            }
            else
            {
                cout << "循环链表不为空" << endl;
                return false;
            }
        }
        else
        {
            cout << "循环链表不存在" << endl;
            return true;
        }
    }
    
    //销毁单循环链表(包括头结点在内的所有结点)
    //需要根据头结点判断循环结束条件,先删除除头结点之外的所有结点,再删除头结点
    Status DestroyList_cycle(LinkList_cycle& L)
    {
    
        LNode* p = L->next;                 //第一个结点
        LNode* q;
        while (p != L)              //结束条件为p=头结点
        {
            q = p->next;
            delete p;
            p = q;
        }
        delete L;
        cout << "销毁成功" << endl;
        return OK;
    }
    
    //遍历单循环链表
    void ListTraverse_cycle(LinkList_cycle L)
    {
        LNode* p = L->next;
        while (p != L)
        {
            cout << p->data << " ";
            p = p->next;
        }
        cout << endl;
    }
    
    //头插法建立单循环链表,并返回此链表的尾指针
    LinkList_cycle CreateList_cycle_H(LinkList_cycle& L_H, int n)
    {
        L_H = new LNode;
        L_H->next = L_H;                //单循环链表空表
    
        LNode* rear = L_H;              //开始时尾指针指向头结点
        for (int i = n; i > 0; i--)
        {
            LNode* p = new LNode;       //建立新结点
            p->data = i;
            p->next = L_H->next;        //新结点的next域指向原来头结点的next域指向的结点
            L_H->next = p;              //头结点的next域指向新结点
            if (p->next == L_H)         //如果p的next域指向的结点为头结点
            {
                rear = p;               //更新尾指针
            }
        }
        return rear;
    }
    
    //尾插法建立单循环链表(返回尾指针)
    LinkList_cycle CreateList_cycle_T(LinkList_cycle& L_T, int  n)
    {
        L_T = new LNode;
        L_T->next = L_T;                //单循环链表的空表
    
        LNode* rear = L_T;              //记录尾指针,开始就为头结点
        for (int i = 1; i <= n; i++)
        {
            LNode* p = new LNode;       //建立新结点
            p->data = i + 5;
            p->next = rear->next;       //新结点指向头结点,即尾指针的next域指向的结点
            rear->next = p;             //原来尾指针指向的next域为新结点
            rear = p;                   //尾指针更新为指向新结点
        }
        return rear;
    }
    

    两个单循环链表合并:


    合并

    1.保存第一个链表的头结点
    2.第一个链表尾指针的next域指向第二个链表的第一个结点
    3.第二个链表的尾指针的next域指向第一个链表的头结点

    //合并两个用尾指针表示的单循环链表到第一个链表中
    void Connect(LinkList_cycle& rear_H, LinkList_cycle& rear_T)
    {
        LinkList_cycle L_H = rear_H->next;      //第一个链表的头结点
        rear_H->next = rear_T->next->next;      //第一个链表的尾指针的next域指向第二个链表的第一个结点
        rear_T->next = L_H;                     //第二个链表的尾指针指向第一个链表的头结点
    
        cout << "合并成功" << endl;
    }
    

    main.cpp

    测试:

    #include "LinkList_cycle.h"
    
    #include <iostream>
    using namespace std;
    
    int main(int argc, char** argv)
    {
        LinkList_cycle L;
    
        InitList_cycle(L);                  //初始化单循环链表
        ListEmpty_cycle(L);                 //判空
        DestroyList_cycle(L);               //销毁
    
        LinkList_cycle L_H;
        LNode* rear_H = CreateList_cycle_H(L_H, 5);     //头插法创建
        ListTraverse_cycle(L_H);                        //遍历
        cout << "单循环链表第一个结点:" << rear_H->next->next->data << endl;
    
        LinkList_cycle L_T;
        LNode* rear_T = CreateList_cycle_T(L_T, 5);     //尾插法创建
        ListTraverse_cycle(L_T);                        //遍历
        cout << "单循环链表第一个结点:" << rear_T->next->next->data << endl;
    
        Connect(rear_H, rear_T);                        //合并两个链表到rear_H中
        ListTraverse_cycle(rear_T->next);               //遍历合并后的链表
        ListTraverse_cycle(L_H);                        //遍历合并后的链表
    
        DestroyList_cycle(L_T);                         //销毁第二个链表
    
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:单循环链表

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