单链表C语言实现

news2024/10/5 21:20:07

链表就是许多节点在逻辑上串起来的数据存储方式 是通过结构体中的指针将后续的节点串联起来

typedef int SLTDataType;//数据类型
typedef struct SListNode//节点
{
	SLTDataType data;//存储的数据
	struct SListNode* next;//指向下一个节点地址的指针
}SLTNode;//结构体类型的简化

上面的代码只是声明 并没有定义 也就是没有创建结构体变量 

SListNode* pc = NULL;//定义结构体

下面开始实现链表的各个接口 让链表可以存储和删除数据

链表的打印

void SListPrint(SListNode* phead)
{
	while (phead != NULL)
	{
		printf("%d->", phead->val);
		phead = phead->next;
	}
	printf("NULL");
}

链表的插入会向内存申请空间 去创造一个新的节点 所以后续的 头部插入 尾部插入 还是任意位置的插入 都会进行相同的操作 所以这里将开辟节点这个过程单独分装为一个函数 方便后面的操作

static SListNode* CreatNode(DataType x)
{
	SListNode* tmp = (SListNode*)malloc(sizeof(SListNode));
	if (tmp == NULL)
	{
		printf("failed to allocate memory.");
		exit(-1);
	}
	tmp->val = x;
	tmp->next = NULL;
	return tmp;
}

这里使用了static将函数的作用域限制在该函数所在的项目中 在其它项目中无法访问

链表的头部插入

void SListFront(SListNode** phead, DataType x)
{
	SListNode* tmp = CreatNode(x);
	tmp->next = *phead;
	tmp->val = x;
	*phead = tmp;
}

链表的尾部插入

链表的尾部插入相比于头部插入就显得不是那么好写

因为你要考虑 链表中是否有数据 也就是*phead是否为空  并且还要考虑当链表不为空时 尾插该怎样插入  我们可以使用if语句进行判断

