4、循环链表

|   版权声明:本文为博主原创文章,未经博主允许不得转载。

  1、知识点:

    (1)、循环链表其实就是将单项链表的首尾连接起来。就是在链表的尾部添加一个指向头节点的指针(及在结束节点的next域中

的NULL值改成指向头节点的指针就行了)。

    (2)、存在一个尾指针rear,在一些实际的例子中使用rear指针作为开始节点的情况是比较常见的。

    (3)、图示(图片摘自百度)

>>.分布代码

  (1)、头插法创建循环链表(只带头指针的循环链表)

  (2)、创建只带尾指针的循环链表(个人认为这个比较的好,当然在相应的情况下还是采取合适的解决方法)

  (3)、循环链表是否为空

  (4)、打印函数

  (5)、链表的整合

  (6)、销毁链表

(7)、说明

在循环链表,一些关于增删改对链表的操作和前面的几节博客中的思路是一样一样的。

>>.全部代码

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4
  5 using namespace std;
  6
  7 #define OK                1
  8 #define ERROR            0
  9 #define OVERFLOW        -1
 10
 11 typedef int STATUS;
 12 typedef int ElemType;
 13
 14 //创建循环链表的结构体
 15 typedef struct CycleChain
 16 {
 17     struct CycleChain* next;
 18     ElemType data;
 19 }cycleChain;
 20
 21 //尾指针法创建循环链表,其实这是一个尾插法创建链表的方法
 22 cycleChain* createCycleChain(cycleChain** headNode, cycleChain* rearNode, ElemType elem)
 23 {
 24     //创建链表前判断headNode是否创建过。
 25     if((*headNode)==NULL && rearNode==NULL)
 26     {
 27         //没有创建headNode
 28         (*headNode) = (cycleChain*) malloc(sizeof(cycleChain));
 29         if(!(*headNode))
 30         {
 31             cout << "The head node is create faliure of cycle chain, Error!" << endl;
 32             exit(OVERFLOW);
 33         }
 34         (*headNode)->next = (*headNode);
 35         rearNode = (*headNode);
 36     }
 37
 38     //创建新的节点,并插入链表
 39     cycleChain* newNode = NULL;
 40     newNode = (cycleChain*) malloc(sizeof(cycleChain));
 41     if(!newNode)
 42     {
 43         cout << "The new node is create failure of cycle chain, Error!" << endl;
 44         exit(OVERFLOW);
 45     }
 46     newNode->data = elem;
 47
 48     newNode->next = rearNode->next;
 49     rearNode->next = newNode;
 50     rearNode = newNode;
 51
 52
 53     return rearNode;
 54 }
 55
 56 //判断循环链表是否为空
 57 bool emptyCycleChain(cycleChain* headNode)
 58 {
 59     if(headNode->next == headNode)
 60         return true;
 61         //cout << "The cycle chain is empty!" << endl;
 62     else
 63         return false;
 64         //cout << "The cycke chain is not empty!" << endl;
 65 }
 66
 67
 68 //打印循环链表
 69 STATUS printCycleChain(cycleChain* headNode)
 70 {
 71     //首先判断此链表是否为空
 72     if(emptyCycleChain(headNode))
 73     {
 74         cout << "The cycle chain is empty, without data to printf!" ;
 75         return ERROR;
 76     }
 77     cycleChain* ptrNode;
 78     ptrNode = headNode->next;
 79     cout << "Cycle chain list:  ";
 80     while(ptrNode!=headNode)
 81     {
 82         cout << ptrNode->data << ", ";
 83         ptrNode = ptrNode->next;
 84     }
 85     return OK;
 86 }
 87
 88 //两个循环链表的整合
 89 STATUS connectionCycleChain(cycleChain* rearNode_A, cycleChain* rearNode_B)
 90 {
 91     //将b表接到a表之后
 92     cycleChain* ptrNode = NULL;
 93     cycleChain* tmpNode = NULL;
 94
 95     tmpNode = rearNode_B->next;
 96     ptrNode = rearNode_A->next;    //ptrNode指向头节点A
 97
 98     //开始连接两表
 99     rearNode_A->next = tmpNode->next;
100     rearNode_B->next = ptrNode;
101     free(tmpNode);
102     return OK;
103 }
104
105 //销毁循环链表
106 STATUS destroyCycleChain(cycleChain* headNode, cycleChain* rearNode)
107 {
108     cycleChain* ptrNode = NULL;
109     cycleChain* tmpNode = NULL;
110
111     if(headNode->next==headNode)
112     {
113         //这里说明只有一个头节点的链表
114         free(headNode);
115         return OK;
116     }
117
118     tmpNode = headNode;
119     while(tmpNode != rearNode)
120     {
121         ptrNode = tmpNode->next;
122         free(tmpNode);
123         tmpNode = ptrNode;
124     }
125     return OK;
126 }
127
128 int main(void)
129 {
130     cout << "1:  创建循环链表" << endl;
131     cout << "2:  打印循环链表" << endl;
132     cout << "3:  判断链表为空" << endl;
133     cout << "4:  链表的整合" << endl;
134     cout << "5:  销毁循环链表" << endl;
135     cout << "0:  退出程序" << endl << endl << endl;
136
137     int choice = 0;
138     int amount = 0;
139     int i = 0;
140     int elem = 0;
141     cycleChain* headNode = NULL;
142     cycleChain* rearNode = NULL;
143
144     cycleChain* headNode_A = NULL;
145     cycleChain* headNode_B = NULL;
146     cycleChain* rearNode_A = NULL;
147     cycleChain* rearNode_B = NULL;
148
149     while(1)
150     {
151         cout << "Enter you choice: ";
152         cin >> choice;
153
154         switch(choice)
155         {
156         case 1:
157             cout << "Enter amount of chain node: ";
158             cin >> amount;
159             cout << "Please enter the " << amount << " elem: ";
160             for(i=0; i<amount; i++)
161             {
162                 cin >> elem;
163                 rearNode = createCycleChain(&headNode, rearNode, elem);
164             }
165             cout << endl;
166             break;
167         case 2:
168             cout << "Print List: " << endl;
169             printCycleChain(headNode);
170             cout << endl << endl;;
171             break;
172         case 3:
173             cout << "The cycle chain if is empty:  ";
174             if(emptyCycleChain(headNode))
175                 cout << "Yes !" << endl;
176             else
177                 cout << "No !" << endl;
178             cout << endl;
179             break;
180         case 4:
181             cout << "Please enter first cycle chain of data:  " << endl;
182             cout << "Enter amount of chain node: ";
183             cin >> amount;
184             cout << "Please enter the " << amount << " elem: ";
185             for(i=0; i<amount; i++)
186             {
187                 cin >> elem;
188                 rearNode_A = createCycleChain(&headNode_A, rearNode_A, elem);
189             }
190
191             cout << "Please enter second cycle chain of data:  " << endl;
192             cout << "Enter amount of chain node: ";
193             cin >> amount;
194             cout << "Please enter the " << amount << " elem: ";
195             for(i=0; i<amount; i++)
196             {
197                 cin >> elem;
198                 rearNode_B = createCycleChain(&headNode_B, rearNode_B, elem);
199             }
200             connectionCycleChain(rearNode_A, rearNode_B);
201             printCycleChain(headNode_A);
202             cout << endl << endl;
203             break;
204         case 5:
205             cout << "The cycle chain destory status:  ";
206             if(destroyCycleChain(headNode, rearNode))
207                 cout << "successful!" << endl;
208             else
209                 cout << "failure!" << endl;
210             cout << endl;
211             break;
212         case 0:
213             exit(0);
214             break;
215         }
216     }
217
218     return 0;
219 }

