Detailed explanation of singly linked list (with diagram and complete source code at the end)

Let's start with a diagram of the addition, deletion, checking and modification of a singly linked list.

First, let me introduce you to the linked list.

A linked list means that each structure contains a data and a structure pointer. This pointer acts like a chain to lock the next structure, but the space of each structure is relatively independent.

Illustration:

1 First implement tail insertion

If we want to insert the end, we need to find the end node and then use the next pointer to connect it.

Illustration:

The following is the code implementation

Here I considered a special case, that is, if the linked list is empty, we will directly connect the head node.

A second-order pointer must be used here to determine whether the first node is empty.

(If you use a first-order pointer, then the space will be destroyed after leaving the scope of this function, which is equivalent to your work being in vain)

Remember to release the space every time you use it, otherwise there will be a memory leak.

SL* BuyNewnode(DataSL x)
{
	SL* Newnode = (SL*)malloc(sizeof(SL));
	if (Newnode==NULL)
	{
		perror("malloc");
		assert(Newnode);
	}
	Newnode->data = x;
	Newnode->next = NULL;
	return Newnode;
}


void DistorySL(SL** pphead)
{
    SL* tail = *pphead;
	if (tail)
		return;
	else
	{
		while (tail->next)
		{
			SL* cur = tail->next;
			tail->next = NULL;
			tail->data = 0;
			free(tail);
			tail = cur;
		}
		tail->next = NULL;
		tail->data = 0;
		free(tail);
	}
}


void BackPushSL(SL** pphead, DataSL x)//尾插
{
	SL* tail = *pphead;
	SL* Newnode = BuyNewnode(x);
	if (tail == NULL)
	{
		*pphead = Newnode;
	}
	else
	{
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = Newnode;
	}
}

2 Then implement tail deletion

void BackPopSL(SL** pphead)//尾删
{
	assert(pphead);
	assert(*pphead);//空链表不删
	SL* tail = *pphead;
	if (tail->next==NULL)
	{
		tail->data = 0;
		free(tail);
	}
	else
	{
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

3 Then implement the head plug

void FrontPushSL(SL** pphead, DataSL x)
{
	assert(pphead);
	SL* tail = *pphead;
	SL* Newnode= BuyNewnode(x);
	if (tail == NULL)
	{
		tail = BuyNewnode(x);
	}
	else
	{
		Newnode->next = tail;
	}
	*pphead = Newnode;
}

4 Then implement header deletion

void FrontPopSL(SL** pphead)
{
	assert(pphead);
	SL* tail = (*pphead)->next;
	free(*pphead);
	(*pphead)->next = NULL;
	*pphead = tail;
}

5 Then implement intermediate insertion (coordinated search)

There are two cases of middle insertion: front insertion and rear insertion.

SL* FindSL(SL** pphead, DataSL x)
{
	SL* tail = *pphead;
	while (tail)
	{
		if (tail->data == x)
		{
			break;
		}
		else
		{
			tail = tail->next;
		}
	}
	return tail;
}


void FrontInsertSL(SL** pphead,SL* pos,DataSL x)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	SL* Newnode = BuyNewnode(x);
	SL* cur = tail;
	if (*pphead == NULL)
	{
		FrontPushSL(&tail,x);
	}
	while (tail!= pos)
	{
		cur = tail;
		tail = tail->next;
	}
	cur->next = BuyNewnode(x);
	cur->next->next = pos;
}

The situation of rear insertion is similar

SL* FindSL(SL** pphead, DataSL x)
{
	SL* tail = *pphead;
	while (tail)
	{
		if (tail->data == x)
		{
			break;
		}
		else
		{
			tail = tail->next;
		}
	}
	return tail;
}



void AfterInsertSL(SL** pphead, SL* pos, DataSL x)
{
	assert(pphead);
	assert(pos);
	SL* Newnode = BuyNewnode(x);
	SL* tail = *pphead;
	while (tail != pos)
	{
		tail = tail->next;
	}
	SL* cur = tail->next;
	tail->next = Newnode;
	Newnode->next = cur;
}

6 Then implement checking and deleting nodes (the principle is similar to the above, you can draw the picture by yourself)

void EraseSL(SL** pphead, SL* pos)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	if (tail==pos)
	{
		BackPopSL(tail);
	}
	else
	{
		while (tail->next != pos)
		{
			tail = tail->next;
		}
	SL* cur = tail->next;
	tail->next = tail->next->next;
	cur->data = 0;
	cur->next = NULL;
	free(cur->next);
	}
}

7 Finally, change the content of a node

void ReviseSL(SL** pphead, SL* pos, DataSL x)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	if (tail== pos)
	{
		tail->data = x;
	}
	else
	{
		while (tail->next != pos)
		{
			tail = tail->next;
		}
		tail->next->data = x;
	}
}

Attached below are all the source codes

SingleSeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataSL;
typedef struct SingleSqList SL;
typedef struct SingleSqList 
{
	DataSL data;
	SL* next;
}SL;

