数据结构——单链表详解

博客IDLanFuRen
C系列专栏 C语言重点部分 C语言注意点 C++基础 Linux 数据结构 C++注意点

声明等级:黑色->蓝色->红色

欢迎新粉加入,会一直努力提供更优质的编程博客,希望大家三连支持一下啦

目录

1.链表的概念

2.单链表主体的实现

3.单链表内部方法实现

1)二级指针的问题

2)头插尾插的实现

3)其他代码展示


1.链表的概念

链表是⼀种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

链表就像火车一样,由一节一节车厢所构成。

从概念图可以看出,下一节"车厢",通过上一节"车厢"中的指针来链接。由上图,我们可以清晰地写出链表的主体部分,该链表结构体中有两个结构体成员------节点所存入的数据,结构体指针存放下一个节点的地址。(车厢=节点)。

2.单链表主体的实现

代码如下:

cpp 复制代码
typedef struct SListNode
{
	int data;//存放的数据
	struct SListNode* next;//结构体指针
}SLTNode;

SList:single单个的意思,list代表链表,node代表节点。

3.单链表内部方法实现

这里依旧提供几个比较重要的方法的实现过程:

//链表的打印

void SLTPrint(SLTNode* phead);

//链表的头插、尾插

void SLTPushBack(SLTNode** pphead, SLTDataType x);

void SLTPushFront(SLTNode** pphead, SLTDataType x);

链表的头删、尾删

void SLTPopBack(SLTNode** pphead);

void SLTPopFront(SLTNode** pphead);

//查找

SLTNode* SLTFind(SLTNode** pphead, SLTDataType x);

//在指定位置之前插入数据

void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);

//在指定位置之后插入数据

void SLTInsertAfter(SLTNode* pos, SLTDataType x);

//删除pos节点

void SLTErase(SLTNode** pphead, SLTNode* pos);

1)二级指针的问题

我们先来看看这里的二级指针的问题,为什么要使用SLTNode**pphead?那我们就得看实参跟形参的关系了,我们实参应该是一个链表,假设名字是plist,**我们要在函数中去修改这个plist,即修改plist存放的地址(指向),**而这个plist应该是SLTNode*plist=NULL(节点),**我们要去修改一级指针的值,就需要得到一级指针的地址,**这样就用到了二级指针。

2)头插尾插的实现

代码如下:

cpp 复制代码
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);
	/*if (*pphead==NULL)
	{
		*pphead = newnode;
		return;
	}*/
	newnode->next = *pphead;
	*pphead = newnode;//重要
}
cpp 复制代码
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)//传二级指针是因为这样才能修改plist链表,我们想获得plist的内部成员(节点内容),就是值,得传址,所以说传二级指针
{
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);
	//空链表
	if (*pphead == NULL)
	{
		*pphead = newnode;
		return;
	}
	//链表不为空
	SLTNode* ptail = *pphead;//ptail是一级指针
	while (ptail->next)
	{
		ptail = ptail->next;//ptail指针存放的是节点地址,节点包括next,这一步仅仅传一级指针就行。
	}
	ptail->next = newnode;

	/*while ((*pphead)->next)
	{
		*pphead = (*pphead)->next;
	}
	(*pphead)->next = newnode;*/
}

3)其他代码展示

cpp 复制代码
//尾删
void SLTPopBack(SLTNode** pphead)
{
	assert(pphead);
	assert(*pphead);
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		(*pphead)=NULL;
		return;
	}
	SLTNode* prev = *pphead;
	SLTNode* ptail = *pphead;
	while (ptail->next)
	{
		prev = ptail;//上一级
		ptail = ptail->next;//尾
	}
	prev->next = NULL;
	free(ptail);
	ptail = NULL;
}

void SLTPopFront(SLTNode** pphead) 
{
	assert(pphead);
	assert(*pphead);
	SLTNode* del = *pphead;
	*pphead= (*pphead)->next ;
	free(del);
	del = NULL;
	/*SLTNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;*/
}

//查找
//为指定位置增删有帮助
SLTNode* SLTFind(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	//assert(*pphead);
	SLTNode* val = *pphead;
	while (val != NULL)
	{
		if (val->data == x)
		{
			return val;
		}
		val = val->next;
	}
	return NULL;
}

在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	assert(pphead);
	assert(pos);
	assert(*pphead);//空链表哪里来的指定位置插入
	SLTNode* newnode = SLTBuyNode(x);
	if (pos == *pphead)
	{
		SLTPushFront(pphead, x);
		return;
	}//头节点
	//不是头节点
	SLTNode* pos_before = *pphead;
	while (pos_before->next != pos)
	{
		pos_before = pos_before->next;
	}
	/*pos_before->next = newnode->data;
	newnode->next = pos->data;*/
	pos_before->next = newnode;
	newnode->next = pos;
}

//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* newnode = SLTBuyNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos) 
{
	assert(pphead);
	assert(*pphead);
	assert(pos);
	//pos刚好是头结点,没有前驱节点,执行头删
	if (*pphead == pos) {
		//头删
		SLTPopFront(pphead);
		return;
	}
	SLTNode* pos_before = *pphead;
	while (pos_before->next != pos)
	{
		pos_before = pos_before->next;
	}//找到前驱节点
	SLTNode* pos_after = pos->next;//后驱节点
	pos_before->next = pos_after;
	//pos->next = NULL;
	free(pos);
	pos = NULL;
}
相关推荐
网易独家音乐人Mike Zhou3 小时前
【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)
c语言·python·单片机·物联网·算法·嵌入式·iot
搬砖的小码农_Sky5 小时前
C语言:数组
c语言·数据结构
先鱼鲨生7 小时前
数据结构——栈、队列
数据结构
一念之坤7 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python
IT 青年7 小时前
数据结构 (1)基本概念和术语
数据结构·算法
熬夜学编程的小王8 小时前
【初阶数据结构篇】双向链表的实现(赋源码)
数据结构·c++·链表·双向链表
liujjjiyun8 小时前
小R的随机播放顺序
数据结构·c++·算法
ahadee9 小时前
蓝桥杯每日真题 - 第19天
c语言·vscode·算法·蓝桥杯
Theliars10 小时前
C语言之字符串
c语言·开发语言
Reese_Cool10 小时前
【数据结构与算法】排序
java·c语言·开发语言·数据结构·c++·算法·排序算法