🌟一、带头双向循环链表
🌏1.1头删:
💫1.1.1代码:
void LTPopFront(LTNode* phead) { assert(phead); LTNode* cur = phead->next; phead->next = cur->next ; cur->next->prev = phead; free(cur); }
💫1.1.2流程图:
定义一个指针时:(代码如上图)
定义两个指针时:(建议使用两个—代码如下图)
🌏1.2尾删:
💫1.2.1代码:
void LTPopBack(LTNode* phead) { assert(phead); assert(!LTEmpty(phead)); LTNode* tail = phead->prev; LTNode* tailPrev = tail->prev; free(tail); phead->prev = tailPrev; tailPrev->next = phead; }
💫1.2.2流程图:
第一种:
第二种:
第三种:需要注意
🌏1.3查找:
LTNode* LTFind(LTNode* phead, LTDataType x) { assert(phead); LTNode* cur = phead->next; while (cur != phead) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; }
🌏1.4在pos位置之前插入:
💫1.4.1代码:
void LTInsert(LTNode* pos, LTDataType x) { assert(pos); LTNode* newnode = BuyLTNode(x); pos->prev->next = newnode; newnode->prev = pos->prev; newnode->next = pos; pos->prev = newnode; //第二种: ///LTNode* prev = pos->prev; //prev->next = newnode; //newnode->prev = prev; //pos->prev = newnode; //newnode->next = pos; }
💫1.4.2流程图:
第一种:
第二种:
🌏1.5在pos位置删除:
💫1.5.1代码:
void LTErase(LTNode* pos)//要注意不能传哨兵位 { assert(pos); LTNode* posPrev = pos->prev; LTNode* posNext = pos->next; posPrev->next = posNext; posNext->prev = posPrev; free(pos); }
💫1.5.2流程图:
🌏1.6释放链表:
void LTDestroy(LTNode* phead) { assert(phead); LTNode* cur = phead->next; while (cur != phead) { LTNode* next = cur->next; free(cur); cur = next; } free(phead); }
🌟二、完整带头双向循环链表
//List.h #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<stdbool.h> typedef int LTDataType; typedef struct ListNode { struct ListNode* next; struct ListNode* prev; LTDataType data; }LTNode; LTNode* LTInit(); void LTNodePrint(LTNode* phead); bool LTEmpty(LTNode* phead); void LTPushFront(LTNode* phead, LTDataType x); void LTPushBack(LTNode* phead, LTDataType x); void LTPopFront(LTNode* phead); void LTPopBack(LTNode* phead); LTNode* LTFind(LTNode* phead, LTDataType x); //在pos之前插入 void LTInsert(LTNode* pos, LTDataType x); //删除pos位置的值 void LTErase(LTNode* pos); void LTDestroy(LTNode* phead); //List.c #define _CRT_SECURE_NO_WARNINGS 1 #include"List.h" bool LTEmpty(LTNode* phead) { assert(phead); return phead->next == phead; } LTNode* BuyLTNode(LTDataType x) { LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); if (newnode == NULL) { perror("malloc fail"); } newnode->data = x; newnode->next = NULL; newnode->prev = NULL; return newnode; } LTNode* LTInit() { LTNode* phead = BuyLTNode(-1); phead->next = phead; phead->prev = phead; return phead; } void LTNodePrint(LTNode* phead) { assert(phead); LTNode* cur = phead->next; printf("guard<==>"); while (cur != phead) { printf("%d<==>", cur->data); cur = cur->next; } printf("\n"); } void LTPushFront(LTNode* phead, LTDataType x) { LTNode* newnode = BuyLTNode(x); LTNode* cur = phead->next; newnode->prev = phead; phead->next = newnode; newnode->next = cur; cur->prev = newnode; } void LTPushBack(LTNode* phead, LTDataType x) { assert(phead); LTNode* newnode = BuyLTNode(x); LTNode* tail = phead->prev; tail->next = newnode; newnode->prev = tail; newnode->next = phead; phead->prev = newnode; } void LTPopFront(LTNode* phead) { assert(phead); LTNode* cur = phead->next; //LTNode* next = cur->next; phead->next = cur->next ; cur->next->prev = phead; free(cur); } void LTPopBack(LTNode* phead) { assert(phead); assert(!LTEmpty(phead)); LTNode* tail = phead->prev; LTNode* tailPrev = tail->prev; free(tail); phead->prev = tailPrev; tailPrev->next = phead; } LTNode* LTFind(LTNode* phead, LTDataType x) { assert(phead); LTNode* cur = phead->next; while (cur != phead) { if (cur->data == x) { return cur; } cur = cur->next; } return NULL; } void LTInsert(LTNode* pos, LTDataType x) { assert(pos); LTNode* newnode = BuyLTNode(x); pos->prev->next = newnode; newnode->prev = pos->prev; newnode->next = pos; pos->prev = newnode; //第二种: ///LTNode* prev = pos->prev; //prev->next = newnode; //newnode->prev = prev; //pos->prev = newnode; //newnode->next = pos; } void LTErase(LTNode* pos)//要注意不能传哨兵位 { assert(pos); LTNode* posPrev = pos->prev; LTNode* posNext = pos->next; posPrev->next = posNext; posNext->prev = posPrev; free(pos); } void LTDestroy(LTNode* phead) { assert(phead); LTNode* cur = phead->next; while (cur != phead) { LTNode* next = cur->next; free(cur); cur = next; } free(phead); } //Test.c #define _CRT_SECURE_NO_WARNINGS 1 #include"List.h" void TestList() { LTNode* plist = LTInit(); LTPushBack(plist, 1); LTPushBack(plist, 2); LTPushBack(plist, 3); LTPushBack(plist, 4); LTNodePrint(plist); //LTPushFront(plist, 1); //LTPushFront(plist, 2); //LTPushFront(plist, 3); //LTPushFront(plist, 4); //LTNodePrint(plist); /*LTPopBack(plist); LTNodePrint(plist);*/ /*LTPopFront(plist); LTNodePrint(plist);*/ /*LTNode* pos = LTFind(plist,3); if (pos) { LTInsert(pos, 30); } LTNodePrint(plist);*/ LTNode* pos = LTFind(plist, 2); if (pos) { LTErase(pos, 30); } LTNodePrint(plist); LTDestroy(plist); plist = NULL; } int main() { TestList(); return 0; }
😽总结
😽Ending,今天的链表之带头双向循环链表(中)的内容就到此结束啦~,如果后续想了解更多,就请关注我吧。