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的程序猿,帶你豐富項目經驗哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM