数据结构: 单向链表

news2024/11/15 23:29:33

目录

一、链表的概念及结构

二、单链表的实现

2.1 头文件

2.2 各个功能的实现

2.2.1 内存申请

 2.2.2 头插,尾插,头删,尾删

头插

 尾插

 头删

尾删

 2.2.3 查找数据

 2.2.4 指定位置前中后的数据增删

指定位置之前插入数据

指定位置之后插入数据

删除指定位置之后数据

删除指定位置数据

 2.2.5 打印链表

2.2.6 销毁链表


一、链表的概念及结构

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

 

     链表的结构跟火车车厢相似,淡季时车次的车厢会相应减少,旺季时车次的车厢会额外增加几节。只需要将火车里的某节车厢去掉或者加上,不会影响其他车厢,每节车厢都是独立存在的,车厢是独立存在的,且每节车厢都有车门,想象⼀下这样的场景,假设每节车厢的车门都是锁上的状 态,需要不同的钥匙才能解锁,每次只能携带⼀把钥匙的情况下如何从车头走到车尾? 最简单的做法:每节车厢里都放⼀把下⼀节车厢的钥匙。

链表里的“车厢”

    与顺序表不同的是,链表里的每节"车厢"都是独立申请下来的空间,我们称之为“节点”, 节点的组成主要有两个部分:当前节点要保存的数据和保存下⼀个节点的地址(指针变量)。 图中指针变量plist保存的是第⼀个节点的地址,我们称plist此时“指向”第⼀个节点,如果我们希望plist“指向”第⼆个节点时,只需要修改plist保存的内容为0x0012FFA0。

链表中每个节点都是独立申请的(即需要插⼊数据时才去申请⼀块节点的空间),我们需要通过指针变量来保存下⼀个节点位置才能从当前节点找到下⼀个节点。

结合结构体知识,我们可以给出每个节点对应的结构体代码: 假设当前保存的节点为整型:

struct SListNode
{
 int data; //节点数据 
 struct SListNode* next; //指针变量⽤保存下⼀个节点的地址 
};

当我们想要保存⼀个整型数据时,实际是向操作系统申请了⼀块内存,这个内存不仅要保存整型数 据,也需要保存下⼀个节点的地址(当下⼀个节点为空时保存的地址为空)。

当我们想要从第⼀个节点走到最后⼀个节点时,只需要在前⼀个节点拿上下⼀个节点的地址(下⼀个 节点的钥匙)就可以了。

二、单链表的实现

2.1 头文件

    先要创建一个头文件,写入我们需要的函数名以及结构体

typedef int SLTDataType;//方便类型转换
typedef struct SListNode
{
 SLTDataType data; //节点数据 
 struct SListNode* next; //指针保存下⼀个节点的地址 
}SLTNode;

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* phead, SLTDataType x);
//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//删除指定位置节点
void SLTErase(SLTNode** pphead, SLTNode* pos);
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
//删除指定位置之后的节点
void SLTEraseAfter(SLTNode* pos);
//销毁链表
void SListDesTroy(SLTNode** pphead);

2.2 各个功能的实现

2.2.1 内存申请

    单链表是每添加一份数据就申请一次内存空间,虽然这样降低了一点运行效率但是有效的避免了内存空间的浪费。

SLTNode* capacity(SLTDataType x)
{
	SLTNode* new = (SLTNode*)malloc(sizeof(SLTNode));
	if (new == NULL)
	{
		perror("malloc fail");
		exit(1);
	}
	new->data = x;
	new->next = NULL; 
	return new;
}

 2.2.2 头插,尾插,头删,尾删

头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{
	SLTNode* new = capacity(x);
	new->next = *pphead;
	*pphead = new;
}
 尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	SLTNode* new = capacity(x);
	if (*pphead == NULL)
	{
		*pphead = new;
	}
	else
	{
		SLTNode* newnode = *pphead;
		while (newnode->next)
		{
			newnode = newnode->next;
		}
		newnode-> next= new;
	}
}
 头删

    注意free释放指针完,指针一定要有指向(指向空也是可以的),避免造成野指针。

void SLTPopFront(SLTNode** pphead)
{
	assert(*pphead && pphead);
	SLTNode* new = (*pphead)->next;
	free(*pphead);
	*pphead = new;
}
尾删
void SLTPopBack(SLTNode** pphead)
{
	assert(*pphead && pphead);
	SLTNode* new = *pphead;
	SLTNode* newnode = *pphead;
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLTNode* new = *pphead;
		SLTNode* newnode = *pphead;
		while (new->next)
		{
			newnode = new;
			new = new->next;
		}
		free(new);
		new = NULL;
		newnode->next = NULL;
	}
}

 2.2.3 查找数据

SLTNode* SLTFind(SLTNode* phead, SLTDataType x)
{
	while (phead)
	{
		if (phead->data == x)
		{
			return phead;
		}
		phead = phead->next;
	}
	printf("没找到");
	return NULL;
}

 2.2.4 指定位置前中后的数据增删

