[Data structure] Interface implementation of doubly linked list (with attached solution and source code)

Interface implementation of doubly linked list (with solution and source code)



foreword

This article mainly introduces the implementation of interfaces such as adding, deleting, checking and modifying in the doubly linked list , and the total source code is attached at the end !


1. Define the structure

insert image description here

The code is as follows (example):

typedef int LTDataType;
typedef struct ListNode
{
    
    
	LTDataType data;
	struct ListNode* prev;
	struct ListNode* next;
}ListNode;

2. Interface implementation (attached solution + source code)

insert image description here

There are a total of 10 interfaces here, and I will explain them to you one by one ( illustration + source code )


1. Initialize the doubly linked list

Initialize a sentinel head node (opened with malloc), and both next and prev point to itself. The details are as shown in the figure below!
insert image description here
insert image description here

The code is as follows (example):

ListNode* ListInit()
{
    
    
	ListNode* p = (ListNode*)malloc(sizeof(ListNode));
	if (p == NULL)
	{
    
    
		perror(errno);
	}
	ListNode* phead = p;
	phead->next = phead;
	phead->prev = phead;
	return phead;
}

2. Open up new space

(1) Open up a dynamic space of linked list type, and give the address to newnode;
(2) Put the value into the data data of newnode;
(3) Set the next and prev of newnode to NULL;
Note: 1. Open up malloc When the space is stored in newnode, the parameter is the byte size occupied by the structure! 2. Make a NULL judgment on newnode!

The code is as follows (example):

ListNode* BuyListNode(LTDataType x)
{
    
    
	ListNode* p = (ListNode*)malloc(sizeof(ListNode));
	if (p == NULL)
	{
    
    
		perror(errno);
	}
	ListNode* newNode = p;
	newNode->data = x;
	newNode->next = NULL;
	newNode->prev = NULL;
	return newNode;
}

3. Tail plug data

insert image description here


insert image description here


insert image description here


The code is as follows (example):

void ListPushBack(ListNode* phead, LTDataType x)//尾插数据
{
    
    
	ListNode* tail = phead->prev;
	ListNode* newnode = BuyListNode(x);

	//第一个链接
	tail->next = newnode;
	newnode->prev = tail;
	//第二个链接
	phead->prev = newnode;
	newnode->next = phead;
}

4. Delete data at the end

Here two assertions are required:
insert image description here


insert image description here


insert image description here


The code is as follows (example):

void ListPopBack(ListNode* phead)//尾删
{
    
    
	assert(phead);
	assert(phead->next != phead);

	ListNode* tail = phead->prev;
	ListNode* tailprev = tail->prev;
	free(tail);

	//连接
	tailprev->next = phead;
	phead->prev = tailprev;
}

5. Print the data in the doubly linked list

insert image description here


The code is as follows (example):

void ListPrint(ListNode* phead)//打印数据
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}

6. Head plug data

The plug-in data is also a very simple interface, just link twice, as shown in the figure below !
insert image description here


The code is as follows (example):

void ListPushFront(ListNode* phead, LTDataType x)//头插
{
    
    
	assert(phead);
	ListNode* newNode = BuyListNode(x);
    ListNode* next = phead->next;
	phead->next = newNode;
	newNode->prev = phead;
	newNode->next = next;
	next->prev = newNode;
}

7. Header delete data

When deleting data at the head and deleting data at the end, two assertions are required ! As shown below!
insert image description here


insert image description here


insert image description here


insert image description here


The code is as follows (example):

void ListPopFront(ListNode* phead)//头删
{
    
    
	assert(phead);
	assert(phead->next != phead);

	ListNode* next = phead->next;
	ListNode* nextNext = next->next;

	phead->next = nextNext;
	nextNext->prev = phead;
	free(next);
}

8. Find the node position

This is relatively simple, just like the single-linked list, just use cur to traverse directly, and directly upload the code :

The code is as follows (example):

ListNode* ListFind(ListNode* phead, LTDataType x)
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		if (cur->data == x)
		{
    
    
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

9. Insert before pos position

insert image description here


insert image description here


The code is as follows (example):

void ListInsert(ListNode* pos, LTDataType x)//pos位置之前插入
{
    
    
	assert(pos);
	ListNode* newNode = BuyListNode(x);
	ListNode* posPrev = pos->prev;

	// posPrev  newnode pos
	posPrev->next = newNode;
	newNode->prev = posPrev;
	newNode->next = pos;
	pos->prev = newNode;
}

According to the ListInsert interface, we can modify the header and tail inserts, as shown in the figure below!
insert image description here


insert image description here


10. Delete pos position

insert image description here


insert image description here


insert image description here


The code is as follows (example):

void ListErase(ListNode* pos)//删除pos位置
{
    
    
	assert(pos);
	ListNode* prev = pos->prev;
	ListNode* next = pos->next;
	free(pos);
	pos = NULL;
	prev->next = next;
	next->prev = prev;
}

11. Destroy the doubly linked list

insert image description here


insert image description here


The code is as follows (example):

void ListDestory(ListNode* phead)
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		ListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	free(phead);
	phead = NULL;
}

3. Source code display

1.test.c (test + main function)

The code is as follows (example):