运行截图:

时间: 2024-10-17 22:09:59

4、循环链表的相关文章

循环链表

?? 循环链表和单链表没有本质上的区别.唯一不同的链表的最后不再是空的了,而是指向了first头指针.仅仅有这样我们才会实现链表的循环功能,那么问题来了,我们在以下的函数功能中我们仅仅是须要把里面用的头指针的重用名换到first->next中.并且当中的计数器count也从1開始计数,这样就避免了在while的循环中第一步实行不下去. 废话不多说. 具体看wo的代码吧. #ifndef CirLinkList_H #define CirLinkList_H #include<iostream&

第33课 双向循环链表的实现

1. DTLib中双向链表的设计思路 (1)数据结点之间在逻辑上构成双向循环,这有别于Linux内核链表的实现. (2)头结点仅用于结点的定位,而Linux内核链表是将头结点作为循环的一部分. 2. 实现思路 (1)通过模板定义DualCircleList类,继承自DualLinkList类 (2)在DualCircleList内部使用Linux内核链表进行实现(另类实现) (3)使用struct list_head定义DualCircleList的头结点 (4)特殊处理:循环遍历时忽略头结点

C++__循环链表(练习)

循环链表 link.h #ifndef LINK_H_ #define LINK_H_ #define HEADER 0 #define TAIL -1 typedef int data_type; enum LINK_OP { LINK_ERR = -1, LINK_OK }; class LINK { private: data_type data; LINK *next; LINK *last; public: LINK(); LINK(data_type data); virtual ~

