Data structure - double linked list

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.

Guess you like

Origin blog.csdn.net/zyb___/article/details/132063876