[数据结构] -- 单链表

🌈 个人主页:白子寰
🔥 分类专栏:C++打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~
💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~)

 

目录

链表

概念

结构

链表的分类

单向链表和双向链表

 带头(哨兵位) 或 不带头(哨兵位) 链表

顺序表和链表的优缺点

在SList.h文件中

定义单链表的结构

实现单链表的接口/方法

在SList.c文件中 

打印单链表(遍历链表)

开辟空间

开辟空间molloc返回值问题

尾部插入元素

传参的时候为什么要传二级指针? 

测试尾插 

头部插入元素 

测试 

尾部删除元素 

测试 

头部删除元素 

测试 

查找元素 

 在指定位置之前插入数据

测试 

删除pos节点 

测试 

在指定位置之后插入数据

删除pos之后的节点 

测试 

销毁链表 




链表

概念

链表是一种物理存储结构上非连续、非顺序的存储结构,

数据元素的逻辑顺序是通过链表中的指针链接次序实现的,


单链表一般不会单独使用,
只有头插和头删实现简单且效率高

结构

链表也属于线性表,线性表在物理上存储时,
通常以数组(顺序表)和链式结构(链表)的形式存储,
链式结构在逻辑上是连续的,但在物理上不一定连续
                 
现实中的结点一般是从堆上申请出来的
              
从堆上申请的空间,是按照一定的策略来分配的,
两次申请的空间可能连续,也可能不连续


链表的分类

单向链表和双向链表

单向链表(常用)

双向链表 

 


 带头(哨兵位) 或 不带头(哨兵位) 链表

 带头(哨兵位) 链表

不带头(哨兵位) 链表


循环链表

 

带头双向循环链表(常用)

 



顺序表和链表的优缺点

顺序表链表
存储空间物理上一定连续逻辑上连续,物理上不一定连续
访问随机访问不支持随机访问
任意位置插入或删除元素效率低修改指针指向
应用空间不够扩容,元素高效存储,随机访问分节点,开节点,可以在任意位置插入或删除

 



在SList.h文件中

定义单链表的结构

typedef int SLTDataType;
typedef struct SListNode
{SLTDataType data;		//数据struct SListNode* next; //指针域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);
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos);
//销毁链表
void SListDesTroy(SLTNode** pphead);


 

在SList.c文件中 

打印单链表(遍历链表)

//SLTNode*,表示 phead 是一个指向 SLTNode 类型的指针。
void SLTPrint(SLTNode* phead)		//接收一个指向链表头节点的指针 phead 作为参数
{//一级指针SLTNode* pcur = phead;while (pcur){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL");printf("\n");
}

 

开辟空间

//开辟空间
SLTNode* SLTBuyNode(SLTDataType x)
{//为一个 SLTNode 类型的结构体分配内存,以便访问和操作这个新分配的 SLTNode 结构体//所以返回值为SLTNnode*SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc");exit(1);}newnode->data = x;newnode->next = NULL;return newnode;
}

开辟空间molloc返回值问题

函数原型:

 

 

 


尾部插入元素

//尾部插入元素
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);//头结点为空if (*pphead == NULL){*pphead = newnode;return;}//头结点不为空SLTNode* ptail = *pphead;while (ptail->next){ptail = ptail->next;}ptail->next = newnode;
}

传参的时候为什么要传二级指针? 

二级指针,在函数内部修改头指针本身的值

一级指针,用于遍历和访问链表

以下的 打印链表和销毁链表函数 说明一级和二级指针的意思 

测试尾插 


 

头部插入元素 

//头部插入元素 
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = SLTBuyNode(x);newnode->next = *pphead;	// *pphead表示头结点*pphead = newnode;
}

测试 


 

尾部删除元素 

free作用:

①free(ptail);之后,ptail指针本身的值并未改变,但它所指向的内存已经被释放,因此不应该再使  用这个指针访问已经被释放的内存。

②我们只需要确保不要再使用这个指针来访问内存,而不必将其置为NULL

//尾部删除元素 
void SLTPopBack(SLTNode** pphead)
{assert(pphead);assert(*pphead);	//保证头结点不为空if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;return;}//有多个结点SLTNode* ptail = *pphead;SLTNode* prev = NULL;while (ptail->next){prev = ptail;ptail = ptail->next;}//单链表最后一个结点,只有数据域data且指针域的值是NULL// 释放尾节点的内存free(ptail);// 将尾节点的前驱节点的next置为NULL,实现删除尾节点 prev->next = NULL;
}

测试 

头部删除元素 

