Doubly linked list in seconds

Hello, sister A Zi called all the martial arts warriors today, what's the matter? ? ?

Everyone answered: Of course, Sister Azi is here to lead us to learn new kung fu! ! !


First of all, you have to warm up before practicing kung fu (I tell you in a low voice, the warm-up sister Azi said is chicken soup for the soul)

  • Persistence is victory. Whenever we can't persevere, we have to tell ourselves that victory is not far away, and if we give up, our previous efforts will be in vain.
  • Keep on, keep on, keep on! ! !
  • Persistence is the secret to doing anything.

review:

First, let's take a look at what are the disadvantages of a singly linked list? ? ?

The main disadvantages of singly linked list: ① can not traverse from back to front ② can not find the predecessor


Singly linked list defect solution - "Double linked list:

There are eight linked list structures:


 The code implementation of the doubly circular linked list with the head:

list.h: header file

#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#pragma once

typedef int LTDataType;

//带头双向循环---最有链表结构,任意位置插入删除数据都是O(1)
typedef struct ListNode
{
	struct ListNode* next;
	struct ListNode* prev;
	LTDataType data;
}ListNode;

//初始化
ListNode* ListInit(ListNode* phead);


//尾插
void ListPushBack(ListNode* phead,LTDataType x);

//头插
void ListPushFront(ListNode* phead, LTDataType x);

//打印
void ListPrint(ListNode* phead);

//头删
void ListPopFront(ListNode* phead);

//尾删
void ListPopBack(ListNode* phead);

//查找
ListNode* ListFind(ListNode* phead, LTDataType x);

//pos位置之前插入x
void ListInsert(ListNode* pos, LTDataType x);

//删除pos位置的值
void ListErase(ListNode* pos);

//销毁链表
void ListDestory(ListNode* phead);

In the header file, the header file inclusion, structure declaration, type redefinition, and custom function declaration of library functions are carried out


test.c: test file

#define  _CRT_SECURE_NO_WARNINGS 1
#include"list.h"
void TestList1()
{
	ListNode* plist = NULL;
	plist = ListInit(plist);
	ListPushBack(plist, 1);
	ListPushBack(plist, 2);
	ListPushBack(plist, 3);
	ListPushBack(plist, 4);
	ListPushBack(plist, 5);
	ListPushBack(plist, 6);
	ListPrint(plist);

	ListPushFront(plist, 0);
	ListPrint(plist);

	ListPopFront(plist);
	ListPrint(plist);

	ListPopBack(plist);
	ListPrint(plist);

	ListNode* pos = ListFind(plist, 3);
	if (pos)
	{
		//查找附带修改作用
		pos->data *= 10;
		printf("找到了,并且*10\n");
	}
	else
	{
		printf("没有找到\n");
	}
	ListPrint(plist);

	ListInsert(pos, 300);
	ListPrint(plist);

	ListErase(pos);
	ListPrint(plist);

	ListDestory(plist);
}
int main()
{

	TestList1();
	return 0;
}

Mainly test the function of our double linked list


Next, let's look at the implementation of the custom function one by one:

Linked list initialization:

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

ListNode* ListInit(ListNode* phead)
{
	phead = BuyListNode(0);
	phead->next = phead;
	phead->prev = phead;

	return phead;
}

tail plug

ListNode* BuyListNode(LTDataType x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	if (newnode == NULL)
	{
		return;
	}
	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;
	newnode->next = phead;
	phead->prev = newnode;

}

 tail deletion

void ListPopBack(ListNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	ListNode* tail = phead->prev;
	ListNode* prev = tail->prev;
	prev->next = phead;
	phead->prev = prev;
	free(tail);
	tail = NULL;
}

 Header:

ListNode* BuyListNode(LTDataType x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	if (newnode == NULL)
	{
		return;
	}
	newnode->data = x;
	newnode->next = NULL;
	newnode->prev = NULL;
	return newnode;
}
void ListPushFront(ListNode* phead, LTDataType x)
{
	assert(phead);
	ListNode* first = phead->next;
	ListNode* newnode = BuyListNode(x);

	phead->next = newnode;
	newnode->prev = phead;
	newnode->next = first;
	first->prev = newnode;
}

 Header delete:

void ListPopFront(ListNode* phead)
{
	assert(phead);
	assert(phead->next != phead);
	ListNode* first = phead->next;
	ListNode* second = first->next;
	phead->next = second;
	second->prev = phead;

	free(first);
	first = NULL;
}

Print:

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

 Find:

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;
}

cur points to the first node, when the data field of the node is not equal to x, go to the next node, if the phead is not found at the end, it means there is no.

Insert a node before a node:

void ListInsert(ListNode* pos, LTDataType x)
{
	assert(pos);
	ListNode* newnode = BuyListNode(x);

	ListNode* prev = pos->prev;
	prev->next = newnode;
	newnode->prev = prev;
	newnode->next = pos;
	pos->prev = newnode;
}

 Delete a node:

void ListErase(ListNode* pos)
{
	assert(pos);
	ListNode* prev = pos->prev;
	ListNode* next = pos->next;

	prev->next = next;
	next->prev = prev;
	 
	free(pos);
	pos = NULL;

}

 Destroy the linked list:

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;
}


Have you learned the double linked list martial arts today? ? ?

QQ.2186529582
Let's refuel together and be one step closer to success! ! !

 Well that's it for today! ! !

Guess you like

Origin blog.csdn.net/m0_66488562/article/details/123460220