双向链表是比较常见的,主要是在链表的基础上添加prev指针,闲话少说直接上代码吧(这个也是网上一个大神的思路,真心不错,条理清楚,逻辑缜密)
主要也是为了学习,贴上我所调试成功的代码(Linux环境下)
双向链表代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef struct NodeTag Node; 5 typedef struct LinkedListTag LinkedList; 6 7 struct NodeTag 8 { 9 Node* prev; 10 Node* next; 11 void* data; 12 }; 13 14 struct LinkedListTag 15 { 16 Node* head; 17 Node* tail; 18 Node* cur; 19 int size; 20 }; 21 22 // 创建一个链表 成功返回该链表的指针 否则返回NULL 23 LinkedList* Create( void ) 24 { 25 // 创建一个新节点 26 LinkedList* list = (LinkedList*)malloc(sizeof(LinkedList)); 27 // 创建不成功,返回NULL 28 if(!list) return NULL; 29 30 list->head = NULL; 31 list->tail = NULL; 32 list->cur = NULL; 33 list->size = 0; 34 35 // 初始化成功后,返回list 36 return list; 37 } 38 39 // 将元素添加到链表的末尾,成功返回链表的size,失败返回-1 40 int AddBack(LinkedList* list, void* data) 41 { 42 // 创建一个新节点,创建不成功的话,返回-1 43 Node* node = (Node *)malloc(sizeof(Node)); 44 if(!node) return -1; 45 46 // 为节点的数据域赋值 47 node->data = data; 48 // 如果为链表的末尾 49 if(list->tail) 50 { 51 list->tail->next = node; // 把新节点赋给链表末尾的下一个 52 node->prev = list->tail; // 新节点的前一个等于之前的末节点 53 node->next = NULL; // 新节点为末节点,把它下一个指向NULL 54 } 55 else // 如果不为末尾,其实就是空链表 56 { 57 node->next = NULL; // 新节点的下一个为NULL 58 node->prev = NULL; // 新节点的前一个为NULL 59 list->head = node; // 链表的头为新节点node 60 } 61 list->tail = node; // 链表的末尾指向node 62 63 return ++list->size; // 返回链表的size 64 } 65 66 // 将元素添加到链表前端,成功返回非0,否则返回0 67 int AddFront(LinkedList* list, void* data) 68 { 69 Node *node = (Node*)malloc(sizeof(Node)); 70 if(!node) return 0; 71 72 node->data = data; 73 if(list->head) 74 { 75 list->head->prev = node; 76 node->next = list->head; 77 node->prev = NULL; 78 } 79 else 80 { 81 node->next = NULL; 82 node->prev = NULL; 83 list->tail = node; 84 } 85 list->head = node; 86 87 return ++list->size; 88 } 89 90 // 将元素从末端移除并返回该元素,如果链表为空则返回NULL 91 void* RemoveBack(LinkedList* list) 92 { 93 Node* temp; 94 void* data; 95 96 if(!list->size) return NULL; 97 98 temp = list->tail; 99 data = list->tail->data; 100 101 if(list->head == list->tail) 102 { 103 list->head = NULL; 104 list->tail = NULL; 105 list->cur = NULL; 106 } 107 else 108 { 109 list->tail = list->tail->prev; 110 list->tail->next = NULL; 111 } 112 --list->size; 113 free(temp); 114 return data; 115 } 116 117 // 将元素从前端移除并返回该元素,如果链表为空则返回NULL 118 void* RemoveFront(LinkedList* list) 119 { 120 Node* temp; 121 void* data; 122 123 if(!list->size) return NULL; 124 125 temp = list->head; 126 data = list->head->data; 127 128 if(list->head == list->tail) 129 { 130 list->head = NULL; 131 list->tail = NULL; 132 list->cur = NULL; 133 } 134 else 135 { 136 list->head = list->head->next; 137 list->head->prev = NULL; 138 } 139 --list->size; 140 free(temp); 141 return data; 142 } 143 144 /* 如果当前链表为空则返回非0,否则返回0 */ 145 int IsEmpty(LinkedList* list) 146 { 147 return list->size == 0; 148 } 149 150 /* 获得链表的大小(元素总个数) */ 151 int Size(LinkedList* list) 152 { 153 return list->size; 154 } 155 156 /* 将当前位置移动到链表的开始 */ 157 void Begin(LinkedList* list) 158 { 159 list->cur = list->head; 160 } 161 162 /* 将当前位置移动到链表的最后 */ 163 void End(LinkedList* list) 164 { 165 list->cur = list->tail; 166 } 167 /* 将当前位置向后移动一个位置 */ 168 void MoveNext(LinkedList* list) 169 { 170 list->cur = list->cur->next; 171 } 172 173 /* 将当前位置向后移动一个位置 */ 174 void MovePrev(LinkedList* list) 175 { 176 list->cur = list->cur->prev; 177 } 178 179 /* 清空链表中所有元素 */ 180 void Clear(LinkedList* list) 181 { 182 while(RemoveBack(list)); 183 } 184 185 /* 销毁一个链表 */ 186 void Destroy(LinkedList* list) 187 { 188 Clear(list); 189 free(list); 190 } 191 192 /* 如果当前位置之后还有元素则返回非0,否则返回0 */ 193 int HasNext(LinkedList* list) 194 { 195 if (!list->cur) return 0; 196 if (list->cur == list->tail) return 1; 197 return list->cur->next != NULL; 198 } 199 200 /* 如果当前位置之前还有元素则返回非0,否则返回0 */ 201 int HasPrev(LinkedList* list) 202 { 203 if (!list->cur) return 0; 204 if (list->cur == list->head) return 1; 205 return list->cur->prev != NULL; 206 } 207 208 /* 返回当前位置的元素 */ 209 void* Current(LinkedList* list) 210 { 211 return list->cur->data; 212 } 213 214 215 216 // 正向打印链表 217 void Traverse(LinkedList* list) 218 { 219 for( Begin(list); HasNext(list); MoveNext(list) ) 220 printf("%d ", *(int*)Current(list)); 221 putchar(‘\n‘); 222 } 223 224 // 反向打印链表 225 void RTraverse(LinkedList* list) 226 { 227 for (End(list); HasPrev(list); MovePrev(list)) 228 printf("%d ", *(int*)Current(list)); 229 putchar(‘\n‘); 230 } 231 232 233 int main() 234 { 235 int i; 236 LinkedList* list = Create(); 237 238 int array1[10]; 239 int array2[10]; 240 241 for(i=0; i<10; i++) 242 { 243 array1[i] = i+1; 244 array2[i] = i+100+1; 245 AddBack(list, &array1[i]); 246 } 247 248 printf("链表大小(SIZE): %d\n", Size(list)); 249 250 printf("正向打印链表:\n"); 251 Traverse(list); 252 printf("反向打印链表:\n"); 253 RTraverse(list); 254 255 printf("添加array2[0]数\n"); 256 AddBack(list, &array2[0]); 257 258 printf("链表大小(SIZE): %d\n", Size(list)); 259 printf("正向打印链表:\n"); 260 Traverse(list); 261 printf("反向打印链表:\n"); 262 RTraverse(list); 263 264 printf("调用AddFront函数,添加array2[0]数\n"); 265 AddFront(list, &array2[1]); 266 267 printf("链表大小(SIZE): %d\n", Size(list)); 268 printf("正向打印链表:\n"); 269 Traverse(list); 270 printf("反向打印链表:\n"); 271 RTraverse(list); 272 273 printf("从末尾移除的元素是: %d\n", *(int *)RemoveBack(list)); 274 printf("链表大小(SIZE): %d\n", Size(list)); 275 printf("正向打印链表:\n"); 276 Traverse(list); 277 printf("反向打印链表:\n"); 278 RTraverse(list); 279 280 printf("从开头移除的元素是: %d\n", *(int *)RemoveFront(list)); 281 printf("链表大小(SIZE): %d\n", Size(list)); 282 printf("正向打印链表:\n"); 283 Traverse(list); 284 printf("反向打印链表:\n"); 285 RTraverse(list); 286 287 printf("清空链表,Clear(list)后\n"); 288 Clear(list); 289 printf("链表大小(SIZE): %d\n", Size(list)); 290 291 for(i=0; i<10; i++) 292 { 293 AddFront(list, &array2[i]); 294 } 295 printf("正向打印链表:\n"); 296 Traverse(list); 297 printf("反向打印链表:\n"); 298 RTraverse(list); 299 300 Destroy(list); 301 printf("销毁链表Destroy(list)\n"); 302 303 return 0; 304 }
以下是执行结果:
链表大小(SIZE): 10 正向打印链表: 1 2 3 4 5 6 7 8 9 10 反向打印链表: 10 9 8 7 6 5 4 3 2 1 添加array2[0]数 链表大小(SIZE): 11 正向打印链表: 1 2 3 4 5 6 7 8 9 10 101 反向打印链表: 101 10 9 8 7 6 5 4 3 2 1 调用AddFront函数,添加array2[0]数 链表大小(SIZE): 12 正向打印链表: 102 1 2 3 4 5 6 7 8 9 10 101 反向打印链表: 101 10 9 8 7 6 5 4 3 2 1 102 从末尾移除的元素是: 101 链表大小(SIZE): 11 正向打印链表: 102 1 2 3 4 5 6 7 8 9 10 反向打印链表: 10 9 8 7 6 5 4 3 2 1 102 从开头移除的元素是: 102 链表大小(SIZE): 10 正向打印链表: 1 2 3 4 5 6 7 8 9 10 反向打印链表: 10 9 8 7 6 5 4 3 2 1 清空链表,Clear(list)后 链表大小(SIZE): 0 正向打印链表: 110 109 108 107 106 105 104 103 102 101 反向打印链表: 101 102 103 104 105 106 107 108 109 110 销毁链表Destroy(list)
在世界上,努力坚持的绝对不是自己一个人,好好努力会成功的。
时间: 2025-01-09 22:40:12