【数据结构】单链表详解(超详细)

单链表是我们学习数据结构时必不可少的部分,但也由于指针的参与变得更加复杂,这篇文章学习完之后可以更好地理解与掌握链表结构

注意:

  • 数据结构中,不在乎菜单的创建,注重的是功能的实现;
  • 菜单的创建会影响我们的调试

目录

结构体的创建:

这里要注意typedef的灵活使用,可以更方便的使用与修改结构体,不必牵一发而动全身

c 复制代码
typedef int SLTDateType;
typedef struct SListNode
{
	SLTDateType data;
	struct SListNode* next;
}SListNode;

动态申请节点:

在我们前插或者尾插时,需要一个新的结点,故我们需要一个申请节点的函数帮助我们,同时我们需要返回这个地址,否则将会内存泄漏

c 复制代码
SListNode* BuySListNode(SLTDateType x)
{
	SListNode* newnode = (SListNode*)malloc(sizeof(SListNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

打印:

打印可以很好的帮助我们检查我们写的程序有无错误

c 复制代码
void SListPrint(SListNode* plist)
{
	SListNode* cur = plist;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

尾插:

单链表尾差与顺序表尾差完全不一样 ,要知道,单链表在创建头结点时:SListNode* ps = NULL;

我们发现,创建的头结点是一个指针,而我们尾插时如果是第一个元素,就会改变ps的值,而改变一个指针的值需要传入指针的地址,故:

c 复制代码
void SListPushBack(SListNode** pplist, SLTDateType x)
//传入二级指针,可以改变ps的值
{
	SListNode* newnode = BuySListNode(x);
	if (*pplist == NULL)
	{
		*pplist = newnode;
	}
	else
	{
		SListNode* cur= *pplist;
		while (cur->next != NULL)
		{
			cur = cur->next;
		}
		cur->next = newnode;
	}
}

头插:

与尾插同理,需要二级指针

c 复制代码
void SListPushFront(SListNode** pplist, SLTDateType x)
{
	SListNode* newnode = BuySListNode(x);
	newnode->next = *pplist;
	*pplist = newnode;
}

尾删:

c 复制代码
void SListPopBack(SListNode** pplist)
{
	assert(*pplist);
	SListNode* cur = *pplist;
	if (cur->next == NULL)
	{
		*pplist = NULL;
	}
	else
	{
		while (cur->next->next != NULL)
		{
			cur = cur->next;
		}
		free(cur->next);
		cur->next = NULL;
	}
}

头删:

c 复制代码
void SListPopFront(SListNode** pplist)
{
	assert(*pplist);
	SListNode* cur = (*pplist)->next;
	free(*pplist);
	*pplist = cur;
}

链表查找:

c 复制代码
SListNode* SListFind(SListNode* plist, SLTDateType x)
{
	assert(plist);
	SListNode* cur = plist;
	while (cur->next)
	{
		if (cur->data == x)
		{
			return cur;
		}
		cur = cur->next;
	}
	return NULL;
}

(插入,删除)与查找通常是配套使用

链表插入某节点:

单链表插入时只能向后插入,因为单链表只能找到后边的节点却无法找到前边的节点,故链表的形态多种多样,适用各种场景

c 复制代码
void SListInsertAfter(SListNode* pos, SLTDateType x)
{
	SListNode* newnode = BuySListNode(x);
	newnode->next = pos->next;
	pos->next = newnode;
}

链表删除某节点:

c 复制代码
void SListEraseAfter(SListNode* pos)
{
	assert(pos->next);
	SListNode* cur = pos;
	SListNode* tmp = pos->next;
	cur->next = cur->next->next;
	free(tmp);
}

欢迎讨论,有问题可以及时找我沟通,每天25h高强度冲浪

相关推荐
想放学的刺客5 分钟前
单片机嵌入式试题(第27期)设计可移植、可配置的外设驱动框架的关键要点
c语言·stm32·单片机·嵌入式硬件·物联网
mit6.82420 分钟前
dijk|tire+floyd+dp %
算法
独自破碎E35 分钟前
【总和拆分 + 双变量遍历】LCR_012_寻找数组的中心下标
数据结构·算法
WBluuue35 分钟前
Codeforces 1076 Div3(ABCDEFG)
c++·算法
BackCatK Chen39 分钟前
第 1 篇:软件视角扫盲|TMC2240 软件核心特性 + 学习路径(附工具清单)
c语言·stm32·单片机·学习·电机驱动·保姆级教程·tmc2240
u0109272711 小时前
模板编译期排序算法
开发语言·c++·算法
GIS瞧葩菜1 小时前
Cesium 轴拖拽 + 旋转圈拖拽 核心数学知识
人工智能·算法·机器学习
m0_686041611 小时前
C++中的适配器模式变体
开发语言·c++·算法
txzrxz1 小时前
结构体排序,双指针,单调栈
数据结构·算法·双指针算法·单调栈·结构体排序
AndrewHZ1 小时前
【AI黑话日日新】什么是AI智能体?
人工智能·算法·语言模型·大模型·llm·ai智能体