Learning "Introduction to Algorithms" (12) - linked list (C language)


foreword

The article mainly explains the related explanations of the linked list, involves the operation functions of the single linked list, the double linked list, and the circular linked list, and implements it in C language


1. Linked list

1. What is a linked list?

To understand linked lists, we must first talk about arrays.
The array is the sequential storage structure of the computer, which fits the hardware architecture of the computer

The linked list is a linked storage structure. Its storage method uses pointers as links , and then the structure space as nodes . connect the nodes with a chain
As far as the underlying structure of the computer is concerned, the address space between any two nodes of the chain structure has no connection

2. Why do you need a linked list?

The advantage of the sequential structure is that it is very convenient to find and access, becauseIt satisfies the lowest hardware architecture of the computer

However, the insertion and deletion of array elements is very inconvenient, which can be calledmove the whole body, to insert an array in the middle of the array. If you want to keep the original element order unchanged, you need to re-transpose the elements of the entire array; the same is true for deletion.

At this time we use the linked list, the best job of the linked list is to delete and insert elements, because
Its storage structure is chained, and the connection between nodes is maintained by the chain
Therefore, inserting and deleting elements only needs to change the "chain" and release the storage space of the nodes.

2. Singly linked list

1. Data structure

typedef struct body
{
    
    
	int value;
	struct body *next;
}; 

2. Operation function

#include<stdio.h>
#include<stdlib.h>
char a[10001];
char b[3]; 
typedef struct body
{
    
    
	int value;
	struct body *next;
}; 
body *init()
{
    
    
	body *first=(body*)malloc(sizeof(body));
	first->next=NULL;
	first->value=0;
	printf("创建成功\n");
	return first; 
}
void isemp(body *first)
{
    
    
	if(first->next==NULL||first==NULL)
	{
    
    
		printf("单链表为空\n");
	}
	else printf("单链表不为空\n"); 
}
void printlinelist(body *first)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("单链表为空表\n");
	}
	else
	{
    
    
		body* per;
		per=first->next;
		while(per->next!=NULL)
		{
    
    
			printf("%d  ",per->value);
			per=per->next;
		}
		printf("%d\n",per->value);
	}
}
int length(body *first)
{
    
    
	if(first->next==NULL)
	{
    
    
		return 0;
	}
	else
	{
    
    
		return first->value;
	}
}
int getvalue(body *first,int i)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("单链表为空表,取值无效\n");
		return 0;
	}
	else if(i<=0)
	{
    
    
		printf("位置信息不合规范\n");
		return 0;
	}
	else if(i>first->value)
	{
    
    
		printf("超过单链表大小\n");
		return 0;
	}
	else
	{
    
    
		int count=1;
		body *per;
		per=first;
		while(count!=i)
		{
    
    
			per=per->next;
			count++;
		}
		return per->next->value;	
	} 
}
int getlocation(body *first,int value1)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("单链表为空表\n");
		return 0;
	}
	else
	{
    
    
		int count=0;
		body *per;
		per=first->next;
		while(per->next!=NULL)
		{
    
    
			count++;
			if(per->value==value1)
			{
    
    
				return count;
			}
			per=per->next;
		}
		if(per->value==value1)
		{
    
    
			return count+1;
		}
		 else 
		 {
    
    
		 	printf("没有该值\n");
			 return 0;	
		 }
	}
 } 
