目录

双链表(带头)
1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结 构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都 是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带 来很多优势,实现反而简单了,后面我们代码实现了就知道了
- #pragma once
- #include
- #include
- #include
-
- typedef int LTDataType;
- typedef struct ListNode
- {
- struct ListNode* next;
- struct ListNode* prev;
- LTDataType data;
- }LTNode;
-
- //扩容
- LTNode* BuyLTNode(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);
-
- //链表大小
- int LTSize(LTNode* phead);
-
- //找位置
- LTNode* LTFind(LTNode* phead, LTDataType x);
-
- // 在pos位置插入x
- void LTInsert(LTNode* pos, LTDataType x);
- // 删除pos位置
- void LTErase(LTNode* pos);
-
-
-
- //扩容
- LTNode* BuyLTNode(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 = BuyLTNode(0);
- phead->next = phead;
- phead->prev = phead;
- return phead;
- }
-
- //打印
- void LTPrint(LTNode* phead)
- {
- assert(phead);
- printf("phead->");
- LTNode* cur = phead;
- while (cur->next != phead)
- {
- printf("%d ", cur->data);
- cur = cur->next;
- }
- printf("\n");
- }
- 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 LTPopBack(LTNode* phead)
- {
- assert(phead);
- assert(phead->next != phead);
-
- LTNode* tail = phead->prev;
- LTNode* tailPrev = tail->prev;
- free(tail);
-
- phead->prev = tailPrev;
- tailPrev->next = phead;
-
- }

- //头插
- void LTPushFront(LTNode* phead, LTDataType x)
- {
- assert(phead);
- LTNode* newnode = BuyLTNode(x);
-
- newnode->next = phead->next;
- phead->next->prev = newnode;
-
- phead->next = newnode;
- newnode->prev = phead;
- }

- 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;
- }

- LTNode* LTFind(LTNode* phead, LTDataType x)
- {
- LTNode* cur = phead->next;
- while (cur)
- {
- if (cur->data == x)
- {
- return cur;
- }
-
- cur = cur->next;
- }
-
- return NULL;
- }
- // 在pos位置插入x
- void LTInsert(LTNode* pos, LTDataType x)
- {
- assert(pos);
- LTNode* newnode = BuyLTNode(x);
- LTNode* posPrev = pos->prev;
-
- posPrev->next = newnode;
- newnode->prev = posPrev;
-
- newnode->next = pos;
- pos->prev = newnode;
- }

- // 删除pos位置
- void LTErase(LTNode* pos)
- {
- assert(pos);
- LTNode* posPrev = pos->prev;
- LTNode* posNext = pos->next;
- free(pos);
-
- posPrev->next = posNext;
- posNext->prev = posPrev;
- }

- #include"List.h"
-
- void Test1()
- {
- LTNode* plist = LTInit();
- LTPushBack(plist, 1);
- LTPushBack(plist, 2);
- LTPushBack(plist, 3);
- LTPushBack(plist, 4);
- LTPushBack(plist, 5);
- LTPrint(plist);
-
- LTPopBack(plist);
- LTPrint(plist);
-
- LTPushFront(plist, 40);
- LTPrint(plist);
-
- LTPopFront(plist);
- LTPrint(plist);
-
- LTNode* pos1 = LTFind(plist, 4);
- LTInsert(pos1, 50);
- LTPrint(plist);
-
- LTNode* pos2 = LTFind(plist, 50);
- LTErase(pos2);
- LTPrint(plist);
- }
-
- int main()
- {
- Test1();
- return 0;
- }

感觉理解链表的原理 实现起来其实不难 下一个博客我将对链表这一块的常规题目进行整理 继续加油!