#include "list.h"
void Testlist1()
{
    
    
	ListNode* n1 = ListInit();
	ListPushBack(n1, 1);//尾插
	ListPushBack(n1, 2);//尾插
	//ListPushBack(n1, 3);//尾插
	//ListPushBack(n1, 4);//尾插
	//ListPushBack(n1, 5);//尾插
	//ListPopFront(n1);//头删
	//ListPopBack(n1);//尾删
	//ListPushFront(n1, 0);//头插
	ListPrint(n1);
}
void Testlist2()
{
    
    
	ListNode* n1 = ListInit();
	ListPushBack(n1, 1);//尾插
	ListPushBack(n1, 2);//尾插
	ListPushBack(n1, 3);//尾插
	ListPushBack(n1, 4);//尾插
	ListPushBack(n1, 5);//尾插
	ListNode* p = ListFind(n1, 5);
	printf("%d \n", p->data);
}
void Testlist3()
{
    
    
	ListNode* n1 = ListInit();
	ListPushBack(n1, 1);//尾插
	ListPushBack(n1, 2);//尾插
	ListPushBack(n1, 3);//尾插
	ListPushBack(n1, 4);//尾插
	ListPushBack(n1, 5);//尾插
	//ListNode* p = ListFind(n1, 5);
	//ListInsert(p, 0);
	ListDestory(n1);
	ListPrint(n1);
}
int main()
{
    
    
	//Testlist1();
	//Testlist2();
	Testlist3();
	return 0;
}

2.List.h (declaration of interface functions)

The code is as follows (example):

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
typedef int LTDataType;
typedef struct ListNode
{
    
    
	LTDataType data;
	struct ListNode* prev;
	struct ListNode* next;
}ListNode;
ListNode* ListInit();//初始化双向链表
void ListPushBack(ListNode* phead, LTDataType x);//尾插
void ListPopBack(ListNode* phead);//尾删
void ListPushFront(ListNode* phead, LTDataType x);//头插
void ListPopFront(ListNode* phead);//头删
void ListPrint(ListNode* phead);//打印
ListNode* ListFind(ListNode* phead, LTDataType x);//查找数据
void ListInsert(ListNode* pos, LTDataType x);//pos位置之前插入
void ListErase(ListNode* pos);//删除pos位置
void ListDestory(ListNode* phead);//销毁双向链表

3.List.c (implementation of interface functions)

The code is as follows (example):

#include "list.h"
ListNode* ListInit()
{
    
    
	ListNode* p = (ListNode*)malloc(sizeof(ListNode));
	if (p == NULL)
	{
    
    
		perror(errno);
	}
	ListNode* phead = p;
	phead->next = phead;
	phead->prev = phead;
	return phead;
}
ListNode* BuyListNode(LTDataType x)
{
    
    
	ListNode* p = (ListNode*)malloc(sizeof(ListNode));
	if (p == NULL)
	{
    
    
		perror(errno);
	}
	ListNode* newNode = p;
	newNode->data = x;
	newNode->next = NULL;
	newNode->prev = NULL;
	return newNode;
}
void ListPushBack(ListNode* phead, LTDataType x)//尾插数据
{
    
    
	ListNode* tail = phead->prev;
	ListNode* newnode = BuyListNode(x);

	//第一个链接
	tail->next = newnode;
	newnode->prev = tail;
	//第二个链接
	phead->prev = newnode;
	newnode->next = phead;
	//ListInsert(phead, x);
}
void ListPrint(ListNode* phead)//打印数据
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		printf("%d ", cur->data);
		cur = cur->next;
	}
	printf("\n");
}
void ListPopBack(ListNode* phead)//尾删
{
    
    
	assert(phead);
	assert(phead->next != phead);

	ListNode* tail = phead->prev;
	ListNode* tailprev = tail->prev;
	free(tail);

	//连接
	tailprev->next = phead;
	phead->prev = tailprev;
}
void ListPushFront(ListNode* phead, LTDataType x)//头插
{
    
    
	assert(phead);
	ListNode* newNode = BuyListNode(x);
	ListNode* next = phead->next;
	phead->next = newNode;
	newNode->prev = phead;
	newNode->next = next;
	next->prev = newNode;
	//ListInsert(phead->next, x);
}
void ListPopFront(ListNode* phead)//头删
{
    
    
	assert(phead);
	assert(phead->next != phead);

	ListNode* next = phead->next;
	ListNode* nextNext = next->next;

	phead->next = nextNext;
	nextNext->prev = phead;
	free(next);
}
ListNode* ListFind(ListNode* phead, LTDataType x)
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		if (cur->data == x)
		{
    
    
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}
void ListInsert(ListNode* pos, LTDataType x)//pos位置之前插入
{
    
    
	assert(pos);
	ListNode* newNode = BuyListNode(x);
	ListNode* posPrev = pos->prev;

	// posPrev  newnode pos
	posPrev->next = newNode;
	newNode->prev = posPrev;
	newNode->next = pos;
	pos->prev = newNode;
}
void ListErase(ListNode* pos)//删除pos位置
{
    
    
	assert(pos);
	ListNode* prev = pos->prev;
	ListNode* next = pos->next;
	free(pos);
	pos = NULL;
	prev->next = next;
	next->prev = prev;
}
void ListDestory(ListNode* phead)
{
    
    
	assert(phead);
	ListNode* cur = phead->next;
	while (cur != phead)
	{
    
    
		ListNode* next = cur->next;
		free(cur);
		cur = next;
	}
	free(phead);
	phead = NULL;
}

Summarize

The above is what I will talk about today. This article introduces the interface implementation of the doubly linked list (with attached solution and source code).
If my blog is helpful to you, remember to support it three times, thank you for your support!
insert image description here

Guess you like

Origin blog.csdn.net/2201_75587702/article/details/129215687