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语言的链表,主要区别:(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 }
单向循环链表
注意:(1)单向循环链表销毁时,需要将头结点和尾结点删除;(2)单向循环链表插入,删除,遍历,清空链表时,条件从头结点或第一节点始,判断指针是否达到尾结点;(3)清空链表时,最后将头结点指向尾结点;(4)销毁链表时,条件从头结点始,判断条件为指针是否到达头结点,最后将指针置空。
-------------------------------------------------------------------------------------------------------------
如果上面的资料对你有启发,麻烦点个推荐,让更多人的人看到哦。
关注公众号【两猿社】,懂点互联网,懂点IC的程序猿,带你丰富项目经验哦。