Data Structure---Single Linked List

content

1. Singly linked list

2. Implementation of a singly linked list

head File

Implementation of the function

(1) Print the linked list

(2) Dynamic application node

(3) Tail plug

(4) Head plug

(5) Tail deletion

(6) Header deletion

(7) Find

(8) Insert before pos

(9) delete pos

 (10) Insert after pos

(11) Delete after pos

(12) Remember to destroy when you are finished using it

3. Test of each function


Preface: The singly linked list is the basis of the double linked list and the circular linked list to be learned later. If we want to continue to understand the data structure and C++ in depth, we must lay the foundation stone! Come and learn with me next!

Here we will simply implement the addition and deletion of the singly linked list.

1. Singly linked list

Concept: Linked list is a non-consecutive and non-sequential storage structure in physical storage structure. The logical order of data elements is realized through the link order of pointers in the linked list.

 (The closest thing a linked list is to our lives is a train.)

2. Implementation of a singly linked list

Next, we will implement the addition, deletion and modification of the singly linked list.

head File

#pragma once

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

typedef int SLDataType;

//链表的创建
typedef struct SListNode
{
	SLDataType data;//val
	struct SListNode* next;//存储下一个结点的地址
}SListNode,SLN;

//打印链表
void SListPrint(SListNode* phead);

//尾插
void SListPushBack(SListNode** pphead, SLDataType x);

//头插
void SListPushFront(SListNode** pphead, SLDataType x);

//尾删
void SListPopBack(SListNode** pphead);

//头删
void SListPopFront(SListNode** pphead);

//查找
SListNode* SListFind(SListNode* phead, SLDataType x);

//在pos位置之前插入
void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x);

//删除pos位置
void SListErase(SListNode** pphead, SListNode* pos);

//在pos位置之后插入
void SlistInserAfter(SListNode* pos, SLDataType x);

//删除pos后的值
void SlistEraseAfter(SListNode* pos);

//用完销毁
void SListDestroy(SListNode** pphead);

Implementation of the function

(1) Print the linked list

void SListPrint(SListNode* phead)
{
	assert(phead);

	SListNode* cur = phead;

	if (cur == NULL)
	{
		printf("SList is NULL\n");
	}

	while (cur != NULL)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

(2) Dynamic application node

Apply a data x dynamically to the node.

SListNode* BuySList(SLDataType x)
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	if (newnode == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	else
	{
		newnode->data = x;
		newnode->next = NULL;
	}
	return newnode;
}

(3) Tail plug

void SListPushBack(SListNode** pphead, SLDataType x)
{
	assert(pphead);

	SListNode* newnode = BuySList(x);
	
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		//找尾
		SListNode* tail = *pphead;
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		//走完循环找到尾
		tail->next = newnode;
	}

}

(4) Head plug

void SListPushFront(SListNode** pphead, SLDataType x)
{
	assert(pphead);

	SListNode* newnode = BuySList(x);

	newnode->next = *pphead;
	*pphead = newnode;

}

(5) Tail deletion

void SListPopBack(SListNode** pphead)
{
	assert(pphead);

	//当链表只有一个结点时
	if (*pphead == NULL)
	{
		printf("SListNode is NULL\n");
		return;
	}
	//当链表只有一个结点时
	else if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	//当链表有多个结点时
	else
	{
		SListNode* tail = *pphead;
		while (tail->next->next != NULL)
		{
			tail = tail->next;
		}
		free(tail->next);
		tail->next = NULL;
	}
}

(6) Header deletion

void SListPopFront(SListNode** pphead)
{
	assert(pphead);

	if (*pphead == NULL)
	{
		printf("SList is NULL\n");
		return;
	}
	else
	{
		SListNode* next = (*pphead)->next;
		free(*pphead);
		*pphead = next;
	}
}

(7) Find

SListNode* SListFind(SListNode* phead, SLDataType x)
{
	assert(phead);

	SListNode* cur = phead;
	while (cur != NULL)
	{
		if (cur->data == x)
		{
			return cur;
		}
		//如果没找到就往下走
		cur = cur->next;
	}
	//循环完成后还没找到就说明链表中没有该值
	return NULL;
}