双向循环链表 初始化 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(DuLNode)

循环链表的基本操作

循环链表与普通链表最大的区别在于尾结点的指针域指向什么:普通链表的尾结点的指针域指向空(NULL),而循环链表的尾结点的指针域指向头结点,形成一个环! #include<iostream> #include<cstdlib> using namespace std; struct Node{ int data; Node* next; }; typedef Node* LinkList; //函数声明 void show(); void InitList(LinkList &

(线性结构)循环链表的初始化,增删减除结点。新手的了解

1.查找rear指针为O(1) 那么开始节点就为rear->next->next,也是O(1)   //大家可以想象从最后一个结点开始有什么好处2.head->next ==head 判断是否空表 //链表的定义 typedef struct CLinkList { ElemType data; struct CLinkList; } node ; 1 //插入结点 2 void ds_insert (node **pNode,int i) 3 { 4 node *temp; 5 nod

双向循环链表

//双向循环链表 typedef int datatype; //方便修改 //当然也可以写成模板来适应更多的数据类型 struct dclink{ datatype data;//数据定义 struct dclink *pre; struct dclink *next;//前驱和后继指针 }; class DCLink { public: DCLink();//default constructor DCLink(datatype data);//单参constructor void add(

算法导论13:双向循环链表 2016.1.13

今天这个又打了很长时间,本来觉得数据结构就是那样,不过是一种思维,但是实际上真正自己打和想象中差距还是很大,需要考虑到各种细节. 今天这个问题有一个比较有意思的应用,就是“约瑟夫环问题”. 具体可以参见百度百科: http://baike.baidu.com/link?url=poA1Aanlptc6yzP1puYhSw_0RQjRAplhPfHwk6eoiqMNxw6WigCEbexxZ8a9SUbrMGokpPbKNzVYw308xjeEw_ 读完问题就可以发现,这个问题用链表就是一个很完美

循环链表模板

#include <stdio.h> #include <stdlib.h> typedef struct lnode{ int data; struct lnode* next; } node,*linklist; void initlist(linklist &l){ linklist p=(linklist)malloc(sizeof(node)); p->next=p;//此处可以控制循环链表 l=p; } void InsertFront(linklist

链表(五)——单向循环链表

1.单向循环链表 区分单向链表和单向循环链表:单向循环链表的尾指针指向头结点. 2.单向循环链表的基本操作 #include <stdio.h> #include <malloc.h> #define NULL 0 typedef struct node { int data; struct node *next; }ElemSN; ElemSN * creat_link(int ms); //创建一个单向循环链表 void print_link(ElemSN *head); //