I would rather rely on my own strength to open up my future than seek favor from the powerful
Article directory
The function name or variable name of each interface of the double-wire linked list
Doubly linked list interface implementation source code
Quick index [header files and function declarations]
Doubly linked list interface implementation
Construction Analysis of Doubly Linked List
Definition and initialization of doubly linked list
Insertion and deletion of doubly linked list
Past review:
Data Structure - Singly Linked List
Data Structure - Sequence List
Hello everyone, I am Ji Ning.
This article introduces to you a linked list with better performance than a single linked list - a doubly linked list, which can more efficiently implement data insertion, deletion, and search.
The first half of the article is the corresponding name and source code of the doubly linked list, and the second half of the article is a specific explanation of the implementation of the doubly linked list.
The function name or variable name of each interface of the double-wire linked list
LTDataType | Doubly linked list data type renaming |
ListNode | doubly linked list structure |
LTNode | Doubly linked list renaming |
BuyLTNode | create a node |
LTI | initialize node |
LTPrint | print doubly linked list |
LTPushBack | tail plug |
LTPopBack | tail delete |
LTPushFront | plug |
LTPopFront | head delete |
LTSize | Calculate the number of doubly linked list elements |
LTFind | Find linked list elements |
LTInsert | insert node before pos |
LTErase | Delete the node at position pos |
Doubly linked list interface implementation source code
Quick index [header files and function declarations]
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int LTDataType;//重命名
typedef struct ListNode
{
LTDataType Data;
struct ListNode* next;
struct ListNode* prev;
}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);//头删
LTNode* LTFind(LTNode* phead, LTDataType x);//寻找结点
void LTInsert(LTNode*phead,LTNode* pos, LTDataType x); //在pos之前插入结点
Doubly linked list interface implementation
LTNode* BuyLTNode(LTDataType x)
{
LTNode* nownode =(LTNode*)malloc(sizeof(LTNode));
if (nownode == NULL)
{
perror("malloc fail");
}
nownode->Data = x;
nownode->next = NULL;
nownode->prev = NULL;
return nownode;
}
LTNode* LTInit()
{
LTNode* phead = BuyLTNode(0);
phead->next = phead;
phead->prev = phead;
return phead;
}
void LTPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* tail = phead->prev;
LTNode* nownode = BuyLTNode(x);
nownode->next = phead;
nownode->prev = tail;
tail->next = nownode;
phead->prev = nownode;
}
void LTPrint(LTNode* phead)
{
assert(phead);
printf("phead<=>");
LTNode* cur = phead;
while (cur->next!=phead)
{
printf("%d<=>", cur->next->Data);
cur = cur->next;
}
printf("\n");
}
void LTPopBack(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);//只有哨兵位的时候不能删
LTNode* tail = phead->prev;
LTNode* tailPrev = tail->prev;
tailPrev->next = tail->next;
phead->prev = tailPrev;
free(tail);
}
void LTPushFront(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* first = phead->next;
LTNode* nownode = BuyLTNode(x);
nownode->next = first;
nownode->prev = phead;
phead->next = nownode;
first->prev = nownode;
}
void LTPopFront(LTNode* phead)
{
assert(phead);
assert(phead->next != phead);//只有哨兵位的时候不能删除
LTNode* first = phead->next;
LTNode* second = first->next;
phead->next = second;
second->prev = phead;
free(first);
}
LTNode* LTFind(LTNode* phead, LTDataType x)
{
assert(phead);
LTNode* cur = phead;
while (cur->next != phead)
{
if (cur->next->Data == x)
return cur->next;
cur = cur->next;
}
return NULL;
}
void LTInsert(LTNode* phead, LTNode* pos, LTDataType x)
{
assert(phead);
assert(pos);
LTNode* cur = phead;
while (cur->next != pos)
{
cur = cur->next;
}
LTNode*nownode = BuyLTNode(x);
nownode->next = pos;
nownode->prev = cur;
cur->next = nownode;
pos->prev = nownode;
}
void LTErase(LTNode* phead, LTNode* pos)
{
assert(pos&&phead);
assert(pos->next != pos);
assert(phead->next != phead);
LTNode* cur = phead;
LTNode* posNext = pos->next;
while (cur->next != pos)
{
cur = cur->next;
}
cur->next = posNext;
posNext->prev = cur;
free(pos);
}
Construction Analysis of Doubly Linked List
Doubly linked list, compared with single linked list, the node of doubly linked list has two pointer domains, one pointing to the next node, the other pointing to the previous node, the default doubly linked list has a head node with a sentinel bit, the head of the sentinel bit The node stores the address of the first valid node (phead->next) and the address of the last valid node (phead->prev).
Comparison of single and double linked list logic diagrams
Comparison of physical diagrams of single and double linked lists
Definition and initialization of doubly linked list
There is a data field and two pointer fields in the doubly linked list, one pointer points to the address of the next node, and one pointer points to the address of the previous node, and the structure of the double linked list is renamed again.
When a doubly linked list opens a new node, it first needs to open up a node-sized space, point its next and NULL to empty, and then assign its data field value to x.
Insertion and deletion of doubly linked list
To delete the doubly linked list, the first thing to be clear is that the head node of the sentinel bit cannot be deleted, because it is the structural support of the entire doubly linked list. When deleting, find the previous node and the next node of the node to be deleted, point the next pointer of the previous node to the next node, and point the prev pointer of the next node to the previous node. Finally, the deleted node space is freed.
The insertion of a doubly linked list, when inserting, can theoretically insert a node at any position. Because at the time of initialization, the pointer fields defining the newly created nodes are all empty. Therefore, when inserting, it is necessary to change the two pointer fields of the inserted node, point its next pointer to the next node, and make its prev pointer point to the previous node. Similarly, point the next pointer of the previous node to this new node, and point the prev pointer of the next pointer to this new node.