C/C++实现单向循环链表(尾指针,带头尾节点)

  C语言实现单向循环链表,主要功能为空链表创建,链表初始化(头插法,尾插法),链表元素读取,按位置插入,(有序链表)按值插入,按位置删除,按值删除,清空链表,销毁链表。

  单向循环链表和单向链表的区别:(1)单向链表为头指针,循环链表为尾指针,头指针指向头结点,尾指针指向终端结点;(2)为统一方便操作,单向链表设置头结点,单向循环链表设置头结点和尾结点;(3)设置尾结点后,尾指针指向尾结点,插入,删除等操作不用移动尾指针。

  关键思路:创建头结点和尾结点。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 typedef struct Node{
  5     int data;
  6     struct Node *next;
  7 }Node;
  8 
  9 //空循环链表创建
 10 //创建头结点和尾结点
 11 //链表尾指针指向尾结点,尾结点指向头结点,头结点指向尾结点
 12 void iniCList(Node **CListTail){
 13     *CListTail = (Node *)malloc(sizeof(Node));
 14     Node *CListHead = (Node *)malloc(sizeof(Node));
 15     if (NULL == *CListTail || NULL == CListHead){
 16         exit(0);
 17     }
 18 
 19     (*CListTail)->next = CListHead;
 20     CListHead->next = *CListTail;
 21 }
 22 
 23 //循环链表初始化(头插法)
 24 void iniCListHead(Node **CListTail, int n){
 25     //创建头尾结点
 26     *CListTail = (Node *)malloc(sizeof(Node));
 27     Node *CListHead = (Node *)malloc(sizeof(Node));
 28     if (NULL == *CListTail || NULL == CListHead){
 29         exit(0);
 30     }
 31 
 32     (*CListTail)->next = CListHead;
 33     CListHead->next = *CListTail;
 34 
 35     int i = 0;
 36     while (i < n){
 37 
 38         Node *tmpNode = (Node *)malloc(sizeof(Node));
 39         if (NULL == tmpNode){
 40             exit(0);
 41         }
 42         tmpNode->data = i;
 43         tmpNode->next = CListHead->next;
 44         CListHead->next = tmpNode;
 45         ++i;
 46     }
 47 }
 48 
 49 //循环链表初始化(尾插法)
 50 void iniCListTail(Node **CListTail, int n){
 51     //创建头尾结点
 52     *CListTail = (Node *)malloc(sizeof(Node));
 53     Node *CListHead = (Node *)malloc(sizeof(Node));
 54     if (NULL == *CListTail || NULL == CListHead){
 55         exit(0);
 56     }
 57 
 58     (*CListTail)->next = CListHead;
 59     CListHead->next = *CListTail;
 60 
 61     Node *pCurrent = CListHead;
 62 
 63     int i = 0; 
 64     while (i < n){
 65         Node *tmpNode = (Node *)malloc(sizeof(Node));
 66         if (NULL == tmpNode){
 67             exit(0);
 68         }
 69         tmpNode->data = i;
 70         tmpNode->next = *CListTail;
 71         pCurrent->next = tmpNode;
 72         pCurrent = tmpNode;
 73 
 74         ++i;
 75     }
 76 }
 77 
 78 //循环链表按位置插入
 79 void insertCListPos(Node *CList, int pos, int val){
 80 
 81     Node *pCurrent = CList->next; //指向头结点
 82     int i = 1;
 83     while (pCurrent != CList && i < pos){
 84         pCurrent = pCurrent->next;
 85         ++i;
 86     }
 87 
 88     Node *tmpNode = (Node *)malloc(sizeof(Node));
 89     if (NULL == tmpNode){
 90         exit(0);
 91     }
 92     tmpNode->data = val;
 93     tmpNode->next = pCurrent->next;
 94     pCurrent->next = tmpNode;
 95 
 96 }
 97 
 98 //有序循环链表,按值插入
 99 void insertCListValue(Node *CList, int val){
100     Node *pCur = CList->next->next;
101     Node *pPer = CList->next;
102 
103     while (pCur != CList && pCur->data < val){
104         pPer = pCur;
105         pCur = pCur->next;
106     }
107 
108     Node *tmpNode = (Node *)malloc(sizeof(Node));
109     if (NULL == tmpNode){
110         exit(0);
111     }
112     tmpNode->data = val;
113     tmpNode->next = pPer->next;
114     pPer->next = tmpNode;
115 }
116 
117 //循环链表,按位置删除
118 void deleteCListPos(Node *CList, int pos){
119     Node *pCur = CList->next;
120     
121     int i = 1;
122     while (pCur != CList && i < pos){
123         pCur = pCur->next;
124         ++i;
125     }
126 
127     Node *tmpNode = pCur->next;
128     pCur->next = tmpNode->next;
129     free(tmpNode);
130 }
131 
132 //循环链表,按值删除
133 //删除空链表为出问题
134 void deleteCListValue(Node *CList, int val){
135     Node *pCur = CList->next->next;
136     Node *pPer = CList->next;
137 
138     while (pCur != CList && pCur->data != val){
139         pPer = pCur;
140         pCur = pCur->next;
141     }
142     if (pCur == CList)
143         return;
144     else{
145         pPer->next = pCur->next;
146         free(pCur);
147     }
148 }
149 
150 //循环链表,清空链表
151 void claerCList(Node *CList){
152     Node *p = CList->next->next;
153     Node *q = NULL;
154 
155     while (p != CList){ //到达表尾
156         q = p->next;
157         free(p);
158         p = q;
159     }
160 
161     CList->next = CList; //将头结点指向尾结点
162 }
163 
164 //循环链表,销毁链表
165 void destoryCList(Node **CList){
166     Node *p = (*CList)->next;
167     Node *q = NULL;
168 
169     while (p != (*CList)->next){ //到达表头
170         q = p->next;
171         free(p);
172         p = q;
173     }
174 
175     *CList = NULL;
176 }
177 
178 //获取元素
179 void getCList(Node *CList, int pos, int *val){
180     Node *pCur = CList->next->next;
181     int i = 1;
182     while (pCur != CList && i < pos){
183         pCur = pCur->next;
184         ++i;
185     }
186 
187     *val = pCur->data;
188 }
189 //遍历输出元素
190 void printCList(Node *CList){
191     Node * tmpNode = CList->next->next;
192     while (tmpNode != CList){ //到达表尾
193         printf("%d\n", tmpNode->data);
194         tmpNode = tmpNode->next;
195     }
196 }
197 
198 
199 int main(){
200     Node *CList = NULL;
201     //iniCListHead(&CList, 8);
202     //iniCList(&CList);
203     iniCListTail(&CList, 8);
204 
205     //insertCListPos(CList, 1, 2);
206     //insertCListPos(CList, 2, 4);
207     //insertCListPos(CList, 3, 6);
208     //
209     //insertCListValue(CList, 1);
210     //
211     //deleteCListPos(CList, 3);
212     //
213     //deleteCListValue(CList, 6);
214 
215     //claerCList(CList);
216 
217     int a = 0;
218     getCList(CList, 2, &a);
219     printf("%d\n", a);
220 
221     printCList(CList);
222 
223     printf("%d\n", CList);
224     destoryCList(&CList);
225     printf("%d\n", CList);
226 
227     system("pause");
228     return 0;
229 }
C语言完整代码

  通过C++实现C语言的链表,主要区别:(1)struct可以不通过typedef,直接使用Node;(2)将malloc和free更换为new和delete

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 struct Node{
  5     int data;
  6     struct Node *next;
  7 };
  8 
  9 //空循环链表创建
 10 //创建头结点和尾结点
 11 //链表尾指针指向尾结点,尾结点指向头结点,头结点指向尾结点
 12 void iniCList(Node **CListTail){
 13     *CListTail = new Node;
 14     Node *CListHead = new Node;
 15 
 16     (*CListTail)->next = CListHead;
 17     CListHead->next = *CListTail;
 18 }
 19 
 20 //循环链表初始化(头插法)
 21 void iniCListHead(Node **CListTail, int n){
 22     //创建头尾结点
 23     *CListTail = new Node;
 24     Node *CListHead = new Node;
 25 
 26     (*CListTail)->next = CListHead;
 27     CListHead->next = *CListTail;
 28 
 29     int i = 0;
 30     while (i < n){
 31         Node *tmpNode = new Node;
 32 
 33         tmpNode->data = i;
 34         tmpNode->next = CListHead->next;
 35         CListHead->next = tmpNode;
 36         ++i;
 37     }
 38 }
 39 
 40 //循环链表初始化(尾插法)
 41 void iniCListTail(Node **CListTail, int n){
 42     //创建头尾结点
 43     *CListTail = new Node;
 44     Node *CListHead = new Node;
 45 
 46     (*CListTail)->next = CListHead;
 47     CListHead->next = *CListTail;
 48 
 49     Node *pCurrent = CListHead;
 50 
 51     int i = 0;
 52     while (i < n){
 53         Node *tmpNode = new Node;
 54 
 55         tmpNode->data = i;
 56         tmpNode->next = *CListTail;
 57         pCurrent->next = tmpNode;
 58         pCurrent = tmpNode;
 59 
 60         ++i;
 61     }
 62 }
 63 
 64 //循环链表按位置插入
 65 void insertCListPos(Node *CList, int pos, int val){
 66 
 67     Node *pCurrent = CList->next; //指向头结点
 68     int i = 1;
 69     while (pCurrent != CList && i < pos){
 70         pCurrent = pCurrent->next;
 71         ++i;
 72     }
 73 
 74     Node *tmpNode = new Node;
 75 
 76     tmpNode->data = val;
 77     tmpNode->next = pCurrent->next;
 78     pCurrent->next = tmpNode;
 79 
 80 }
 81 
 82 //有序循环链表,按值插入
 83 void insertCListValue(Node *CList, int val){
 84     Node *pCur = CList->next->next;
 85     Node *pPer = CList->next;
 86 
 87     while (pCur != CList && pCur->data < val){
 88         pPer = pCur;
 89         pCur = pCur->next;
 90     }
 91 
 92     Node *tmpNode = new Node;
 93 
 94     tmpNode->data = val;
 95     tmpNode->next = pPer->next;
 96     pPer->next = tmpNode;
 97 }
 98 
 99 //循环链表,按位置删除
