目录
之前写少了一个东西——哨兵位,它是先建立一个节点,然后next指向空,之后在next指向的位置开始插入,也就是next = newhead,哨兵位用在尾插上是比较合适的。
进入正题
学了单链表后,双向循环链表就会变得简单。虽然结构稍复杂一点,但实际操作轻松不少。
- #pragma once
- #define _CRT_SECURE_NO_WARNINGS 1
- #include
- #include
- #include
- #include
-
- typedef int LTDataType;
- typedef struct ListNode
- {
- struct ListNode* prev;
- struct ListNode* next;
- LTDataType data;
- }LTNode;
-
- LTNode* BuyListNode(LTDataType x);
- LTNode* LTInit();
- void LTPrint(LTNode* phead);
-
- //尾插尾删
- void LTPushBack(LTNode* phead, LTDataType x);
- void LTPopBack(LTNode* phead);
- //头插头删
- void LTPushFront(LTNode* phead, LTDataType x);
- void LTPopFront(LTNode* phead);
-
- LTNode* LTFind(LTNode* phead, LTDataType x);
-
- //在pos之前插入
- void LTInsert(LTNode* pos, LTDataType x);
- //删除pos位置
- void LTErase(LTNode* pos);
-
- bool LTEmpty(LTNode* phead);
- size_t LTSize(LTNode* phead);
- void LTDestroy(LTNode* phead);
- LTNode* BuyListNode(LTDataType x)
- {
- LTNode* node = (LTNode*)malloc(sizeof(LTNode));
- if (node == NULL)
- {
- perror("malloc fail");
- exit(-1);
- }
-
- node->data = x;
- node->next = NULL;
- node->prev = NULL;
- return node;
- }
-
- LTNode* LTInit()
- {
- LTNode* phead = BuyListNode(-1);
- phead->next = phead;
- phead->prev = phead;
-
- return phead;
- }
-
- void LTPrint(LTNode* phead)
- {
- assert(phead);
-
- LTNode* cur = phead->next;
- while (cur != phead)
- {
- printf("%d ", cur->data);
- cur = cur->next;
- }
- printf("\n");
- }
-
- void LTPushBack(LTNode* phead, LTDataType x)
- {
- assert(phead);
-
- /*LTNode* newnode = BuyListNode(x);
- LTNode* tail = phead->prev;
- tail->next = newnode;
- newnode->prev = tail;
- newnode->next = phead;
- phead->prev = newnode;*/
-
- LTInsert(phead, x);
- }
-
- void LTPopBack(LTNode* phead)
- {
- assert(phead);
- assert(phead->next != phead); // 空
-
-
- //LTNode* tail = phead->prev;
- //LTNode* tailPrev = tail->prev;
-
- //tailPrev->next = phead;
- //phead->prev = tailPrev;
- //free(tail);
-
- LTErase(phead->prev);
- }
-
- void LTPushFront(LTNode* phead, LTDataType x)
- {
- assert(phead);
-
- /*LTNode* newnode = BuyListNode(x);
- newnode->next = phead->next;
- phead->next->prev = newnode;
- phead->next = newnode;
- newnode->prev = phead;*/
-
- //LTNode* newnode = BuyListNode(x);
- //LTNode* first = phead->next;
-
- phead newnode first
- 顺序无关
- //phead->next = newnode;
- //newnode->prev = phead;
- //newnode->next = first;
- //first->prev = newnode;
-
- LTInsert(phead->next, x);
-
- }
-
- void LTPopFront(LTNode* phead)
- {
- assert(phead);
- assert(phead->next != phead); // 空
-
- /*LTNode* first = phead->next;
- LTNode* second = first->next;
- free(first);
- phead->next = second;
- second->prev = phead;*/
- LTErase(phead->next);
- }
-
- 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;
- }
-
- // 在pos之前插入x
- void LTInsert(LTNode* pos, LTDataType x)
- {
- assert(pos);
-
- LTNode* prev = pos->prev;
- LTNode* newnode = BuyListNode(x);
- // prev newnode pos
- prev->next = newnode;
- newnode->prev = prev;
- newnode->next = pos;
- pos->prev = newnode;
- }
-
- // 删除pos位置
- void LTErase(LTNode* pos)
- {
- assert(pos);
-
- LTNode* prev = pos->prev;
- LTNode* next = pos->next;
- free(pos);
-
- prev->next = next;
- next->prev = prev;
- }
-
-
- bool LTEmpty(LTNode* phead)
- {
- assert(phead);
-
- /*if (phead->next == phead)
- {
- return true;
- }
- else
- {
- return false;
- }*/
-
- return phead->next == phead;
- }
-
- size_t LTSize(LTNode* phead)
- {
- assert(phead);
-
- size_t size = 0;
- LTNode* cur = phead->next;
- while (cur != phead)
- {
- ++size;
- cur = cur->next;
- }
-
- return size;
- }
-
- void LTDestroy(LTNode* phead)
- {
- assert(phead);
-
- LTNode* cur = phead->next;
- while (cur != phead)
- {
- LTNode* next = cur->next;
- free(cur);
-
- cur = next;
- }
-
- free(phead);
- //phead = NULL;
- }
- void TestList1()
- {
- LTNode* phead = BuyListNode(-1);
- phead->prev = phead;
- phead->next = phead;
- //没有办法LTNode* phead = LTInit(phead), 总是在说使用未初始化的变量,嗯,毛病太多了
- LTPushBack(phead, 1);
- LTPushBack(phead, 2);
- LTPushBack(phead, 3);
- LTPushBack(phead, 4);
- LTPrint(phead);
-
- LTPopBack(phead);
- LTPrint(phead);
- LTPopBack(phead);
- LTPrint(phead);
- LTPopBack(phead);
- LTPrint(phead);
- LTPopBack(phead);
- LTPrint(phead);
- }
-
- void TestList2()
- {
- LTNode* phead = BuyListNode(-1);
- phead->prev = phead;
- phead->next = phead;
- LTPushFront(phead, 1);
- LTPushFront(phead, 2);
- LTPushFront(phead, 3);
- LTPushFront(phead, 4);
- LTPrint(phead);
-
- LTPopFront(phead);
- LTPrint(phead);
- LTPopFront(phead);
- LTPrint(phead);
- LTPopFront(phead);
- LTPrint(phead);
- LTPopFront(phead);
- LTPrint(phead);
- }
-
- void TestList3()
- {
- LTNode* phead = BuyListNode(-1);
- phead->prev = phead;
- phead->next = phead;
- LTPushFront(phead, 1);
- LTPushFront(phead, 2);
- LTPushFront(phead, 3);
- LTPushFront(phead, 4);
- LTPrint(phead);
-
- LTNode* pos = LTFind(phead, 3);
- if (pos)
- {
- pos->data *= 10;
- }
- LTPrint(phead);
-
- LTDestroy(phead);
- phead = NULL;
- }
-
- int main()
- {
- TestList3();
- return 0;
- }
其实是觉得没什么细讲的,就只发了代码。
结束。