单链表的基本操作

Posted 王不患吖吖吖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单链表的基本操作相关的知识,希望对你有一定的参考价值。

文章目录

单链表的基本介绍

单链表是顺序表的一种,顺序表指的是可以线性排列,具有同种元素的有限序列。比如数组是顺序表的一种,它的空间上是连续的,逻辑上也是连续的。
而链表是由指针进行连接的,空间上是不连续的,逻辑上是连续的。

链表与数组的区别

对于链表它是不支持随机访问的,因为它必须知道它的地址,要寻找上一个节点,而数组可以随机访问
在插入元素上,数组上可能要搬运元素,但是链表却可以任意插入,时间复杂度较高。
如果插入了许多元素,链表不需要扩容,而数组需要
对于元素频繁访问,数组会更好一点,对于任意位置插入和删除,链表会更好
顺序表的缓存利用率更高

链表的基本操作

前置

typedef  int SLDataType ;
typedef struct SListNode

	SLDataType data;
	struct SListNode* next;
SL;

链表的创建

SL* BuySListNode(SLDataType x)

	SL* NewNode = (SL*)malloc(sizeof(SL));
	if (NewNode == NULL)
	
		exit(-1);
	
	NewNode->data = x;
	NewNode->next = NULL;
	return NewNode;

malloc一个节点,把内容传进去

链表的尾插

先找到尾,把新节点连接上去,

void SListPushBack(SL** pphead,SLDataType x)

	SL* NewNode = BuySListNode(x);
	if (*pphead == NULL)
	
		*pphead = NewNode;
	
	//当头节点为空的时候
	else
	
		SL* tail = *pphead;
		while (tail->next != NULL)
		
			tail = tail->next;
		
		tail->next = NewNode;//tail->next为空
	
	//找到尾节点尾节点的后面连接上新节点

链表的头插

我们是改变了头指针,所以传入指针的地址,所以是二重指针

void SListPushFront(SL** pphead, SLDataType x)

	SL* NewNode = BuySListNode(x);
	NewNode->next = *pphead;
	*pphead = NewNode;
	//让新节点连接上起始节点,再让新节点作为起始节点

链表的尾删

注意先判断是不是只有一个节点,如果是那么直接free,而且找到tail的next,再free,然后再置为空

void SListPopBack(SL** pphead)

	assert(*pphead);
	if ((*pphead)->next == NULL)
	
		free(*pphead);
		*pphead = NULL;
	
	else
	
		SL* tail = *pphead;
		/*while (tail->next != NULL)
		
			tail = tail->next;
		
		free(tail);
		tail = NULL;*/
		//如果直接freetail,那么链表的尾将会是一个野指针我们free tail的next
		while (tail->next->next)
		
			tail = tail->next;
		
		free(tail->next);
		tail->next = NULL;
	

链表的头删

先把第二个节点保存,以防找不到节点作为新头

void SListPopFront(SL** pphead)

	assert(*pphead);
	SL* cur = (*pphead)->next;;
	free(*pphead);
	*pphead = cur;
	//先把第二个节点保存

链表的查找

遍历链表没什么好说的

SL *SListFind(SL* phead, SLDataType x)

	assert(phead);
	SL* cur = phead;
	while (cur)
	
		if (cur->data == x)
		
			return cur;
		
		else

		cur = cur->next;
	
	return NULL;


链表的指定节点后插

后插的时候记住保存下一个节点

void SListInsertAfter(SL* pos, SLDataType x)

	SL* NewNode = BuySListNode(x);
	SL* cur = pos->next;
	
	
		pos->next = NewNode;
		NewNode->next = cur;
	
	

链表的指定位置前插

先看看指定位置是不是头节点,如果是也就是头插,如果不是,我们要找到指定位置的前一个节点进行保存。

void SListInsert(SL** pphead, SL* pos, SLDataType x)

	SL* NewNode = BuySListNode(x);
	if (pos == *pphead)
	
		NewNode->next = *pphead;
		*pphead = NewNode;
	
	else
	
		//我们要找到pos的前一个位置才行
		SL* posPrev = *pphead;
		
		while (posPrev->next == pos)
		

			posPrev = posPrev->next;
		
		posPrev->next = NewNode;
		NewNode->next = pos;
	
	

链表的删除

同样要找到指定节点的前一个,再进行删除

void SListErase(SL** pphead, SL* pos)

	assert(pos);
	if (*pphead == pos)
	
		*pphead = (*pphead)->next;
		free(pos);
	
	else
	
		SL* posPrev = *pphead;

		while (posPrev->next != pos)
		

			posPrev = posPrev->next;
		
		posPrev->next = pos->next;
		free(pos);
		

	

链表的销毁

先把下一个保存,以免找不到,然后遍历销毁

void SListDestory(SL** pphead)

	SL* p=*pphead;
	while (p)
	

		*pphead = (*pphead)->next;
		free(p);
		p == NULL;
		p = *pphead;

	

**

点个赞再走吧

**

以上是关于单链表的基本操作的主要内容,如果未能解决你的问题,请参考以下文章

单链表的链式存储总结

链表1-单链表

数据结构关于单链表的一些操作的源代码

循环链表的建立及各种操作

Day2:单链表的基本操作

单链表的基本操作