void insert(body* first,int i,int value1)
{
    
    
	if(i<=0)
	{
    
    
		printf("插入失败\n");
	}
	else
	{
    
    
		body *per;
		per=first;
		int count;
		count=first->value;
		if(i>count+1)
		{
    
    
			printf("插入失败\n");
		}
		else if(i==count+1)
		{
    
    
			while(per->next!=NULL)
			{
    
    
				per=per->next;
			}
			body *l1;
			l1=(body*)malloc(sizeof(body));
			per->next=l1;
			l1->next=NULL;
			l1->value=value1;
			first->value=first->value+1;
			printf("插入成功\n");
		} 
		else
		{
    
    
			count=1;
			per=first;
			while(count!=i)
			{
    
    
				per=per->next;//per是第i个位置的元素 
				count++;
			} 
			body* temp;
			temp=(body*)malloc(sizeof(body));
			temp->next=per->next;
			per->next=temp;
			temp->value=value1;
			first->value=first->value+1;
			printf("插入成功\n");
		}
	}
}
void delet(body *first,int i)
{
    
    
	body* per;
	per=first;
	int count;
	count=first->value;
	if(i<0||per->next==NULL)
	{
    
    
		printf("删除失败\n");
	}
	else if(i==count)
	{
    
    
		per=first;
		while(per->next->next!=NULL)
		{
    
    
			per=per->next;
		}
		free(per->next);
		per->next=NULL;
		first->value=first->value-1;
		printf("删除成功\n");
	}
	else if(i>count)
	{
    
    
		printf("超过单链表大小\n");
	}
	else
	{
    
    
		per=first;
		count=1;
		while(count!=i)
		{
    
    
			per=per->next;
			count++;
		}
		body* temp;
		temp=per;
		per=per->next;
		temp->next=per->next;
		free(per);
		first->value=first->value-1;
		printf("删除成功\n");
	}
}
body* creatlinelist(int a[],int i)
{
    
    
	if(i<=0)
	{
    
    
		printf("创建失败\n");
		return NULL;
	}
	else
	{
    
    
		body *first=NULL;
		first=(body*)malloc(sizeof(body));
		body *s=NULL;
		first->value=i;
		body *per;
		per=first;
		for(int k=0;k<i;k++)
		{
    
    
			s=(body*)malloc(sizeof(body));
			s->value=a[k];
			per->next=s;
			per=per->next;
		}
		s->next=NULL;
		printf("创建成功\n");
		return first; 
	}
}
void destroy(body *first)
{
    
    
	body* per;
	first->value=0;
	per=first->next;
	for(int i=1;i<=first->value;i++)
	{
    
    
		body* temp;
		temp=per;
		per=per->next;
		free(temp);
	}
	first->next=NULL; 
	printf("销毁完成\n"); 
}
int main()
{
    
    
	body *l;
	l=init();
    body *l1;
    l1=init();
    int num;
    scanf("%d",&num);
    int number1=0;
    int number2=0;
    int i=0;
    for(int i=0;i<num;i++)
    {
    
    
        scanf("%c",&a[i]);
        printf("%c  ",a[i]);
		if(a[i]==1)
		{
    
    
			number1++;	
		}
		if(a[i]==0)
		{
    
    
			number2++;	
		}
		i++;	
	}
	return 0;
}

Three, doubly linked list

1. Data structure

typedef struct body
{
    
    
	int value;
	struct body *next;
	struct body *pre;
}; 

2. Operation function

#include<stdio.h>
#include<stdlib.h> 
typedef struct body
{
    
    
	int value;
	struct body *next;
	struct body *pre;
}; 
body *init()
{
    
    
	body *first=(body*)malloc(sizeof(body));
	first->next=NULL;
	first->pre=NULL;
	first->value=0;
	printf("创建成功\n");
	return first; 
}
void isemp(body *first)
{
    
    
	if(first->next==NULL||first==NULL)
	{
    
    
		printf("单链表为空\n");
	}
	else printf("单链表不为空\n"); 
}
void nextprintlinelist(body *first)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("单链表为空表\n");
	}
	else
	{
    
    
		body* per;
		per=first->next;
		while(per->next!=NULL)
		{
    
    
			printf("%d  ",per->value);
			per=per->next;
		}
		printf("%d\n",per->value);
	}
}
void preprintlinelist(body *first)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("单链表为空表\n");
	}
	else
	{
    
    
		body* per;
		per=first;
		while(per->next!=NULL)
		{
    
    
			per=per->next;
		}
		while(per->pre!=NULL)
		{
    
    
			printf("%d  ",per->value);
			per=per->pre;
		}
		printf("\n");
	}
}
int length(body *first)
{
    
    
	if(first->next==NULL)
	{
    
    
		return 0;
	}
	else
	{
    
    
		return first->value;
	}
}
int getvalue(body *first,int i)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("单链表为空表,取值无效\n");
		return 0;
	}
	else if(i<=0)
	{
    
    
		printf("位置信息不合规范\n");
		return 0;
	}
	else if(i>first->value)
	{
    
    
		printf("超过单链表大小\n");
		return 0;
	}
	else
	{
    
    
		int count=1;
		body *per;
		per=first;
		while(count!=i)
		{
    
    
			per=per->next;
			count++;
		}
		return per->next->value;	
	} 
}
int getlocation(body *first,int value1)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("单链表为空表\n");
		return 0;
	}
	else
	{
    
    
		int count=0;
		body *per;
		per=first->next;
		while(per->next!=NULL)
		{
    
    
			count++;
			if(per->value==value1)
			{
    
    
				return count;
			}
			per=per->next;
		}
		if(per->value==value1)
		{
    
    
			return count+1;
		}
		 else 
		 {
    
    
		 	printf("没有该值\n");
			 return 0;	
		 }
	}
 } 
