[Data Structure Course Design] Realization of Circular Doubly Linked List

foreword

Leading two-way circular linked list: the most complex structure, used to store data separately. The linked list data structure used in practice is a two-way circular linked list with the lead. In addition, although the structure is complex, after using the code to realize it, you will find that the structure will bring many advantages, and the implementation is simple.

Code

List.h

#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>

// 带头+双向+循环链表增删查改实现
typedef int LTDataType;
typedef struct ListNode
{
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}ListNode;

//链表的初始化
ListNode* ListNodeInit();
// 创建返回链表的头结点.
ListNode* ListCreate();
// 双向链表销毁
void ListDestory(ListNode* pHead);
// 双向链表打印
void ListPrint(ListNode* pHead);
// 双向链表尾插
void ListPushBack(ListNode* pHead, LTDataType x);
// 双向链表尾删
void ListPopBack(ListNode* pHead);
// 双向链表头插
void ListPushFront(ListNode* pHead, LTDataType x);
// 双向链表头删
void ListPopFront(ListNode* pHead);
// 双向链表查找
ListNode* ListFind(ListNode* pHead, LTDataType x);
// 双向链表在pos的前面进行插入
void ListInsert(ListNode* pos, LTDataType x);
// 双向链表删除pos位置的节点
void ListErase(ListNode* pos);
bool ListEmpty(ListNode* pHead);
size_t ListSize(ListNode* pHead);

List.c

#include "List.h"

ListNode* ListNodeInit()
{
	ListNode* guard = (ListNode*)malloc(sizeof(ListNode));
	if (guard == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

	guard->next = guard;
	guard->prev = guard;

	return guard;
}

ListNode* BuyListNode(LTDataType x)
{
	ListNode* node = (ListNode*)malloc(sizeof(ListNode));
	if (node == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}

    node->next = NULL;
	node->prev = NULL;
	node->data = x;
	return node;
}

void ListPrint(ListNode* pHead)
{
	printf("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* newnode = BuyListNode(x);
	ListNode* tail = pHead->prev;
	tail->next = newnode;
	newnode->prev = tail;
	newnode->next = pHead;
	pHead->prev = newnode;*/
	ListInsert(pHead, x);

}

void ListPushFront(ListNode* pHead, LTDataType x)
{
	assert(pHead);

	//ListNode* newnode = BuyListNode(x);
	//ListNode* frist = pHead->next;
	//pHead->next = newnode;
	//newnode->prev = pHead;
	//newnode->next = frist;
	//frist->prev = newnode;
	ListInsert(pHead->next, x);

}

void ListPopBack(ListNode* pHead)
{
	assert(pHead);
	assert(!ListEmpty(pHead));

	/*ListNode* tail = pHead->prev;
	ListNode* prev = tail->prev;
	prev->next = pHead;
	pHead->prev = prev;
	free(tail);
	tail = NULL;*/
	ListErase(pHead->prev);
}

void ListPopFront(ListNode* pHead)
{
	assert(pHead);

	//ListNode* frist = pHead->next;
	//ListNode* second = frist->next;
	//pHead->next = second;
	//second->prev = pHead;
	//free(frist);
	//frist = NULL;
	ListErase(pHead->next);
}

bool ListEmpty(ListNode* pHead)
{
	assert(pHead);
	return pHead->next == pHead;
}
size_t ListSize(ListNode* pHead)
{
	assert(pHead);
	size_t  n = 0;
	ListNode* cur = pHead->next;
	while (cur != pHead)
	{
		++n;
		cur = cur->next;
	}
	return n;
}

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)
{
	assert(pos);

	ListNode* prev = pos->prev;
	ListNode* newnode = BuyListNode(x);

	prev->next = newnode;
	newnode->prev = prev;
	newnode->next = pos;
	pos->prev = newnode;
}
void ListErase(ListNode* pos)
{
	assert(pos);
	ListNode* next = pos->next;
	ListNode* prev = pos->prev;
	prev->next = next;
	next->prev = prev;
	free(pos);
	pos = NULL;
}
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;
}

text.c

#include "List.h"

void Test1()
{
	ListNode* plist = ListNodeInit();

	ListPushBack(plist, 1);
	ListPushBack(plist, 2);
	ListPushBack(plist, 3);
	ListPushBack(plist, 4);

	ListPrint(plist);

	ListPopBack(plist);
	ListPopBack(plist);
	ListPopBack(plist);
	ListPopBack(plist);
	ListPrint(plist);
}
void Test2()
{
	ListNode* plist = ListNodeInit();

	ListPushBack(plist, 1);
	ListPushBack(plist, 2);
	ListPushBack(plist, 3);
	ListPushBack(plist, 4);
	ListPrint(plist);

	ListPopFront(plist);
	ListPopFront(plist);
	ListPrint(plist);

	ListPopFront(plist);
	ListPopFront(plist);
	ListPrint(plist);
	ListDestory(plist);
	plist = NULL;

}
int main()
{
	Test1();
	//Test2();
	return 0;
}

I won’t test them one by one here. The code should be fine. If you have any questions, you can chat with me privately.

Table of contents

foreword

Leading two-way circular linked list: the most complex structure, used to store data separately. The linked list data structure used in practice is a two-way circular linked list with the lead. In addition, although the structure is complex, after using the code to realize it, you will find that the structure will bring many advantages, and the implementation is simple.

Code

List.h

List.c

text.c

Guess you like

Origin blog.csdn.net/weixin_64214213/article/details/126182920