(8) Insert before pos

void SListInsert(SListNode** pphead, SListNode* pos, SLDataType x)
{
	assert(pphead);
	assert(pos);

	//pos是第一个位置
	if (pos == *pphead)
	{
		SListPushFront(pphead, x);
	}

	//pos不是第一个位置
	else
	{
		SListNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		SListNode* newnode = BuySList(x);
		prev->next = newnode;
		newnode->next = pos;
	}
}

(9) delete pos

void SListErase(SListNode** pphead, SListNode* pos)
{
	assert(pphead);
	assert(pos);

	//1、头结点为空
	if (*pphead == NULL)
	{
		printf("SList is NULL\n");
		return;
	}
	//2、删除第一个结点
	else if (pos == *pphead)
	{
		SListPopFront(pphead);
	}
	//3、其他结点
	else
	{
		SListNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

 (10) Insert after pos

Compared with inserting before pos, inserting after pos can be used without a header node, no matter where pos is located.

void SListInsertAfter(SListNode* pos, SLDataType x)
{
	assert(pos);

	SListNode* newnode = BuySList(x);
	SListNode* next = pos->next;

	pos->next = newnode;
	newnode->next = next;

    //下面这种方式也可以
	/*SListNode* newnode = BuySList(x);
	newnode->next = pos->next;
	pos->next = newnode;*/
	
}

(11) Delete after pos

void SListEraseAfter(SListNode* pos)
{
	assert(pos);

	SListNode* next = pos->next;
	if (next)
	{
		pos->next = next->next;
		free(next);
		next = NULL;
	}
	
}

(12) Remember to destroy when you are finished using it

void SListDestroy(SListNode** pphead)
{
	assert(pphead);

	SListNode* cur = *pphead;
	while (cur)
	{
		SListNode* next = cur->next;
		free(cur);
		cur = next;
	}

	*pphead = NULL;
}

3. Test of each function

#include "SList.h"

void test1()
{
	SListNode* slist = NULL;

	//测试尾插
	SListPushBack(&slist, 1);
	SListPushBack(&slist, 2);
	SListPushBack(&slist, 3);
	SListPushFront(&slist, 5);
	SListPushFront(&slist, 4);
	SListPrint(slist);

	//测试头插
	SListPushFront(&slist, 5);
	SListPushFront(&slist, 4);
	SListPrint(slist);

	//测试尾删
	SListPopBack(&slist);
	SListPopBack(&slist);
	SListPrint(slist);

	//测试头删
	SListPopFront(&slist);
	SListPopFront(&slist);
	SListPopFront(&slist);
	SListPrint(slist);

	//测试查找
	SListNode* ret1 = SListFind(slist, 5);
	printf("%d\n", ret1->data);
	/*SListNode* ret2 = SListFind(slist, 2);
	printf("%d\n", ret2->data);*/

	//pos前插测试
	SListNode* pos = SListFind(slist, 1);
	if (pos)
	{
		SListInsert(&slist,pos,3);
	}
	SListPrint(slist);
	pos = SListFind(slist, 1);
	if (pos)
	{
		SListInsert(&slist, pos, 10);
	}
	SListPrint(slist);

	//删除pos测试
	pos = SListFind(slist, 10);
	if (pos)
	{
		SListErase(&slist, pos);
	}
	SListPrint(slist);

	//测试在pos后插入
	pos = SListFind(slist, 3);
	if (pos)
	{
		SListInsertAfter(pos, 6);
	}
	SListPrint(slist);
	pos = SListFind(slist, 1);
	if (pos)
	{
		SListInsertAfter(pos, 8);
	}
	SListPrint(slist);

	//测试删除pos后的值
	pos = SListFind(slist, 1);
	if (pos)
	{
		SListEraseAfter(pos);
	}
	SListPrint(slist);

}

int main()
{
	
	test1();

	return 0;
}

operation result:

This is the end of the implementation of the singly linked list. If you want to go further, please pay attention to the follow-up----single linked list OJ, so that you will no longer be confused! 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324324515&siteId=291194637