void insert(body* first,int i,int value1)
{
    
    
	if(i<=0)
	{
    
    
		printf("插入失败\n");
	}
	else
	{
    
    
		body *per;
		per=first;
		int count;
		count=first->value;
		if(i>count+1)
		{
    
    
			printf("插入失败\n");
		}
		else if(i==count+1)
		{
    
    
			while(per->next!=NULL)
			{
    
    
				per=per->next;
			}
			body *l1;
			l1=(body*)malloc(sizeof(body));
			per->next=l1;
			l1->pre=per;
			l1->next=NULL;
			l1->value=value1;
			first->value=first->value+1;
			printf("插入成功\n");
		} 
		else
		{
    
    
			count=1;
			per=first;
			while(count!=i)
			{
    
    
				per=per->next;//per是第i个位置的元素 
				count++;
			} 
			body* temp;
			temp=(body*)malloc(sizeof(body));
			temp->next=per->next;
			per->next->pre=temp;
			temp->pre=per;
			per->next=temp;
			temp->value=value1;
			first->value=first->value+1;
			printf("插入成功\n");
		}
	}
}
void delet(body *first,int i)
{
    
    
	body* per;
	per=first;
	int count;
	count=first->value;
	if(i<0||per->next==NULL)
	{
    
    
		printf("删除失败\n");
	}
	else if(i==count)
	{
    
    
		per=first;
		while(per->next->next!=NULL)
		{
    
    
			per=per->next;
		}
		free(per->next);
		per->next=NULL;
		first->value=first->value-1;
		printf("删除成功\n");
	}
	else if(i>count)
	{
    
    
		printf("超过单链表大小\n");
	}
	else
	{
    
    
		per=first;
		count=1;
		while(count!=i)
		{
    
    
			per=per->next;
			count++;
		}
		body* temp;
		temp=per;
		per=per->next;
		per->next->pre=temp;
		temp->next=per->next;
		free(per);
		first->value=first->value-1;
		printf("删除成功\n");
	}
}
body* creatlinelist(int a[],int i)
{
    
    
	if(i<=0)
	{
    
    
		printf("创建失败\n");
		return NULL;
	}
	else
	{
    
    
		body *first=NULL;
		first=(body*)malloc(sizeof(body));
		body *s=NULL;
		first->value=i;
		first->pre=NULL;
		body *per;
		per=first;
		for(int k=0;k<i;k++)
		{
    
    
			s=(body*)malloc(sizeof(body));
			s->value=a[k];
			per->next=s;
			s->pre=per;
			per=per->next;
		}
		s->next=NULL;
		printf("创建成功\n");
		return first; 
	}
}
void destroy(body *first)
{
    
    
	body* per;
	first->value=0;
	per=first->next;
	for(int i=1;i<=first->value;i++)
	{
    
    
		body* temp;
		temp=per;
		per=per->next;
		free(temp);
	}
	first->next=NULL; 
	printf("销毁完成\n"); 
}
int main()
{
    
    
	int b[7];
	for(int i=0;i<7;i++)
	{
    
    
		scanf("%d",&b[i]);
	}
	body *l;
	l=creatlinelist(b,7);
	preprintlinelist(l);
	nextprintlinelist(l);
	insert(l,5,888);
	delet(l,1);
	preprintlinelist(l);
	nextprintlinelist(l);
	destroy(l);
	return 0;
 } 

4. Circular linked list

1. Data structure

typedef struct body
{
    
    
	int value;
	struct body *next;
}; 

2. Operation function

