双向链表
1. 双向链表的定义
双向带头循环链表
1 2 3 4 5 6
| typedef struct ListNode { LTDataType data; struct ListNode *prev; struct ListNode *next; }LTNode;
|
2. 链表初始化
1 2 3 4 5 6 7 8
| LTNode* ListInit() { LTNode* phead = (LTNode*)malloc(sizeof(LTNode)); phead->next = phead; phead->prev = phead;
return phead; };
|
3. 创建新的节点
1 2 3 4 5 6 7 8 9
| LTNode* BuyListNode(LTDataType x) { LTNode* newnode = (LTNode*)malloc(sizeof(LTNode)); newnode->data = x; newnode->next = NULL; newnode->prev = NULL;
return newnode; };
|
4. 尾插
1 2 3 4 5 6 7 8 9 10 11 12
| void ListPushBack(LTNode* phead,LTDataType x) { assert(phead); LTNode* tail = phead->prev; LTNode* newnode =(LTNode*)malloc(sizeof(LTNode)); newnode->data = x;
tail->next = newnode; newnode->prev = tail; newnode->next = phead; phead->prev = newnode; };
|
5. 头插
1 2 3 4 5 6 7 8 9 10
| void ListPushFront(LTNode* phead,LTDataType x) { assert(phead != NULL); LTNode* newnode = BuyListNode(x); LTNode* tail = phead->next; phead->next = newnode; newnode->prev = phead; newnode->next = tail; tail->prev = newnode; };
|
6. 尾删
1 2 3 4 5 6 7 8 9 10
| void ListPopBack(LTNode* phead) { assert(phead != NULL); assert(phead->next != phead); LTNode* tail = phead->prev; LTNode* tailprev = tail->prev; free(tail); tailprev->next = phead; phead->prev = tailprev; };
|
7. 头删
1 2 3 4 5 6 7 8 9 10
| void ListPopFront(LTNode* phead) { assert(phead != NULL); assert(phead->next != phead); LTNode* tail = phead->next; LTNode* next = tail->next; free(tail); phead->next = next; next->prev = phead; };
|
8. pos位置删除
1 2 3 4 5 6 7 8 9
| void ListErase(LTNode* pos) { assert(pos != NULL); LTNode* posPrev = pos->prev; LTNode* posNext = pos->next; free(pos); posPrev->next = posNext; posNext->prev = posPrev; };
|
9. 查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| LTNode* ListFind(LTNode* phead,LTDataType x) { assert(phead); LTNode* cur = phead->next; while(cur != phead) { if(cur->data == x) { return cur; } cur = cur->next; } return NULL; };
|
10. pos位置之前插入
1 2 3 4 5 6 7 8 9 10
| void ListInsert(LTNode* pos,LTDataType x) { assert(pos != NULL); LTNode* posPrev = pos->prev; LTNode* newnode = BuyListNode(x); posPrev->next = newnode; newnode->prev = posPrev; newnode->next = pos; pos->prev = newnode; };
|
11. pos位置删除
1 2 3 4 5 6 7 8 9 10
| void ListErase(LTNode* pos) { assert(pos != NULL); LTNode* posPrev = pos->prev; LTNode* posNext = pos->next;
posPrev->next = posNext; posNext->prev = posPrev; free(pos); };
|
12.双向链表的销毁
1 2 3 4 5 6 7 8 9 10 11 12
| void ListDestroy(LTNode* phead) { assert(phead != NULL); LTNode* cur = phead->next; while(cur != phead) { LTNode* next = cur->next; free(cur); cur = next; } free(phead); };
|
用完Destroy后要将传过来的指针手动置空,这是因为要保证传参结构的一致性(都是传一级指针),如果要在Destroy内置空,要用二级指针实现。