100 void deleteCListPos(Node *CList, int pos){
101     Node *pCur = CList->next;
102 
103     int i = 1;
104     while (pCur != CList && i < pos){
105         pCur = pCur->next;
106         ++i;
107     }
108 
109     Node *tmpNode = pCur->next;
110     pCur->next = tmpNode->next;
111     delete tmpNode;
112 }
113 
114 //循环链表,按值删除
115 //删除空链表为出问题
116 void deleteCListValue(Node *CList, int val){
117     Node *pCur = CList->next->next;
118     Node *pPer = CList->next;
119 
120     while (pCur != CList && pCur->data != val){
121         pPer = pCur;
122         pCur = pCur->next;
123     }
124     if (pCur == CList)
125         return;
126     else{
127         pPer->next = pCur->next;
128         delete pCur;
129     }
130 }
131 
132 //循环链表,清空链表
133 void claerCList(Node *CList){
134     Node *p = CList->next->next;
135     Node *q = NULL;
136 
137     while (p != CList){ //到达表尾
138         q = p->next;
139         delete p;
140         p = q;
141     }
142 
143     CList->next = CList; //将头结点指向尾结点
144 }
145 
146 //循环链表,销毁链表
147 void destoryCList(Node **CList){
148     Node *p = (*CList)->next;
149     Node *q = NULL;
150 
151     while (p != (*CList)->next){ //到达表头
152         q = p->next;
153         delete p;
154         p = q;
155     }
156 
157     *CList = NULL;
158 }
159 
160 //获取元素
161 void getCList(Node *CList, int pos, int *val){
162     Node *pCur = CList->next->next;
163     int i = 1;
164     while (pCur != CList && i < pos){
165         pCur = pCur->next;
166         ++i;
167     }
168 
169     *val = pCur->data;
170 }
171 //遍历输出元素
172 void printCList(Node *CList){
173     Node * tmpNode = CList->next->next;
174     while (tmpNode != CList){ //到达表尾
175         printf("%d\n", tmpNode->data);
176         tmpNode = tmpNode->next;
177     }
178 }
179 
180 
181 int main(){
182     Node *CList = NULL;
183     //iniCListHead(&CList, 8);
184     //iniCList(&CList);
185     iniCListTail(&CList, 8);
186 
187     //insertCListPos(CList, 1, 2);
188     //insertCListPos(CList, 2, 4);
189     //insertCListPos(CList, 3, 6);
190     //
191     //insertCListValue(CList, 1);
192     //
193     //deleteCListPos(CList, 3);
194     //
195     //deleteCListValue(CList, 6);
196 
197     //claerCList(CList);
198 
199     int a = 0;
200     getCList(CList, 2, &a);
201     printf("%d\n", a);
202 
203     printCList(CList);
204 
205     printf("%d\n", CList);
206     destoryCList(&CList);
207     printf("%d\n", CList);
208 
209     system("pause");
210     return 0;
211 }
C++完整代码

单向循环链表

   注意:(1)单向循环链表销毁时,需要将头结点和尾结点删除;(2)单向循环链表插入,删除,遍历,清空链表时,条件从头结点或第一节点始,判断指针是否达到尾结点;(3)清空链表时,最后将头结点指向尾结点;(4)销毁链表时,条件从头结点始,判断条件为指针是否到达头结点,最后将指针置空。

 

-------------------------------------------------------------------------------------------------------------

如果上面的资料对你有启发,麻烦点个推荐,让更多人的人看到哦。

关注公众号【两猿社】,懂点互联网,懂点IC的程序猿,带你丰富项目经验哦。

posted @ 2019-02-25 10:48  两猿社  阅读(5003)  评论(0编辑  收藏  举报