指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
	if (*pphead == pos)
	{
		SLTPushFront(pphead, x);
	}
	else
	{
		SLTNode* new = capacity(x);
		SLTNode* newnode = *pphead;
		while (newnode->next != pos)
		{
			newnode = newnode->next;
		}
		new->next = pos;
		newnode->next = new;
	}
}
指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x)
{
	assert(pos);
	SLTNode* new = capacity(x);
	SLTNode* newnode = pos->next;
	pos->next = new;
	new->next = newnode;
}
删除指定位置之后数据
void SLTEraseAfter(SLTNode* pos)
{
	assert(pos&&pos->next);
	SLTNode* new = pos->next;
	pos->next = new->next;
	free(new);
	new = NULL;
}
删除指定位置数据
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(*pphead && *pphead);
	assert(pos);
	SLTNode* new = pos->next;
	while ((*pphead)->next != pos)
	{
		*pphead = (*pphead)->next;
	}
	(*pphead)->next = new;
	free(pos);
	pos = NULL;
}

 2.2.5 打印链表

    给定链表结构中,实现节点从头到尾的打印。

void SLTPrint(SLTNode* phead)
{
	SLTNode* pcur = phead;
	while (pcur)
	{
		printf("%d->", pcur->data);
		pcur = pcur->next;
	}
	printf("\n");
}

2.2.6 销毁链表

void SListDesTroy(SLTNode** pphead)
{
	assert(*pphead && pphead);
	SLTNode* new=*pphead;
	while (new)
	{
		SLTNode* newnode =new->next;
		free(new);
		new = newnode;
	}
	*pphead= NULL;
}

    各个功能实现后,不要忘了测试,看看写的代码是否有误。


    本篇内容就到这里了,希望对各位有帮助,如果有错误欢迎指出。

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

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

相关文章

完整版 [vue 配置electron]

vue 配置electron,使用make 进行打包 1. 安装依赖 yarn install 2. 在根目录新建文件夹 electron 3. package.json 文件里添加 "name": "my-electron-app","version": "1.0.0","description": "Hello W…

c++三大特性 封装、继承、多态 (一)

c中的继承 一. 封装封装的定义 二.继承的概念及定义2.1继承的概念2.2继承的定义2.2.1 定义格式2.2.2 继承关系和访问限定符2.2.3 继承基类成员访问方式的变化 三.基类和派生类对象赋值转换四.继承中的类作用域 一. 封装 封装的定义 数据和方法放到一起,把像访问定义…

【Canvas与艺术】八个等腰三角形拼成的八角楼

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>八个等腰三角形拼成的八角楼</title><style type"text…

【C语言】编译和链接(细节的king)

文章目录 前言1. 翻译环境和运行环境1.1 翻译环境1.1.1 预处理&#xff08;预编译&#xff09;1.1.2 编译词法分析语法分析语义分析及优化 1.1.3 汇编1.1.4 链接 1.2 运行环境 前言 相信大家在学完C语言的全部基础知识&#xff0c;肯定会经常动手敲代码。以VS为例&#xff0c;…

【C++】—— 类与对象(三)

【C】—— 类与对象&#xff08;三&#xff09; 4、拷贝构造函数4.1、初识拷贝构造4.1.1、为什么要传引用4.1.2、引用尽量加上 const 4.2、深入拷贝构造4.2.1、为什么要自己实现拷贝构造4.2.2、传值返回先调用拷贝构造的原因4.2.3、躺赢的 MyQueue4.2.4、传值返回与引用返回 4.…

云HIS,云HIS源码

医学领域的信息系统平台种类繁多。在很大程度上&#xff0c;对于一些在医疗机构的区域一体化信息平台&#xff0c;在微观层面上&#xff0c;传统的医疗信息系统已经建立了许多医院(HIS)或数字医院系统&#xff0c;包括子系统提供了一个单一的功能&#xff0c;如注册和形象&…

【H3C(HCL)网络模拟器网络桥接】进入网络设备Web页面

H3C模拟器网络桥接 1.模拟器选择Host&#xff0c;添加 2.选中Host主机的网卡&#xff0c;这里我选的是华三的Virtual Box的网卡 选中后连线至防火墙对应接口&#xff0c;建议连接到G1/0/1&#xff0c;这个接口是默认配置的接口&#xff0c;拥有默认地址 3.修改防火墙配置 [F…

Windows 中 PIN 和密码的区别是什么?各有各的优点

PIN PIN 即个人识别号码&#xff08;Personal Identification Number&#xff09;&#xff0c;在 Windows 系统中通常由 4 到 6 位数字组成。它是 Windows Hello 的一部分&#xff0c;设计用于提供快速、安全的身份验证。 密码 密码是一种更为传统的身份验证方法&#xff0c;…

