数据结构——单链表详解

博客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;
}
相关推荐
墨染新瑞25 分钟前
C语言——八股文(笔试面试题)
c语言·开发语言
海绵波波10729 分钟前
240. 搜索二维矩阵 II
数据结构·算法·矩阵
Qhumaing1 小时前
小白C/C++语言常见问题(持续更新)
c语言·c++·算法
嘻嘻啰啰1 小时前
代码随想录第十五天
c语言·数据结构·算法
自信人间三百年1 小时前
数据结构和算法-动态规划(3)-经典问题
java·数据结构·算法·leetcode·动态规划
混迹网络的权某2 小时前
每天一道C语言精选编程题之计算天数
c语言·开发语言·考研·算法·改行学it
2301_807083152 小时前
java-数据结构
java·开发语言·数据结构
Beginner_bml2 小时前
基于C语言实现的TCP客户端
c语言·开发语言·网络协议
重生之我是数学王子2 小时前
网络编程 TCP编程 Linux环境 C语言实现
linux·服务器·c语言·网络·tcp/ip
Renas_TJOvO2 小时前
排序算法汇总
java·数据结构·算法