//开辟节点
SL* BuyNewnode(DataSL x);
//打印单链表的值
void SLPrint(SL* pphead);
//销毁链表
void DistorySL(SL** pphead);

singleSeqList.h

//对链表的增删查改
//头插尾插,头删尾删
void BackPushSL(SL** pphead,DataSL x);
void BackPopSL(SL** pphead);

void FrontPopSL(SL** pphead);
void FrontPushSL(SL** pphead, DataSL x);

//前插
void FrontInsertSL(SL** pphead,SL* pos,DataSL x);


//后插
void AfterInsertSL(SL** pphead, SL* pos, DataSL x);



//查找节点
SL* FindSL(SL** pphead, DataSL x);

//删除某个节点
void EraseSL(SL** pphead, SL* pos);

//修改某个节点的内容
void ReviseSL(SL** pphead, SL* pos, DataSL x);


SingleSeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SingleSqList.h"


void SLPrint(SL** pphead)
{
	SL* tail = *pphead;
	if (tail == NULL)
	{
		return;
	}
	while (tail->next)
	{
		printf("%d->", tail->data);
		tail = tail->next;
	}
	printf("%d", tail->data);
}

void DistorySL(SL** pphead)
{
    SL* tail = *pphead;
	if (tail)
		return;
	else
	{
		while (tail->next)
		{
			SL* cur = tail->next;
			tail->next = NULL;
			tail->data = 0;
			free(tail);
			tail = cur;
		}
		tail->next = NULL;
		tail->data = 0;
		free(tail);
	}
}




SL* BuyNewnode(DataSL x)
{
	SL* Newnode = (SL*)malloc(sizeof(SL));
	if (Newnode==NULL)
	{
		perror("malloc");
		assert(Newnode);
	}
	Newnode->data = x;
	Newnode->next = NULL;
	return Newnode;
}


void BackPushSL(SL** pphead, DataSL x)//尾插
{
	assert(pphead);
	SL* tail = *pphead;
	SL* Newnode = BuyNewnode(x);
	if (tail == NULL)
	{
		*pphead = Newnode;
	}
	else
	{
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = Newnode;
	}
}


void BackPopSL(SL** pphead)//尾删
{
	assert(pphead);
	assert(*pphead);//空链表不删
	SL* tail = *pphead;
	if (tail->next==NULL)
	{
		tail->data = 0;
		free(tail);
	}
	else
	{
		while (tail->next->next)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

void FrontPushSL(SL** pphead, DataSL x)
{
	assert(pphead);
	SL* tail = *pphead;
	SL* Newnode= BuyNewnode(x);
	if (tail == NULL)
	{
		tail = BuyNewnode(x);
	}
	else
	{
		Newnode->next = tail;
	}
	*pphead = Newnode;
}


void FrontPopSL(SL** pphead)
{
	assert(pphead);
	SL* tail = (*pphead)->next;
	free(*pphead);
	(*pphead)->next = NULL;
	*pphead = tail;
}


SL* FindSL(SL** pphead, DataSL x)
{
	SL* tail = *pphead;
	while (tail)
	{
		if (tail->data == x)
		{
			break;
		}
		else
		{
			tail = tail->next;
		}
	}
	return tail;
}



void FrontInsertSL(SL** pphead,SL* pos,DataSL x)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	SL* Newnode = BuyNewnode(x);
	SL* cur = tail;
	if (*pphead == NULL)
	{
		FrontPushSL(&tail,x);
	}
	while (tail!= pos)
	{
		cur = tail;
		tail = tail->next;
	}
	cur->next = BuyNewnode(x);
	cur->next->next = pos;
}

void AfterInsertSL(SL** pphead, SL* pos, DataSL x)
{
	assert(pphead);
	assert(pos);
	SL* Newnode = BuyNewnode(x);
	SL* tail = *pphead;
	while (tail != pos)
	{
		tail = tail->next;
	}
	SL* cur = tail->next;
	tail->next = Newnode;
	Newnode->next = cur;
}


void EraseSL(SL** pphead, SL* pos)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	if (tail==pos)
	{
		BackPopSL(tail);
	}
	else
	{
		while (tail->next != pos)
		{
			tail = tail->next;
		}
	SL* cur = tail->next;
	tail->next = tail->next->next;
	cur->data = 0;
	cur->next = NULL;
	free(cur->next);
	}
}


void ReviseSL(SL** pphead, SL* pos, DataSL x)
{
	assert(pphead);
	assert(pos);
	SL* tail = *pphead;
	if (tail== pos)
	{
		tail->data = x;
	}
	else
	{
		while (tail->next != pos)
		{
			tail = tail->next;
		}
		tail->next->data = x;
	}
}


I have basically implemented every function of the linked list and will not show them one by one here. (No problems have been encountered in testing so far)

Guess you like

Origin blog.csdn.net/2301_79811170/article/details/135038840