Ready to work:
Create structure pointer
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
struct ListNode* next;
struct ListNode* prev;
}LTNode;
1. Create a new node
Basic idea: malloc node, determine whether the node is created successfully.
LTNode* BuyLTNode(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));//动态开辟节点
if (newnode == NULL)//判断是否malloc成功
{
printf("malloc fail\n");
exit(-1);//退出程序
}
newnode->data = x;//初始化
newnode->next = NULL;//置空
newnode->prev = NULL;//置空
return newnode;
}
2. Tail plug
Basic idea: 1) Create a new node
2) Find the tail node and link it
Drawing:
Code:
void LTNodePushBack(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;
}
3. Head plug
Basic idea: 1) Create a new node
2) Find the first node, link the nodes
Drawing:
Code:
void LTNodePushFront(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* newnode = BuyLTNode(x);
LTNode* first = phead->next;//找到第一个节点
//链接
newnode->next = first;
first->prev = newnode;
phead->next = newnode;
newnode->prev = phead;
}
3. Print the linked list
Basic idea: 1) Assertions
2) Create a cur node, pointing to the first node
3) When cur == phead, the round ends.
Drawing:
Code:
void LTNodePrint(LTNode* phead)
{
LTNode* cur = phead->next;//一般情况下,不允许动头节点
while (cur != phead)//当指向phead时,循环结束
{
printf("%d ", cur->data);
cur = cur->next;//更新cur
}
printf("\n\n");
}
4. Tail deletion
Basic idea: 1) Assertions
2) Find the tail node and the penultimate node, link phead and tailPrev, free node
Drawing:
Code:
void LTNPopBack(LTNode* phead)
{
//断言
assert(phead);
//找到尾节点和第二个尾节点
LTNode* tail = phead->prev;
LTNode* tailPrev = tail->prev;
//释放尾节点
free(tail);
tail = NULL;
//新的链接
tailPrev->next = phead;
phead->prev = tailPrev;
}
5. Header deletion
Basic idea: 1) Assertions
2) Find the first and second node, link the phead and the second node, free the first node
Drawing:
Code:
void LTNPopFront(LTNode* phead)
{
//断言
assert(phead);
//找到第一个节点和第二个节点
LTNode* first = phead->next;
LTNode* second = first->next;
//释放内存
free(first);
first = NULL;
//链接
phead->next = second;
second->prev = phead;
}
6. Find the value of pos
Basic idea: 1) Assertions
2) Traverse the linked list, return the linked list if found, and return NULL if not found
Code:
LTNode* LTNFind(LTNode* phead, LTDataType x)
{
//断言
assert(phead);
//创立一个节点
LTNode* cur = phead->next;
while (cur != phead)
{
if (cur->data == x)
{
//找到返回节点
return cur;
}
cur = cur->next;
}
//找不到,返回NULL
return NULL;
}
7. Insert a new node before pos
Basic idea: 1) Assertions
2) Create a new node and find the node before pos
3) Link newnode pos and previous one of pos
Drawing:
Code:
void LTNInsert(LTNode* pos, LTDataType x)
{
//断言
assert(pos);
//找到pos的前一个节点
LTNode* prev = pos->prev;
//创建一个新节点
LTNode* newnode = BuyLTNode(x);
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
8. Delete the pos node
Basic idea: 1) Assertions
2) Create two nodes before and after pos, link, free the pos node
Drawing:
Code:
void LTNErase(LTNode* pos)
{
//断言
assert(pos);
//创建pos对应前后的节点
LTNode* prev = pos->prev;
LTNode* next = pos->next;
//释放节点
free(pos);
pos = NULL;
//链接
prev->next = next;
next->prev = prev;
}
9. Destroy the linked list
Basic idea: 1) Assertions
2) Create a cur pointer record
3) One cycle, one node is released one node at a time.
4) phead is finally released and empty.
Code:
void LTNDestroy(LTNode* phead)
{
//断言
assert(phead);
//创建cur指针
LTNode* cur = phead->prev;
//循环
while (cur != phead)
{
//记录下一个节点
LTNode* next = cur->next;
free(cur);
//更新
cur = next;
}
//释放并置空
free(phead);
phead = NULL;
}
head File:
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
//双向带头循环链表
typedef int LTDataType;
typedef struct ListNode
{
LTDataType data;
struct ListNode* next;
struct ListNode* prev;
}LTNode;
//尾插
void LTNodePushBack(LTNode* phead, LTDataType x);
LTNode* BuyLTNode(LTDataType x);
void LTNodePrint(LTNode* phead);
LTNode* LTNodeInit();
//头插
void LTNodePushFront(LTNode* phead, LTDataType x);
//尾删
void LTNPopBack(LTNode* phead);
//头删
void LTNPopFront(LTNode* phead);
//查找
LTNode* LTNFind(LTNode* phead, LTDataType x);
//在pos前面插入
void LTNInsert(LTNode* pos, LTDataType x);
//删除pos位置对应的值
void LTNErase(LTNode* pos);
//销毁链表
void LTNDestroy(LTNode* phead);