#include<stdio.h>
#include<stdlib.h> 
typedef struct body
{
    
    
	int value;
	struct body *next;
}; 
body *init()
{
    
    
	body *first=(body*)malloc(sizeof(body));
	first->next=NULL;
	first->value=0;
	printf("创建成功\n");
	return first; 
}
void isemp(body *first)
{
    
    
	if(first->next==NULL||first==NULL)
	{
    
    
		printf("循环链表为空\n");
	}
	else printf("循环链表不为空\n"); 
}
void printlinelist(body *first)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("循环链表为空表\n");
	}
	else
	{
    
    
		body* per;
		per=first->next;
		int n;
		n=first->value;
		for(int i=0;i<n;i++)
		{
    
    
			printf("%d ",per->value);
			per=per->next;
		}
		printf("\n");
	}
}
int length(body *first)
{
    
    
	if(first->next==NULL)
	{
    
    
		return 0;
	}
	else
	{
    
    
		return first->value;
	}
}
int getvalueonce(body *first,int i)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("循环链表为空表,取值无效\n");
		return 0;
	}
	else if(i<=0)
	{
    
    
		printf("位置信息不合规范\n");
		return 0;
	}
	else if(i>first->value)
	{
    
    
		printf("超过循环链表大小\n");
		return 0;
	}
	else
	{
    
    
		int count=1;
		body *per;
		per=first;
		while(count!=i)
		{
    
    
			per=per->next;
			count++;
		}
		return per->next->value;	
	} 
}
int getvalue(body *first,int i)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("循环链表为空表\n");
		return 0; 
	}
	else if(i<=0)
	{
    
    
		printf("无效位置\n");
		return 0;
	}
	else
	{
    
    
		int n;
		n=first->value;
		int num;
		num=i%n;
		body *per;
		per=first;
		for(int j=0;j<num;j++)
		{
    
    
			per=per->next;
		}
		printf("取值成功\n");
		return per->value;
	}
}
int getlocation(body *first,int value1)
{
    
    
	if(first->next==NULL)
	{
    
    
		printf("循环链表为空表\n");
		return 0;
	}
	else
	{
    
    
		int count=0;
		body *per;
		per=first->next;
		while(per->next!=NULL)
		{
    
    
			count++;
			if(per->value==value1)
			{
    
    
				return count;
			}
			per=per->next;
		}
		if(per->value==value1)
		{
    
    
			return count+1;
		}
		 else 
		 {
    
    
		 	printf("没有该值\n");
			 return 0;	
		 }
	}
 } 
