Data structure - linked list (c/c + +)

preface

This article is only for learning notes. If there are errors and deficiencies, please correct them.

1. Sequence table

1.1 definition of sequence table

The sequence table can be seen as a structure that stores an array and the length of the array.
Sequence table definition:

typedef int ElemType; 
typedef struct 
{	ElemType data[MaxSize];		//Storage order table element
   	int length;					//Length of storage sequence table
} SqList;

1.2 basic usage of sequence table

The basic usage is as follows:

void CreateList(SqList *&L,ElemType a[],int n)
//Create sequence table
{
	L=(SqList *)malloc(sizeof(SqList));
	for (int i=0;i<n;i++)
		L->data[i]=a[i];
	L->length=n;
}
//Initialization sequence table
void InitList(SqList *&L)
{
	L=(SqList *)malloc(sizeof(SqList));	//Allocate space for linear tables
	L->length=0;
}
//Destruction sequence table
void DestroyList(SqList *&L)
{
	free(L);
}
//Empty sequence table
bool ListEmpty(SqList *L)
{
	return(L->length==0);
}
//Gets the length of the sequence table
int ListLength(SqList *L)
{
	return(L->length);
}
//Output sequence table
void DispList(SqList *L)
{
	for (int i=0;i<L->length;i++)
		printf("%d ",L->data[i]);
	printf("\n");
}
//Gets the element of bit i of the sequence table
bool GetElem(SqList *L,int i,ElemType &e)
{
	if (i<1 || i>L->length)
		return false;
	e=L->data[i-1];
	return true;
}
//Gets the position of the element in the sequence table
int LocateElem(SqList *L, ElemType e)
{
	int i=0;
	while (i<L->length && L->data[i]!=e) i++;
	if (i>=L->length)
		return 0;
	else
		return i+1;
}
//Insert element
bool ListInsert(SqList *&L,int i,ElemType e)
{
	int j;
	if (i<1 || i>L->length+1)
		return false;
	i--;						//Convert sequence table bit order to elem subscript
	for (j=L->length;j>i;j--) 	//Move data[i] and the following elements back one position
		L->data[j]=L->data[j-1];
	L->data[i]=e;
	L->length++;				//Increase the length of sequence table by 1
	return true;
}
//Delete element
bool ListDelete(SqList *&L,int i,ElemType &e)
{
	int j;
	if (i<1 || i>L->length)
		return false;
	i--;						//Convert sequence table bit order to elem subscript
	e=L->data[i];
	for (j=i;j<L->length-1;j++)	//Move the element after data[i] forward one position
		L->data[j]=L->data[j+1];
	L->length--;				//Sequence table length minus 1
	return true;
}

2. Single linked list

2.1 definition of single linked list

Define single linked list:

typedef int ElemType;
typedef struct LNode  
{
	ElemType data;
	struct LNode *next;		//Point to successor node
} LinkNode;

Based on the structure of single linked list, single linked list has the following characteristics:
After accessing a node, you can only access its successor nodes, but not its predecessor nodes. (the pointer of the single linked list refers to the front, not the back)

The linked list is very much like a train. One node connects another node in one direction. The head node is like a locomotive. As the saying goes: "the train runs fast, all by the locomotive".
The benefits of using header nodes are:

Based on the above advantages, head nodes are used in single linked list, double linked list and partial circular linked list.

2.2 basic usage of single linked list

The basic usage of single linked list is as follows:

void CreateListF(LinkNode *&L,ElemType a[],int n)
//Establishing single linked list by head interpolation
{
	LinkNode *s;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//Create header node
	L->next=NULL;
	for (int i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//Create new node s
		s->data=a[i];
		s->next=L->next;			//Insert node s before the original start node and after the head node
		L->next=s;
	}
}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//Establishing single linked list by tail interpolation
{
	LinkNode *s,*r;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//Create header node
	L->next=NULL;
	r=L;					//r always points to the terminal node and at the beginning to the head node
	for (int i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//Create new node s
		s->data=a[i];
		r->next=s;			//Insert node s after node r
		r=s;
	}
	r->next=NULL;			//Set the next field of the terminal node to NULL
}
void InitList(LinkNode *&L)
{
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//Create header node
	L->next=NULL;
}
void DestroyList(LinkNode *&L)
{
	LinkNode *pre=L,*p=pre->next;
	while (p!=NULL)
	{	free(pre);
		pre=p;
		p=pre->next;
	}
	free(pre);	//At this time, p is NULL,pre points to the tail node and releases it
}
bool ListEmpty(LinkNode *L)
{
	return(L->next==NULL);
}
int ListLength(LinkNode *L)
{
	LinkNode *p=L;int i=0;
	while (p->next!=NULL)
	{	i++;
		p=p->next;
	}
	return(i);
}
void DispList(LinkNode *L)
{
	LinkNode *p=L->next;
	while (p!=NULL)
	{	printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L;
	if (i<=0) return false;		//i error return false
	while (j<i && p!=NULL)
	{	j++;
		p=p->next;
	}
	if (p==NULL)				//The ith data node does not exist
		return false;
	else						//The ith data node exists
	{	e=p->data;
		return true;
	}
}
int LocateElem(LinkNode *L,ElemType e)
{
	LinkNode *p=L->next;
	int n=1;
	while (p!=NULL && p->data!=e)
	{	p=p->next;
		n++;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
	int j=0;
	LinkNode *p=L,*s;
	if (i<=0) return false;			//i error return false
	while (j<i-1 && p!=NULL)		//Find the i-1 node p
	{	j++;
		p=p->next;
	}
	if (p==NULL)					//No node with bit order i-1 was found
		return false;
	else							//Find the node * p with bit order i-1
	{	s=(LinkNode *)malloc(sizeof(LinkNode));//Create new node * s
		s->data=e;
		s->next=p->next;			//Insert node s after node p
		p->next=s;
		return true;
	}
}

bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L,*q;
	if (i<=0) return false;		//i error return false
	while (j<i-1 && p!=NULL)	//Find the i-1 node
	{	j++;
		p=p->next;
	}
	if (p==NULL)				//No node with bit order i-1 was found
		return false;
	else						//Find the node p with bit order i-1
	{	q=p->next;				//q points to the node to be deleted
		if (q==NULL) 
			return false;		//If the ith node does not exist, false is returned
		e=q->data;
		p->next=q->next;		//Delete q node from single linked list
		free(q);				//Release q node
		return true;
	}
}

3. Double linked list

3.1 definition of double linked list

typedef int ElemType;
typedef struct DNode		//Define double linked list node type
{
	ElemType data;
	struct DNode *prior;	//Point to precursor node
	struct DNode *next;		//Point to successor node
} DLinkNode;

Based on the definition of double linked list, double linked list has the following characteristics:
Starting from any node, we can quickly find its predecessor node and successor node. From any node, you can access other nodes.
(I think it's more convenient than a single linked list)

3.2 basic use of double linked list

void CreateListF(DLinkNode *&L,ElemType a[],int n)
//Building double linked list by head inserting method
{
	DLinkNode *s;
	L=(DLinkNode *)malloc(sizeof(DLinkNode));  	//Create header node
	L->prior=L->next=NULL;
	for (int i=0;i<n;i++)
	{	
		s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node
		s->data=a[i];
		s->next=L->next;			//Insert node s before the original start node and after the head node
		if (L->next!=NULL) L->next->prior=s;
		L->next=s;s->prior=L;
	}
}
void CreateListR(DLinkNode *&L,ElemType a[],int n)
//Constructing double linked list by tail interpolation
{
	DLinkNode *s,*r;
	L=(DLinkNode *)malloc(sizeof(DLinkNode));  	//Create header node
	L->prior=L->next=NULL;
	r=L;					//r always points to the terminal node and at the beginning to the head node
	for (int i=0;i<n;i++)
	{	
		s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node
		s->data=a[i];
		r->next=s;s->prior=r;	//Insert node s after node r
		r=s;
	}
	r->next=NULL;				//Set the next field of the tail node to NULL
}
void InitList(DLinkNode *&L)
{
	L=(DLinkNode *)malloc(sizeof(DLinkNode));  	//Create header node
	L->prior=L->next=NULL;
}
void DestroyList(DLinkNode *&L)
{
	DLinkNode *pre=L,*p=pre->next;
	while (p!=NULL)
	{
		free(pre);
		pre=p;
		p=pre->next;
	}
	free(pre);
}
bool ListEmpty(DLinkNode *L)
{
	return(L->next==NULL);
}
int ListLength(DLinkNode *L)
{
	DLinkNode *p=L;
	int i=0;
	while (p->next!=NULL)
	{
		i++;
		p=p->next;
	}
	return(i);
}
void DispList(DLinkNode *L)
{
	DLinkNode *p=L->next;
	while (p!=NULL)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(DLinkNode *L,int i,ElemType &e)
{
	int j=0;
	DLinkNode *p=L;
	if (i<=0) return false;		//i error return false
	while (j<i && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)
		return false;
	else
	{
		e=p->data;
		return true;
	}
}
int LocateElem(DLinkNode *L,ElemType e)
{
	int n=1;
	DLinkNode *p=L->next;
	while (p!=NULL && p->data!=e)
	{
		n++;
		p=p->next;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(DLinkNode *&L,int i,ElemType e)
{
	int j=0;
	DLinkNode *p=L,*s;
	if (i<=0) return false;		//i error return false
	while (j<i-1 && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)				//Node i-1 not found
		return false;
	else						//Find the i-1 node p
	{
		s=(DLinkNode *)malloc(sizeof(DLinkNode));	//Create new node s
		s->data=e;	
		s->next=p->next;		//Insert node s after node p
		if (p->next!=NULL) 
			p->next->prior=s;
		s->prior=p;
		p->next=s;
		return true;
	}
}
bool ListDelete(DLinkNode *&L,int i,ElemType &e)
{
	int j=0;
	DLinkNode *p=L,*q;
	if (i<=0) return false;		//i error return false
	while (j<i-1 && p!=NULL)
	{
		j++;
		p=p->next;
	}
	if (p==NULL)				//Node i-1 not found
		return false;
	else						//Find the i-1 node p
	{
		q=p->next;				//q points to the node to be deleted
		if (q==NULL) 
			return false;		//The ith node does not exist
		e=q->data;
		p->next=q->next;		//Delete * q node from single linked list
		if (p->next!=NULL) p->next->prior=p;
		free(q);				//Release q node
		return true;
	}
}

4. Cycle table

4.1 introduction to cycle table

Because the circular list is based on single linked list and double linked list, there are two kinds of circular linked list: circular single linked list and circular double linked list.


Circular single chain indicates intention;

Circular double chain indicates the intention:

4.2 basic use of circular single linked list

void CreateListF(LinkNode *&L,ElemType a[],int n)
//Establishment of circular single linked list by head interpolation
{
	LinkNode *s;int i;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//Create header node
	L->next=NULL;
	for (i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//Create a new node
		s->data=a[i];
		s->next=L->next;			//Insert node s before the original start node and after the head node
		L->next=s;
	}
	s=L->next;	
	while (s->next!=NULL)			//Find the tail node and point to it by s
		s=s->next;
	s->next=L;						//The tail node next field points to the head node

}
void CreateListR(LinkNode *&L,ElemType a[],int n)
//Establishment of circular single chain table by tail interpolation
{
	LinkNode *s,*r;int i;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//Create header node
	L->next=NULL;
	r=L;					//r always points to the terminal node and at the beginning to the head node
	for (i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//Create a new node
		s->data=a[i];
		r->next=s;			//Insert node s after node r
		r=s;
	}
	r->next=L;				//The tail node next field points to the head node
}
void InitList(LinkNode *&L)
{
	L=(LinkNode *)malloc(sizeof(LinkNode));	//Create header node
	L->next=L;
}
void DestroyList(LinkNode *&L)
{
	LinkNode *p=L,*q=p->next;
	while (q!=L)
	{
		free(p);
		p=q;
		q=p->next;
	}
	free(p);
}
bool ListEmpty(LinkNode *L)
{
	return(L->next==L);
}
int ListLength(LinkNode *L)
{
	LinkNode *p=L;int i=0;
	while (p->next!=L)
	{
		i++;
		p=p->next;
	}
	return(i);
}
void DispList(LinkNode *L)
{
	LinkNode *p=L->next;
	while (p!=L)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(LinkNode *L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p;
	if (L->next!=L)		//When the single linked table is not empty
	{
		if (i==1)
		{
			e=L->next->data;
			return true;
		}
		else			//When i is not 1
		{
			p=L->next;
			while (j<i-1 && p!=L)
			{
				j++;
				p=p->next;
			}
			if (p==L)
				return false;
			else
			{
				e=p->data;
				return true;
			}
		}
	}
	else				//When the single linked table is empty
		return false;
}
int LocateElem(LinkNode *L,ElemType e)
{
	LinkNode *p=L->next;
	int n=1;
	while (p!=L && p->data!=e)
	{
		p=p->next;
		n++;
	}
	if (p==L)
		return(0);
	else
		return(n);
}
bool ListInsert(LinkNode *&L,int i,ElemType e)
{
	int j=0;
	LinkNode *p=L,*s;
	if (p->next==L || i==1)		//When the original single linked list is empty or i==1
	{
		s=(LinkNode *)malloc(sizeof(LinkNode));	//Create new node s
		s->data=e;								
		s->next=p->next;		//Insert node s after node p
		p->next=s;
		return true;
	}
	else
	{
		p=L->next;
		while (j<i-2 && p!=L)
		{
			j++;
			p=p->next;
		}
		if (p==L)				//Node i-1 not found
			return false;
		else					//Find the i-1 node p
		{
			s=(LinkNode *)malloc(sizeof(LinkNode));	//Create new node s
			s->data=e;								
			s->next=p->next;						//Insert node s after node p
			p->next=s;
			return true;
		}
	}
}
bool ListDelete(LinkNode *&L,int i,ElemType &e)
{
	int j=0;
	LinkNode *p=L,*q;
	if (p->next!=L)					//When the original single linked list is not empty
	{
		if (i==1)					//When i==1
		{
			q=L->next;				//Delete the first node
			e=q->data;
			L->next=q->next;
			free(q);
			return true;
		}
		else						//When i is not 1
		{
			p=L->next;
			while (j<i-2 && p!=L)
			{
				j++;
				p=p->next;
			}
			if (p==L)				//Node i-1 not found
				return false;
			else					//Find the i-1 node p
			{
				q=p->next;			//q points to the node to be deleted
				e=q->data;
				p->next=q->next;	//Delete q node from single linked list
				free(q);			//Release q node
				return true;
			}
		}
	}
	else return false;
}

4.3 basic use of circular double linked list

void CreateListF(DLinkNode *&L,ElemType a[],int n)
//Establishing circular double linked list by head interpolation
{
	DLinkNode *s;int i;
	L=(DLinkNode *)malloc(sizeof(DLinkNode));  	//Create header node
	L->next=NULL;
	for (i=0;i<n;i++)
	{	
		s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node
		s->data=a[i];
		s->next=L->next;			//Insert node s before the original start node and after the head node
		if (L->next!=NULL) L->next->prior=s;
		L->next=s;s->prior=L;
	}
	s=L->next;	
	while (s->next!=NULL)			//Find the tail node and point to it by s
		s=s->next;
	s->next=L;						//The tail node next field points to the head node
	L->prior=s;						//The head node's prior field points to the tail node

}
void CreateListR(DLinkNode *&L,ElemType a[],int n)
//Establishment of circular double linked list by tail interpolation
{
	DLinkNode *s,*r;int i;
	L=(DLinkNode *)malloc(sizeof(DLinkNode));  //Create header node
	L->next=NULL;
	r=L;					//r always points to the tail node and at the beginning to the head node
	for (i=0;i<n;i++)
	{	
		s=(DLinkNode *)malloc(sizeof(DLinkNode));//Create a new node
		s->data=a[i];
		r->next=s;s->prior=r;	//Insert node s after node r
		r=s;
	}
	r->next=L;				//The tail node next field points to the head node
	L->prior=r;				//The head node's prior field points to the tail node
}
void InitList(DLinkNode *&L)
{
	L=(DLinkNode *)malloc(sizeof(DLinkNode));  	//Create header node
	L->prior=L->next=L;
}
void DestroyList(DLinkNode *&L)
{
	DLinkNode *p=L,*q=p->next;
	while (q!=L)
	{
		free(p);
		p=q;
		q=p->next;
	}
	free(p);
}
bool ListEmpty(DLinkNode *L)
{
	return(L->next==L);
}
int ListLength(DLinkNode *L)
{
	DLinkNode *p=L;
	int i=0;
	while (p->next!=L)
	{
		i++;
		p=p->next;
	}
	return(i);
}
void DispList(DLinkNode *L)
{
	DLinkNode *p=L->next;
	while (p!=L)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}
bool GetElem(DLinkNode *L,int i,ElemType &e)
{
	int j=0;
	DLinkNode *p;
	if (L->next!=L)		//When the double linked list is not empty
	{
		if (i==1)
		{
			e=L->next->data;
			return true;
		}
		else			//When i is not 1
		{
			p=L->next;
			while (j<i-1 && p!=L)
			{
				j++;
				p=p->next;
			}
			if (p==L)
				return false;
			else
			{
				e=p->data;
				return true;
			}
		}
	}
	else				//When the double linked list is empty
		return 0;
}
int LocateElem(DLinkNode *L,ElemType e)
{
	int n=1;
	DLinkNode *p=L->next;
	while (p!=NULL && p->data!=e)
	{
		n++;
		p=p->next;
	}
	if (p==NULL)
		return(0);
	else
		return(n);
}
bool ListInsert(DLinkNode *&L,int i,ElemType e)
{
	int j=0;
	DLinkNode *p=L,*s;
	if (p->next==L)					//When the original double linked list is empty
	{	
		s=(DLinkNode *)malloc(sizeof(DLinkNode));	//Create new node s
		s->data=e;
		p->next=s;s->next=p;
		p->prior=s;s->prior=p;
		return true;
	}
	else if (i==1)					//When the original double linked list is not empty but i=1
	{
		s=(DLinkNode *)malloc(sizeof(DLinkNode));	//Create new node s
		s->data=e;
		s->next=p->next;p->next=s;	//Insert node s after node p
		s->next->prior=s;s->prior=p;
		return true;
	}
	else
	{	
		p=L->next;
		while (j<i-2 && p!=L)
		{	j++;
			p=p->next;
		}
		if (p==L)				//Node i-1 not found
			return false;
		else					//Find node i-1 * p
		{
			s=(DLinkNode *)malloc(sizeof(DLinkNode));	//Create new node s
			s->data=e;	
			s->next=p->next;	//Insert node s after node p
			if (p->next!=NULL) p->next->prior=s;
			s->prior=p;
			p->next=s;
			return true;
		}
	}
}
bool ListDelete(DLinkNode *&L,int i,ElemType &e)
{
	int j=0;
	DLinkNode *p=L,*q;
	if (p->next!=L)					//When the original double linked list is not empty
	{	
		if (i==1)					//When i==1
		{	
			q=L->next;				//Delete the first node
			e=q->data;
			L->next=q->next;
			q->next->prior=L;
			free(q);
			return true;
		}
		else						//When i is not 1
		{	
			p=L->next;
			while (j<i-2 && p!=NULL)		
			{
				j++;
				p=p->next;
			}
			if (p==NULL)				//Node i-1 not found
				return false;
			else						//Find the i-1 node p
			{
				q=p->next;				//q points to the node to be deleted
				if (q==NULL) return 0;	//The ith node does not exist
				e=q->data;
				p->next=q->next;		//Delete q node from single linked list
				if (p->next!=NULL) p->next->prior=p;
				free(q);				//Release q node
				return true;
			}
		}
	}
	else return false;					//When the original double linked list is empty
}

Tags: C data structure linked list

Posted on Sun, 31 Oct 2021 10:11:46 -0400 by iantresman