void SLTPopFront(SLTNode** pphead)
{assert(pphead);assert(*pphead);	//保证头结点不为空SLTNode* next = (*pphead)->next;free(*pphead);*pphead = next;
}

测试 

查找元素 

//查找
SLTNode* SLTFind(SLTNode** phead, SLTDataType x)
{assert(phead);SLTNode* pcur = *phead;while (pcur){if (pcur->data == x){return pcur;}pcur = pcur->next;}return NULL;
}

 在指定位置之前插入数据

//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{assert(pphead);assert(*pphead);assert(pos);SLTNode* newnode = SLTBuyNode(x);//pos刚好是头节点if (newnode->next == *pphead){SLTPushBack(pphead, x);return;}//pos刚好不是头节点SLTNode* pcur = *pphead;while (pcur->next != pos){pcur = pcur->next;}pcur->next = newnode;newnode->next = pos;
}

测试 

删除pos节点 

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{assert(pphead);assert(*pphead);assert(pos);//刚好是头节点if (pos == *pphead){SLTPopFront(pphead);return;}//不是头节点SLTNode* pcur = *pphead;while (pcur->next != pos){pcur = pcur->next;}pcur->next = pos->next;free(pos);pos = NULL;
}

测试 

在指定位置之后插入数据

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

 

删除pos之后的节点 

//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos)
{assert(pos);SLTNode* p1 = pos->next;SLTNode* pcur = pos->next->next;pos->next = pcur;free(p1);p1 = NULL;
}

测试 

 

销毁链表 

