Detailed explanation of two-way leading circular linked list - > attached c language to create linked list code

catalogue

1, What is a two-way circular linked list

II Advantages and disadvantages of two-way cyclic linked list

III How to create a two-way circular linked list

IV Specific code

1, What is a two-way circular linked list

Definition: lead two-way circular linked list: the most complex structure, which is generally used to store data separately. The linked list data structure used in practice is a two-way circular linked list. In addition, although the structure is complex, you will find that the structure will bring many advantages after code implementation, but the implementation is simple. We will know after code implementation. The specific implementation process is shown in the figure below.

II Advantages and disadvantages of two-way cyclic linked list

Bidirectional circular linked list

Advantages: the two-way leading circular linked list has the advantages of precursor and successor, that is, it can be found in both directions

Disadvantages: subscript random access is not supported

Advantages and disadvantages of sequence table

Advantages: relatively speaking, the space utilization rate is higher, no additional space is required, and the occupied space is small (the linked list needs to store pointers). Physical space is continuous. Support random access and subscript access (maximum advantage); Cache hit rate is high.

Disadvantages: inserting or deleting data in the head or middle requires moving one by one, with high time complexity but small space complexity

III How to create a two-way circular linked list

1. First create the structure, then create the head node (equivalent to the sentry position), and link the new node through the head node

  typedef struct ListNode

{

       struct ListNode*prev;

       struct ListNode*next;

       LTDataType data;

}ListNode;

2. Initialize the node (focus, the first node needs to be considered as the head node)

ListNode*ListInit()

{

   ListNode*phead=BuyListNode(0);// At this time, phead is the sentinel position and serves as the head node

   phead->next=phead;

   phead->prev=phead;

          return phead;

}

3. Create nodes

ListNode* BuyListNode(LTDataType x)

{

       ListNode*node=(ListNode*)malloc(sizeof(ListNode));

       node->next=NULL;

       node->prev=NULL;

       node->data=x;

       return node;

}//Dynamic management space

4. Insert data (by inserting data, the head and tail insertion can also be realized, so the head and tail insertion can be realized by multiplexing)

void ListInsert(ListNode*pos,LTDataType x) / / insert data

{

       assert(pos);

       ListNode*newnode=BuyListNode(x);

       ListNode*prev=pos->prev;

       prev->next=newnode;

       newnode->prev=prev;

       newnode->next=pos;

       pos->prev=newnode;

}

5. Delete the specified data (similarly, tail deletion and header deletion can also be realized by reuse)

void ListErase(ListNode*pos) / / delete the data at the specified location

{

       assert(pos);

       ListNode*prev=pos->prev;

       ListNode*tail=pos->next;

       prev->next=tail;

       tail->prev=prev;

       free(pos);

}

6. Destroy the linked list

  void ListDestory(ListNode* phead)

{

       ListNode*cur=phead->next;

while(cur!=phead) / / release the internal node first

       {

              ListNode*next=cur->next;

              free(cur);  

              cur=next;

       }

       free(phead); // Release the header node again

}

IV Specific code

   1. Header file

#include<stdio.h>
#include<assert.h>
#include<stdlib.h> 
#include<malloc.h>
typedef int LTDataType;
typedef struct ListNode
{
	struct ListNode*prev;
	struct ListNode*next;
	LTDataType data;
}ListNode;
ListNode* BuyListNode(LTDataType x);
ListNode* ListInit();
void ListPushBack(ListNode* phead,LTDataType x);
void ListPusnFront(ListNode* phead,LTDataType x);
void ListPrint(ListNode*phead); 
void ListpopBack(ListNode*phead);//Tail deletion 
void ListPopFront(ListNode*phead);//Header deletion 
void ListInsert(ListNode*pos,LTDataType x);//insert data 
void ListErase(ListNode*pos);
void ListDestory(ListNode* phead);//Destroy
LTDataType ListEmpty(ListNode* phead);//Judge whether it is empty 
LTDataType ListFind(ListNode* phead,LTDataType x);

2. Main function module

