[Data structure]: The realization of the addition, deletion, and modification function of the double-linked list (the leading bidirectional circular linked list)

1. Take the lead in a two-way circular linked list

Take the lead in a two-way circular linked list: the structure is the most complicated, and it is generally used to store data separately. The linked list data structure used in practice is a two-way circular linked list that takes the lead. In addition, although this structure is complex, you will find that the structure will bring a lot of advantages after using the code to achieve it, but the implementation is simple.

The logical structure is as follows
Insert picture description here

2. Take the lead in the realization of the addition, deletion, and modification of the two-way circular linked list

(1) The interface and function declaration of the functions of the DoubleList.h linked list

#pragma once

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int LTDataType;
typedef struct ListNode
{
    
    
    //值
	LTDataType data;
	//前驱指针
	struct ListNode* prev;
	//后驱指针
	struct ListNode* next;
}ListNode;

//创建返回链表的头节点
ListNode* ListCreat();
//链表的销毁
void ListDestory(ListNode* phead);
//动态申请一个节点
ListNode* BuyListNode(LTDataType x);
//打印链表
void ListPrint(ListNode* phead);
//尾插
void ListPushBack(ListNode* phead, LTDataType x);
//头插
//头插在第一个有效数据前面,头节点不存储有效数据
void ListPushFront(ListNode* phead, LTDataType x);
//尾删
void ListPopBack(ListNode* phead);
//头删
void ListPopFront(ListNode* phead);
//查找
ListNode* ListFind(ListNode* phead, LTDataType x);
//在pos之前插入x
void ListInsert(ListNode* pos, LTDataType x);
//删除pos位置节点
void ListErase(ListNode* pos);

(2) The realization of each interface function of DoubleList.c

#include"DoubleList.h"

//创建返回链表的头节点
ListNode* ListCreat()
{
    
    
	ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
	phead->prev = phead;
	phead->next = phead;
	return phead;
}
//链表的销毁
void ListDestory(ListNode* phead)
{
    
    
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		ListNode* next = cur->next;
		ListErase(cur);
		cur = next;
	}
	free(phead);
	phead = NULL;
}
//动态申请一个节点
ListNode* BuyListNode(LTDataType x)
{
    
    
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	newnode->data = x;
	//新节点前后指向空
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}
//打印链表
void ListPrint(ListNode* phead)
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}
//尾插
void ListPushBack(ListNode* phead, LTDataType x)
{
    
    
	assert(phead);
	ListNode* tail = phead->prev;
	ListNode* newnode = BuyListNode(x);
	phead->prev = newnode;
	newnode->next = phead;
	tail->next = newnode;
	newnode->prev = tail;
}
//头插
//头插在第一个有效数据前面,头节点不存储有效数据
void ListPushFront(ListNode* phead, LTDataType x)
{
    
    
	assert(phead);
	ListNode* newnode = BuyListNode(x);
	ListNode* next = phead->next;
	phead->next = newnode;
	newnode->next = next;
	next->prev = newnode;
	newnode->prev = phead;
}
//尾删
void ListPopBack(ListNode* phead)
{
    
    
	assert(phead);
	//没有数据了,只有一个头节点
	assert(phead->next != phead);
	ListNode* tailprev = phead->prev->prev;
	ListNode* tail = phead->prev;
	phead->prev = tailprev;
	tailprev->next = phead;
	free(tail);
}
//头删
void ListPopFront(ListNode* phead)
{
    
    
	assert(phead);
	//链表没有数据了,不能在删了
	assert(phead->next != phead);
	ListNode* pheadnext = phead->next;
	ListNode* next = pheadnext->next;
	phead->next = next;
	next->prev = phead;
	free(pheadnext);
}
//查找
ListNode* ListFind(ListNode* phead, LTDataType x)
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		if (cur->data == x)
		{
    
    
			printf("找到了%d\n", cur->data);
			return cur;
		}
		else
		{
    
    
			cur = cur->next;
		}
	}
	printf("没找到%d\n", x);
	return NULL;
}
//在pos之前插入x
void ListInsert(ListNode* pos, LTDataType x)
{
    
    
	assert(pos);
	ListNode* newnode = BuyListNode(x);
	ListNode* posprev = pos->prev;
	newnode->next = pos;
	pos->prev = newnode;
	posprev->next = newnode;
	newnode->prev = posprev;
}
//删除pos位置节点
//注意这里pos不能是phead,否则就破坏了链表大结构
void ListErase(ListNode* pos)
{
    
    
	assert(pos);
	assert(pos->next != pos);
	ListNode* posprev = pos->prev;
	ListNode* posnext = pos->next;
	posprev->next = posnext;
	posnext->prev = posprev;
	free(pos);
}

(3) test.c is used to test various functions

#include"DoubleList.h"

int main()
{
    
    
	ListNode* phead = ListCreat();
	//尾插
	printf("尾插测试: ");
	ListPushBack(phead, 1);
	ListPushBack(phead, 2);
	ListPushBack(phead, 3);
	ListPushBack(phead, 4);
	ListPushBack(phead, 5);
	ListPrint(phead);
	//头插
	printf("头插测试: ");
	ListPushFront(phead, 0);
	ListPushFront(phead, -1);
	ListPushFront(phead, -2);
	ListPushFront(phead, -3);
	ListPushFront(phead, -4);
	ListPushFront(phead, -5);
	ListPrint(phead);
	//尾删
	printf("尾删测试: ");
	ListPopBack(phead);
	ListPrint(phead);
	//头删
	printf("头删测试: ");
	ListPopFront(phead);
	ListPrint(phead);
	//查找
	printf("查找测试: ");
	ListFind(phead, 0);
	//在pos之前插入x
	printf("找pos位置的数测试: ");
	ListNode* pos = ListFind(phead, 3);
	printf("插入x到pos位置之后的结果为: ");
	ListInsert(pos, 30);
	ListPrint(phead);
	//删除pos位置节点
	printf("找pos位置的数测试: ");
	ListNode* pos1 = ListFind(phead, 30);
	printf("删除pos位置之后的结果为: ");
	ListErase(pos1);
	ListPrint(phead);
	//链表的销毁
	ListDestory(phead);
	return 0;
}

(4) Test results

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_50886514/article/details/113815507