//销毁链表
//SLTNode**,表示 pphead 是一个指向 SLTNode* 类型的指针的指针
void SListDesTroy(SLTNode** pphead)
{/*  pphead:(二级指针)*/assert(pphead);//一级指针assert(*pphead);//头结点不为空,链表不为空SLTNode* pcur = *pphead;	//*pphead 是头指针本身(一级指针),用于遍历和访问链表//先释放,后置空while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}


 

 

 ***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。

等等等等一下,分享最近喜欢的一句话:

“迷失的时候,选择更艰辛的那条路”。

我是白子寰,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!! 
好了划走吧。

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

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

相关文章

c++编程14——STL(3)list

欢迎来到博主的专栏:c编程 博主ID:代码小豪 文章目录 list成员类型构造、析构、与赋值iterator元素访问修改元素list的操作 list list的数据结构是一个链表,准确的说应该是一个双向链表。这是一个双向链表的节点结构: list的使用…

Vue学习笔记3——事件处理

事件处理 1、事件处理器(1)内联事件处理器(2)方法事件处理器 2、事件参数3、事件修饰符 1、事件处理器 我们可以使用v-on 指令(简写为)来监听DOM事件,并在事件触发时执行对应的JavaScript。 用法: v-on:click"me…

JVM学习-执行引擎

执行引擎 执行引擎是Java虚拟机核心组成部分之一虚拟机是一个相对于物理机的概念,这两种机器都有代码执行能力,其区别是物理机的执行引擎是直接建立在处理器、缓存、指令集和操作系统层面上的,而虚拟机的执行引擎是由软件自行实现的&#xf…

【算法】递归、搜索与回溯——简介

简介:递归、搜索与回溯,本节博客主要是简单记录一下关于“递归、搜索与回溯”的相关简单概念,为后续算法做铺垫。 目录 1.递归1.1递归概念2.2递归意义2.3学习递归2.4写递归代码步骤 2.搜索3.回溯与剪枝 递归、搜索、回溯的关系: …

ICML2024 定义新隐私保护升级:DP-BITFIT新型微调技术让AI模型学习更安全

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享,与你一起了解前沿深度学习信息! 引言:差分隐私在大模型微调中的重要性和挑战 在当今的深度学习领域,大型预训练模型的微调已成为提高各种任务性能的关键技术。然而&am…

推特热帖:大语言模型自荐能够替代的20种人类工作!快来看你是否需要转行!

最近推特上有一个例子引起了广泛的讨论,事情的起因是这样的:网友让 GPT-4o 预测一下自己未来将会替代人类哪些工作? 这听起来很有趣!GPT-4o会给出什么样的预测呢? 3.5研究测试:hujiaoai.cn 4研究测试&…

02-Linux【基础篇】

一、Linux的目录结构 1.基本介绍 Linux的文件系统采用层级式的树状目录结构,在此结构中的最上层是根目录"/",然后在此目录下再创建其他的目录 深刻理解Linux树状文件目录是非常重要的 记住一句经典的话:在Linux世界里&#xff…

如何在 DigitalOcean Droplet 云主机上创建 Ubuntu 服务器

在本文中,你将通过 DigitalOcean 的管理面板创建一个 Ubuntu 服务器,并将其配置为使用你的 SSH 密钥。设置好服务器后,你可以在其上部署应用程序和网站。 本教程是DigitalOcean云课程简介的一部分,它指导用户完成将应用程序安全地…

win10右键没有默认打开方式的选项的处理方法

问题描述 搞了几个PDF书籍学习一下,不过我不想用默认的WPS打开,因为WPS太恶心人了,占用资源又高。我下载了个Sumatra PDF,这时候我像更改pdf文件默认的打开程序,发现右击没有这个选项。 问题解决 右击文件–属性–…

汽车以太网发展现状及挑战

一、汽车以太网技术联盟 目前推动汽车以太网技术应用与发展的组织包括:OPEN Alliance(One-Pair Ether-Net Alliance SIG)联盟,主要致力于汽车以太网推广与使用,该联盟通过推进 BroadR- Reach 单对非屏蔽双绞线以太网传…

设计新境界:大数据赋能UI的创新美学

设计新境界:大数据赋能UI的创新美学 引言 随着大数据技术的蓬勃发展,它已成为推动UI设计创新的重要力量。大数据不仅为界面设计提供了丰富的数据资源,还赋予了设计师以全新的视角和工具来探索美学的新境界。本文将探讨大数据如何赋能UI设计…

面试八股之JVM篇3.5——垃圾回收——G1垃圾回收器

🌈hello,你好鸭,我是Ethan,一名不断学习的码农,很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 🏃人生之义,在于追求,不在成败,勤通…

常见 JVM 面试题补充

原文地址 : 26 福利:常见 JVM 面试题补充 (lianglianglee.com) CMS 是老年代垃圾回收器? 初步印象是,但实际上不是。根据 CMS 的各个收集过程,它其实是一个涉及年轻代和老年代的综合性垃圾回收器。在很多文章和书籍的划分中&…

SpringCloud Alibaba的相关组件的简介及其使用

Spring Cloud Alibaba是阿里巴巴为开发者提供的一套微服务解决方案,它基于Spring Cloud项目,提供了一系列功能强大的组件,包括服务注册与发现、配置中心、熔断与限流、消息队列等。 本文将对Spring Cloud Alibaba的相关组件进行简介&#xff…

ROCm上运行预训练BERT

14.10. 预训练BERT — 动手学深度学习 2.0.0 documentation (d2l.ai) 下载数据集 在d2l-zh/pytorch/data目录解压: ~/d2l-zh/pytorch/data$ unzip wikitext-2-v1.zip Archive: wikitext-2-v1.zipcreating: wikitext-2/inflating: wikitext-2/wiki.test.tokens …

数据库--数据库基础(一)

目录 第一章 绪论 一.数据库的基本概念 1. 数据库的4个基本概念 2、数据库系统的特点 二.数据库和文件 三.数据模型 1.概念模型 2.逻辑模型(物理模型) 2.1关系模型 四.数据库系统的三级模式结构: 五数据库的二级映像功能与数据独立性 第二章 关系数据库…

2024电工杯数学建模B题高质量成品论文,包括代码数据

2024电工杯数学建模B题高质量成品论文,包括代码数据 完整内容见文末名片 摘要 大学时期是学生们知识学习和身体成长的重要阶段,良好的饮食习惯对于促进生长发育和保证身体健康具有重要意义。针对当前大学生中存在的饮食结构不合理及不良饮食习惯的问题…

为了性能,放弃tft_eSPI,选择arduino_gfx吧

本来对于tft_espi和arduino_gfx没啥特别的感觉,都是tft屏幕驱动,arduino_gfx的好处就是除了支持tft外还支持一些oled屏幕。 谁知道在探寻我那个在单片机项目上显示中文方案 https://github.com/StarCompute/tftziku 时候,寻求极致性能测了一些东西。 t…

算法之背包问题

可分的背包问题是可以用贪心法来解决,而0-1背包问题通常使用动态规划方法来解决。 可分背包问题: 在可分背包问题中,物品可以被分割,您可以取走物品的一部分以适应背包的容量。这里的关键是物品的价值密度,即单…

VTK9.2.0+QT5.14.0绘制三维显示背景

背景 上一篇绘制点云的博文中,使用的vtkCameraOrientationWidget来绘制的坐标轴,最近又学习到两种新的坐标轴绘制形式。 vtkOrientationMarkerWidget vtkAxesActor 单独使用vtkAxesActor能够绘制出坐标轴,但是会随着鼠标操作旋转和平移时…