#include"ListNode.h"
void Test()
{
    ListNode*plist=ListInit(0);	
    ListPushBack(plist,1);
    ListPushBack(plist,2);
	ListPushBack(plist,3);
	ListPushBack(plist,4);
	ListPushBack(plist,5);
	ListPushBack(plist,6);
	ListPusnFront(plist,88);
	ListpopBack(plist);
	ListPopFront(plist);
	ListInsert(plist->next->next,55);
	ListErase(plist->next->next);
    ListPrint(plist);
    LTDataType num=ListFind(plist,3);
    if(num==1)
    {
		printf("eureka\n"); 
	}
	else
	{
		printf("No,\n") ; 
	} 
	   LTDataType a=ListEmpty(plist); 
	     if(a==0)
	     {
		 	printf("empty\n"); 
		 }
		 else
		 {
		 printf("Non empty\n");	
		} 
    //int nums=ListEmpty(plist);
    //printf("%d",nums);
}
int main()
{
	Test();
	return 0;
}

3. Function implementation module

#include"ListNode.h"
ListNode* BuyListNode(LTDataType x)
{
	ListNode*node=(ListNode*)malloc(sizeof(ListNode));
	node->next=NULL;
	node->prev=NULL;
	node->data=x;
	return node;
}
ListNode*ListInit()
{
   ListNode*phead=BuyListNode(0);//At this time, phead is the sentinel position and serves as the head node 
   phead->next=phead;
   phead->prev=phead;
   	return phead;
} 
void ListPushBack(ListNode*phead,LTDataType x)//Tail insertion 
{
	/*assert(phead);
	ListNode*tail=phead->prev;
	ListNode*newnode=BuyListNode(x);
	tail->next=newnode;
	newnode->prev=tail;
	newnode->next=phead;
	phead->prev=newnode;*/ 
	ListInsert(phead,x);
}
void ListPusnFront(ListNode* phead,LTDataType x)//Head insert 
{
	/*assert(phead);
	ListNode*first=phead->next;
	ListNode*newnode=BuyListNode(x);
	first->prev=newnode;
    newnode->next=first;
    phead->next=newnode;
    newnode->prev=phead;*/
	ListInsert(phead->next,x);	
}
void ListPrint(ListNode*phead)
{
	ListNode*cur=phead->next;
	while(cur!=phead)
	{
		printf("%d ",cur->data);
		cur=cur->next;
	}
	printf("\n");
}
void ListpopBack(ListNode*phead)//Tail deletion 
{
	assert(phead);
   /*ListNode*tail=phead->prev;
	ListNode*tailPrev=tail->prev;
	free(tail);
	tailPrev->next=phead;
	phead->prev=tailPrev;*/
	ListErase(phead->prev);
}
void ListPopFront(ListNode*phead)//Header deletion 
{
    assert(phead);
	assert(phead->next!=phead);
	/*ListNode*first=phead->next;
	ListNode*firstnext=first->next;
	free(first);
	phead->next=firstnext;
	firstnext->prev=phead;*/
	ListErase(phead->next); 
}
void ListInsert(ListNode*pos,LTDataType x)//insert data 
{
	assert(pos);
	ListNode*newnode=BuyListNode(x);
	ListNode*prev=pos->prev;
	prev->next=newnode;
	newnode->prev=prev;
	newnode->next=pos;
	pos->prev=newnode;
} 
void ListErase(ListNode*pos)//Delete specified location data 
{
	assert(pos);
	ListNode*prev=pos->prev;
	ListNode*tail=pos->next;
	prev->next=tail;
	tail->prev=prev;
	free(pos);
}
void ListDestory(ListNode* phead)
{
	ListNode*cur=phead->next;
	while(cur!=phead)
	{
		ListNode*next=cur->next;
		free(cur);	
		cur=next;
	}
	free(phead); 
}
LTDataType  ListEmpty(ListNode* phead)//Determine whether the linked list is empty 
{
	if(phead->next==phead)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}
LTDataType ListFind(ListNode* phead,LTDataType x)
{
	ListNode* cur=phead->next;
	while(cur!=phead)
	{
		if(cur->data==x)
		{
			return 1; 
		}
		cur=cur->next;
	}
	return 0;
}

Keywords: C data structure Back-end linked list

Added by cloudbase on Thu, 20 Jan 2022 08:26:42 +0200