提升生产效率:APS高级计划排程系统在车间工序级排程的革命性应用

在制造业的数字化转型浪潮中&#xff0c;APS高级计划排程系统以凭借自身卓越的排程运算能力和应用灵活性&#xff0c;已经成为中大型制造业提升生产效率的关键工具。APS系统的介入&#xff0c;打通了传统ERP和MES等各类业务系统运营平台&#xff0c;并且通过产能均衡规划&#…

聚观早报 | 搜狐2024年Q2财报;一加Open推出深红色版本

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 8月6日消息 搜狐2024年Q2财报 一加Open推出深红色版本 smart精灵#5将在澳洲首秀 OpenAI为ChatGPT测试文本水印 …

手动部署内网穿透

关于内网穿透&#xff0c;主要针对什么是公网和内网&#xff1f;NAT转化技术等引出内网穿透方法。 本文主要技术是利用frp部署内网穿透、以及nagix部署web服务。 测试环境&#xff1a; 服务器&#xff1a;Linux云服务内网&#xff1a;用本地WM充当内网云服务器Linux&#xf…

伯克利Linux系统管理: 脚本编写学习 课堂与实验(系统简洁保姆级学习)

Linux系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 第二章(上) Vim课堂与实验 文章目录 Linux系列文章目录一、前言二、学习内容&#xff1a;2.1 上课内容2.1.1 为什么要学习脚本编写&#xff1f;2.1.2 Bash编程语言2.1.3 SheBang2.…

半导体PEEK纳米级钻孔,用德国高精密主轴

在半导体行业&#xff0c;对精度、效率与稳定性的要求近乎苛刻。其中&#xff0c;PEEK&#xff08;聚醚醚酮&#xff09;材料因其优异的耐热性、耐化学性和机械性能&#xff0c;在高端半导体封装、微流控芯片等领域得到了广泛应用。然而&#xff0c;PEEK材料的硬度与韧性并存&a…

Armv8/Armv9的Pstate寄存器介绍

PSTATE概述 在Armv7及其之前&#xff0c;有一个重要的寄存器叫做程序状态寄存器CPSR&#xff0c;但是到了Armv8/Armv9的aarch64架构时&#xff0c;删除了CPSR寄存器&#xff0c;改为了PSTATE&#xff08;PE状态寄存器&#xff09;。 PSTATE表示一组小寄存器的集合&#xff0c;…

隐私指纹浏览器产品系列 — 什么是指纹(一)

1.引言 现在许多网站在努力的尝试标记互联网上的每一个访客&#xff0c;用以追踪用户的行为轨迹&#xff0c;分析行为习惯&#xff0c;以及确认是否为真实用户。除此之外&#xff0c;他们还利用这些标记&#xff0c;将多个可能是同一个用户身份的访客进行归一&#xff0c;关联…

中国高尔夫运动快速发展中,深圳高尔夫展邀您迎接机遇与挑战

在浩瀚的体育世界中&#xff0c;高尔夫以其悠久的历史、优雅的姿态和独特的魅力闻名于世&#xff0c;被誉为“古老的贵族运动”&#xff0c;而这个美誉却让很多人对它敬而远之。其实高尔夫被称作“贵族运动”&#xff0c;仅仅是因为早期它更多在贵族之间流行而已。 高尔夫&…

【TS】基本类型

基本类型 类型例子描述number1, -33, 2.5任意数字stringhi, "hi", hi任意字符串booleantrue、false布尔值true或false字面量其本身限制变量的值就是该字面量的值any*任意类型unknown*类型安全的anyvoid空值&#xff08;undefined&#xff09;没有值&#xff08;或und…

鸿蒙HarmonyOS开发:如何使用第三方库,加速应用开发

文章目录 一、如何安装 ohpm-cli二、如何安装三方库1、在 oh-package.json5 文件中声明三方库&#xff0c;以 ohos/crypto-js 为例&#xff1a;2、安装指定名称 pacakge_name 的三方库&#xff0c;执行以下命令&#xff0c;将自动在当前目录下的 oh-package.json5 文件中自动添…

面对电商渠道品牌要如何控价

在当今竞争激烈的市场环境中&#xff0c;品牌销售渠道的管理至关重要。线上和线下渠道的低价、窜货问题犹如侵蚀品牌根基的蚁穴&#xff0c;若不加以有效治理&#xff0c;品牌价值将受到严重损害。 线上渠道方面&#xff0c;除了利用系统精准监测低价情况外&#xff0c;还应注重…

手撕数据结构之二叉树

1.树 树的基本概念与结构 树是⼀种⾮线性的数据结构&#xff0c;它是由 n&#xff08;n>0&#xff09; 个有限结点组成⼀个具有层次关系的集合。把它叫做树是因为它看起来像⼀棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;⽽叶朝下的。 • 有⼀个特殊的结点&…