void insert(body* first,int i,int value1)
{
    
    
	if(i<=0)
	{
    
    
		printf("插入失败\n");
	}
	else
	{
    
    
		body *per;
		per=first;
		int count;
		count=first->value;
		int num;
		num=i%count;
		if(num==1)
		{
    
    
			for(int k=0;k<count;k++)
			{
    
    
				per=per->next;
			}
			body *temp;
			temp=(body*)malloc(sizeof(body));
			temp->value=value1;
			temp->next=first->next;
			first->next=temp; 
			per->next=temp;
			printf("插入成功\n");
			first->value=first->value+1;
		}
		else if(num==0)
		{
    
    
			for(int k=1;k<count;k++)
			{
    
    
				per=per->next;
			}
			body *temp;
			temp=(body *)malloc(sizeof(body));
			temp->next=per->next;
			temp->value=value1;
			per->next=temp;
			printf("插入成功\n");
			first->value=first->value+1; 
		}
		else
		{
    
    
			for(int k=1;k<num;k++)
			{
    
    
				per=per->next;
			}
			body *temp;
			temp=(body *)malloc(sizeof(body));
			temp->next=per->next;
			temp->value=value1;
			per->next=temp;
			printf("插入成功\n");
			first->value=first->value+1;
		}
	}
}
void delet(body *first,int i)
{
    
    
	body* per;
	per=first;
	int count;
	count=first->value;
	int num;
	num=i%count;
	if(i<=0||per->next==NULL)
	{
    
    
		printf("删除失败\n");
	}
	else if(num==0)
	{
    
    
		per=first;
		for(int k=1;k<count;k++)
		{
    
    
			per=per->next;
		}
		body *s;
		s=per->next;
		per->next=s->next;
		free(s);
		first->value=first->value-1;
		printf("删除成功\n");
	}
	else
	{
    
    
		per=first;
		for(int k=1;k<num;k++)
		{
    
    
			per=per->next;
		}
		body *s;
		s=per->next;
		per->next=s->next;
		free(s);
		first->value=first->value-1;
		printf("删除成功\n");
	}
}
body* creatlinelist(int a[],int i)
{
    
    
	if(i<=0)
	{
    
    
		printf("创建失败\n");
		return NULL;
	}
	else
	{
    
    
		body *first=NULL;
		first=(body*)malloc(sizeof(body));
		body *s=NULL;
		first->value=i;
		body *per;
		per=first;
		for(int k=0;k<i;k++)
		{
    
    
			s=(body*)malloc(sizeof(body));
			s->value=a[k];
			per->next=s;
			per=per->next;
		}
		s->next=first->next;
		printf("创建成功\n");
		return first; 
	}
}
void destroy(body *first)
{
    
    
	body* per;
	first->value=0;
	per=first->next;
	for(int i=1;i<=first->value;i++)
	{
    
    
		body* temp;
		temp=per;
		per=per->next;
		free(temp);
	}
	first->next=NULL; 
	printf("销毁完成\n"); 
}
void delcha(body *first,int i)
{
    
    
	body* per;
	per=first;
	int count;
	count=first->value;
	int num;
	num=i%count;
	if(i<=0||per->next==NULL)
	{
    
    
		printf("删除失败\n");
	}
	else if(num==0)
	{
    
    
		per=first;
		for(int k=1;k<count;k++)
		{
    
    
			per=per->next;
		}
		body *s;
		s=per->next;
		per->next=s->next;
		free(s);
		first->next=per->next;
		first->value=first->value-1;
		printf("删除成功\n");
	}
	else
	{
    
    
		per=first;
		for(int k=1;k<num;k++)
		{
    
    
			per=per->next;
		}
		body *s;
		s=per->next;
		per->next=s->next;
		free(s);
		first->next=per->next;
		first->value=first->value-1;
		printf("删除成功\n");
	}
}
int main()
{
    
    
	body *l;
	int a[20];
	for(int i=0;i<20;i++)
	{
    
    
		a[i]=i+1;
	}
	l=creatlinelist(a,20);
	printlinelist(l);
	for(int i=0;i<19;i++)
	{
    
    
		delcha(l,3);
	}
	printlinelist(l);
	return 0;
}

3. Application of linked list idea

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define TSIZE 45
typedef struct film
{
    
    
	char title[TSIZE];
	int rating;
	struct film *next;
};
char *sgets(char *st,int n)
{
    
    
	char *ret_val;
	char *find;
	ret_val=fgets(st,n,stdin);
	if(ret_val)
	{
    
    
		find=strchr(st,'\n');
		if(find)
		{
    
    
			*find='\0';
		}
		else
		{
    
    
			while (getchar()!='\n')
				continue;
		}
	}
	return ret_val;	
}
int main()
{
    
    
	film* head=NULL;
	film* prev,*current;
	char input[TSIZE];
	puts("Enter first movie title:");
	while(sgets(input,TSIZE)!=NULL&&input[0]!='\0')
	{
    
    
		current=(film*)malloc(sizeof(film));
		if(head==NULL)
		{
    
    
			head=current;
		}
		else
		{
    
    
			prev->next=current;
		}
		current->next=NULL;
		strcpy(current->title,input);
		puts("Enter your rating<0-10>:");
		scanf("%d",&current->rating);
		while(getchar()!='\n')
		{
    
    
			continue;
		}
		puts("Enter next movie title (empty line to stop):");
		prev=current;
	}
	if(head==NULL)
	{
    
    
		printf("No data entered.");
	}
	else
	{
    
    
		printf("Here is the movie list:\n");
	}
	current=head;
	while(current!=NULL)
	{
    
    
		printf("Movie: %s Rating: %d\n",current->title,current->rating);
		current=current->next;
	}
	current=head;
	while(current!=NULL)
	{
    
    
		current=head;
		head=current->next;
		free(current);
	}
	printf("Bye!\n");
	return 0;
}

Summarize

Since the data structure of the linked list has no logical complexity, there are few explanations, please bear with me. Please
bear with me and correct me if the article is inappropriate or wrong.

Guess you like

Origin blog.csdn.net/weixin_52042488/article/details/126873864