void SListBackPush(SListNode** phead, DataType x)
{
	SListNode* newnode = CreatNode(x);
	if (*phead == NULL)
	{
		*phead = newnode;
	}
	else
	{
		SListNode* tail = *phead;//定义一个变量去向后寻找尾部
		while (tail->next != NULL)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

任意位置的插入(从1位置向后插 超出范围 将该节点插入到尾部)

当链表有数据时 尾部插入和头部插入是一样的流程 用一个临时变量tmp 向后寻找pos位置 再将该位置的下一个节点的地址给 要插入节点的指针 最后将要插入节点的地址给前一个节点的指针 这样就将该节点插进去了 

但是头部插入不太一样 因为头部之前没有节点了 就只能将头节点先给要插入的节点 再将要插入的节点作为头部 这样就完成了头部插入

void SListPosPush(SListNode** phead, DataType x , int pos)
{
	SListNode* newnode = CreatNode(x);
	if (pos == 1)
	{
		newnode->next = *phead;
		*phead = newnode;
	}
	else
	{
		SListNode* tmp = *phead;
		//如果所给的pos位置超出了链表的长度就将其插入到尾部
		while (tmp->next!=NULL && pos>2)
		{
			tmp = tmp->next;
			--pos;
		}
		newnode->next = tmp->next;
		tmp->next = newnode;
	}
}

运行结果如下 以上就是插入接口函数的实现

 删除的相关节点

头删

void SListPopFront(SListNode** phead)
{
	assert(*phead);
	SListNode* tmp = *phead;
	*phead = (*phead)->next;
	free(tmp);
	tmp = NULL;
}

尾删

尾删和头删不一样 因为当链表只有一个节点时 尾删就变成了头删 这样就和有多个数据时 尾部删除不一样 这就分情况 讨论

void SListPopBack(SListNode** phead)
{
	assert(*phead);
	if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		//找尾
		SListNode* tmp = *phead;//防止头节点丢失
		SListNode* str = *phead;
		while (tmp->next != NULL)
		{
			str = tmp;
			tmp = tmp->next;
		}
		free(tmp);
		tmp = NULL;
		str->next = NULL;
	}
}

上面是两个指针配合删除 下面是一个指针去完成

void SListPopBack(SListNode** phead)
{
	assert(*phead);
	if ((*phead)->next == NULL)
	{
		free(*phead);
		*phead = NULL;
	}
	else
	{
		//找尾
		SListNode* tmp = *phead;//防止头节点丢失
		SListNode* str = *phead;
		while (tmp->next->next!=NULL)
		{
			tmp = tmp->next;
		}
		free(tmp->next);
		tmp->next = NULL;
	}
}

链表pos位置删除

void SListPopPos(SListNode** phead, int pos)
{
	assert(*phead);//空链表就不用删除了
	if (pos == 1)
	{
		SListNode* tmp = *phead;
		*phead = (*phead)->next;
		free(tmp);
		tmp = NULL;
	}
	else
	{
		SListNode* tmp = *phead;
		SListNode* str = tmp;
		while (pos > 1 && tmp->next != NULL)
		{
			str = tmp;
			tmp = tmp->next;
			--pos;
		}
		//找到pos位置之后将 pos的下一个节点的地址给pos前面的节点的指针
		//再将pos所在的节点进行释放
		str->next = tmp->next;
		free(tmp);
		tmp = NULL;
	}
}

对链表的查找 修改 其实就是将链表遍历一遍 上面的寻找尾部 打印链表就是遍历链表 所以大家可以将其修改修改 

对单链表就介绍到这里 后续还有双向链表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/443820.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式(GOF)之我见(0)——UML

这里直接梳理画类图时的几个类关系。 类图的语法和功能 关系说明举例依赖(Dependency) 偶然的,陌生的。 对类B进行修改会影响到A。 例如:问路时,路人甲给路人乙带路,路人甲的指引必然会影响到路人乙,但是…

在ROS2中使用奥比中光(ORBBEC)的AstraPro深度相机

0.效果演示 1.下载SDK 到官网下载OpenNI2_SDK 记得是下载这个OpenNI2_SDK,而不是下载那个Orbbec_SDK. 2.拷贝至自定义目录 拷贝到你的ubuntu的一个文件夹中,并解压得到 ros2_astra_camera 文件夹 然后新建一个ros2_ws文件夹,再在ros2_ws文件夹中新建…

矩阵链相乘的乘法次数(动态规划)

Description 设 A1, A2, …, An 为矩阵序列,Ai 是阶为 Pi − 1 * Pi 的矩阵 i  1, 2, …, n.试确定矩阵的乘法顺序,使得计算 A1A2…An 过程中元素相乘的总次数最少.Input 多组数据第一行一个整数 n(1≤n≤300) ,表示一共有 n 个矩…

真题详解(计算机知识)-软件设计(五十四)

真题详解(归并)-软件设计(五十三)https://blog.csdn.net/ke1ying/article/details/130254861 若无条件转移汇编指令采用直接寻址,则该指令功能是将指令中的地址码送入_____? PC(程序计数器) 程序计数器&…

10种黑客类型,你知道几种?

黑客一般有 10 种类型 1、白帽黑客 白帽黑客是指通过实施渗透测试,识别网络安全漏洞,为政府及组织工作并获得授权或认证的黑客。他们也确保保护免受恶意网络犯罪。他们在政府提供的规章制度下工作,这就是为什么他们被称为道德黑客或网络安全…

Kyligence Zen 产品体验 --- 初识庐山真面目

简介 Kyligence Zen 是一款数据分析工具,其市场定位是一站式云端指标平台。它基于 Kyligence 核心 OLAP(On-Line Analytical Processing) 能力打造,提供集业务模型、指标管理、指标加工、数据服务于一体的一站式服务。 其基本的…

Linux: SPI 驱动

文章目录 1. 前言2. SPI 总线驱动2.1 SPI 总线拓扑2.2 SPI 总线工作模式2.3 SPI 总线驱动编写 3. SPI 从设驱动4. SPI 用户空间接口4.1 创建 SPI 总线用户空间字符设备节点4.2 操作 SPI 总线用户字符设备节点 1. 前言 限于作者能力水平,本文可能存在谬误&#xff0…

百趣代谢组学分享,三阴性乳腺癌铁死亡异质性的揭示

百趣代谢组学分享文章标题:Ferroptosis heterogeneity in triple-negative breast cancer reveals an innovative immunotherapy combination strategy 发表期刊:Cell Metabolism 影响因子:31.373 作者单位:复旦大学附属肿瘤医…

DFS与BFS|树与图的遍历:拓扑排序

深度优先搜索DFS DFS每次往最深处搜,搜到叶子节点就返回,然后继续搜,特点:走到头才返回,返回并不是返回最开始,而是每次返回上一层之后,再看这一层能不能往下搜 DFS有回溯和剪枝。返回上一层的过…

维基百科收录企业或品牌词条的规则解析

作为一家知名企业,开展国外市场营销的前提需要做好海外网络口碑营销,解决品牌信任的问题。小马识途营销顾问近来接到很多关于维基百科的咨询,其实做海外营销的企业倒是很有营销意识,主动寻求创建维基百科的很多,但并不…

138. 复制带随机指针的链表

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。 构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 n…

ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7

编辑:ll ASEMI代理ADCMP600BKSZ-REEL7原装ADI车规级ADCMP600BKSZ-REEL7 型号:ADCMP600BKSZ-REEL7 品牌:ADI/亚德诺 封装:SC-70-5 批号:2023 引脚数量:5 工作温度:-40C~125C 安装类型&am…

【从零开始学Skynet】实战篇《球球大作战》(四):分布式登录系统

处理玩家的登录,是服务端框架的主要功能之一。分布式系统涉及多个服务,让它们相互配合不产生冲突是一大难点。 1、登录流程 分布式服务端的登录功能要处理好如下两个问题: 问题一:完成角色对象的构建和销毁。如下图所示&#xf…

虹科Panorama SCADA平台连接OPC UA服务器操作详解

一、前言 虹科Panorama SCADA平台支持丰富的通信传输协议,其中包括OPC UA/DA、SNMP、Modbus、BACnet、IEC 61850、MQTT等多种常用的协议类型。OPC UA 采用简单的客户端/服务器的机制进行通信,服务器可在网络中提供大量信息,如有关 CPU、OPC …

pyecharts从入门到精通-地图专题Map-带时间轴与网格的复杂绘图

文章目录 参考安装与查看pyecharts地图实现-Geo导入依赖生成数据集生成2013-2018年的各个省份GDP数据生成2013-2018年的时间列表生成2013-2018年的总GDP设置visulmap的最大最小值范围 生成2013年的网格组合图提取2013年的数据测试绘制map地图绘制折线图line绘制折线图bar绘制折…

图片加水印的简单方法

图片加水印的简单方法~许多小伙伴都习惯在需要对外发布的图片上添加水印,添加水印后就不必担心图片被盗用或被用于其它不良目的,给我们造成不好的影响。然而,许多用户不知道如何为图片添加水印,也不知道应该选择哪种软件来进行操作…

C/C++|物联网开发入门+项目实战|空间读写|非字符空间|返回值内部实现|嵌入式C语言高级|C语言函数的使用(2)-学习笔记(12)

文章目录 空间的读写作用实现strlen实现strcpy 非字符空间void* 返回值返回连续空间类型示例: 函数内部实现示例: 参考: 麦子学院-嵌入式C语言高级-C语言函数的使用 空间的读写 void fun(char *p); const char *p 只读空间,只为…

多功能PDF工具合集:PDF Squeezer - PDF Toolbox Mac

PDF Squeezer - PDF Toolbox Mac是多功能PDF工具合集。专为操作 PDF 文件而设计,包含几乎所有你能想象到的操作,例如:压缩、合并、拆分、提取、插入、提取图像、转换图像、提取文本、排序、加密等。如果你正在为操作PDF文件发愁,快…

关于yolov8的一些理解

文章目录 1.前言2.创新点及工作3. 网络结构3.1 BackBone3.1.1 C2F3.1.2 结构微调3.1.2 SPPF 3.2 Neck3.3 Head 4.正样本匹配策略4.1 静态分配策略&动态分配策略4.2 TaskAlignedAssigner 5.损失函数5.1 概述5.2 Distribution Focal Loss 6.总结 1.前言 YOLOv8 是 ultralyti…

在Eclipse中安装配置JDK11

下载安装包 从请官方下载,地址为:https://www.oracle.com/java/technologies/javase-jdk11-downloads.html,选择相应的版本下载即可。注意,现在需要注册才能下载。 ** ** 安装JDK11 使用下载的安装包进行安装,双击可…