当前位置: 首页 > news >正文

单链表的头插,尾插,头删,尾删等操作

前言

  1. 顺序表要求是具有连续的物理空间,并且数据的话是在这些空间当中是连续的存储。但这样会带来很多问题,比如说在头部或者说中间插入的话,效率不是很高;并且申请空间可能需要扩容,并且越往后一般来说都是异地扩容,虽然看起来的话是简单的调用了一下realloc,但是从底层来看的话,这个代价很大。而且扩容的话也会存在一定程度的浪费,因此就需要链表的存在。

  1. 链表的话是一个数据存一个内存块。这些内存块之间并不一定要求是物理上连续的,这些内存块之间用指针进行相关的链接,链表实际上具有八种结构。

  1. 链表其实就是用指针这么链接起来的一些个内存块。

链表当中各个节点在物理上不一定是连续的,这个节点之间也并没有任何的顺序关系(都是各自随意malloc出来的),根本就不需要去考虑顺序,孤岛之间只需要有一根桥梁即可

单链表就关注这三个有机组成部分:

  1. 节点 SLTNode

  1. 节点地址(指向节点的指针) SLTNode*

  1. 一级指针(指向链表第一个节点) phead

  1. 二级指针(指向上面的一级指针) pphead


逻辑结构与物理结构

  1. 虽然有时候平时画图的时候,画链表的时候可能会带一些箭头之类的,但是真正在内存里面是不可能有箭头这些东西的。内存里面是不可能存着箭头→这些东西的。我们把这些箭头叫做逻辑结构,是我们想象出来的,因为这些箭头比指针更为直观。

  1. 在内存里面实实在在怎么存的被称为物理结构。

  1. 我们画图的时候看起来好像指针啊什么呀都是在动的,但实际上在内存里面的话,一切都是死的,没有动,无非就是不断的给指针变量进行赋值。然后在我们脑海中直观的形象表现就是:该指针变量不断的指来指去。

  1. 逻辑结构就是我们为了方便理解,形象化画出来的;但是在计算机内存里面是十分枯燥的,实实在在数据在内存中的变化是物理结构。


单链表节点(结构体类型)的创建

  1. 从语言的角度来讲,凡是有多个数据,都需要存到结构体里面去。链表的每一个节点就是通过结构体来表示。结构体里面有当前的数值data,并且还需要一个指针。因为上一个节点需要存下一个节点的地址,这样我才有寻找的依据,这样的话,各个内存块之间才可以像链条一样这么串起来。

  1. 并且我们已经知道每一个节点实际上就是一个结构体。既然上一个节点需要存下一个节点的地址。那么因此显而易见,无非就是一个结构体指针罢了,我们叫做next。

  1. 之前在c语言当中我们也讲过,结构体里面是不能够嵌套结构体的,就是无穷套娃了。但我们刚才结构体里面并没有结构体,是一个结构体指针,大小是确定的,就是四个字节。

//节点结构体的创建
typedef int SLTDataType;
typedef struct SLTNode
{SLTDataType data;struct SLTNode* next;
}SLTNode;

单链表的打印

1. 空的顺序表可以打印,当然一样道理,空的链表也可以打印,给我显示为空不就可以了

2. phead就是链表第一个节点的地址,如果这个链表是空链表,那么phead就是NULL

3. 当我为空链表的时候,phead就为NULL,在打印链表的时候不能够进行断言,不然的话空链表我就打印不出来了,直接把我程序终止了。

4. 链表的话在物理上并不是连续的,它的每一个节点都是malloc出来的

5. 每一个节点(说白了就是结构体)都会存放下一个节点的地址,因此就需要这一很关键的一步:cur = cur -> next

6. 0就是假,非0就是真,NULL本质就是0。

//单链表的打印
void SLTPrint(SLTNode* phead)
{SLTNode* cur = phead;while (cur != NULL){printf("%d->",cur->data);cur = cur->next;}printf("NULL\n");
}

单链表malloc一个新节点并赋值

//单链表malloc一个新节点并赋值
SLTNode* BuySLTNode(SLTDataType x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("BuySLTNode::Malloc");return NULL;}newnode->data = x;;newnode->next = NULL;return newnode;
}

单链表的尾插

1. 由于之前一样的,在这个地方是不能够进行空指针断言的,因为如果是断言的话,我在空链表的情形下想要去尾插,但是断言了的话,给我程序提前终止了,这还玩个屁啊。

2. 尾插的第一步是先得搞一个节点出来,这个地方就不像顺序表一样了,要考虑什么空间够不够啊,要不要扩容啊之类的就不需要考虑了。在这边的话就自己去malloc新创建一个节点。

3. 然后对于这个新节点newnode的值给进去,next指针为NULL。

4. 然后就是找到原先的尾巴,原尾节点的next成员要存储新尾节点的地址。

5. 刚才讲的情况都是链表不为空的情况,如果链表是空的话,这种情况需要额外处理。这时候只需要把phead指向新节点newnode就可以了。

//单链表的尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuySLTNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}

单链表的头插

1. 这个也需要分两种情况,以总是链表为空的情况,第二种就是链表非空。但是发现仅有的三行代码可以完全解决空的情况。

2. 然后发现在这个函数内部也需要创建一个新的节点。那么就是说可以把创建新的节点这个过程给他单独的提取出来。

//单链表的头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{SLTNode* newnode = BuySLTNode(x);newnode->next = *pphead;*pphead = newnode;
}

单链表的尾删

1. 删除的时候也是需要用二级指针。因为万一你要把指针置空的时候,如果你传一级指针的话,就完蛋了。那么原先那个指针就变成野指针了。

2. 链表在尾删的时候要注意分几种特殊情况,第一种情况是当前只有一个节点,第二种特殊情况就是整个链表都是空的。对于第一种情况直接free,然后把指针置空就完事儿了。对于第二种情况,直接暴力assert检查就可以。

//单链表的尾删
void SLTPopBack(SLTNode** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLTNode* prev = NULL;SLTNode* tail = *pphead;while (tail->next != NULL){prev = tail;tail = tail->next;}prev->next = NULL;free(tail);tail = NULL;}
}

单链表的头删

1. 首先也可以暴力检查一下这个链表是不是空的。但头删不需要特判链表只有一个节点的情况。

//单链表的头删
void SLTPopFront(SLTNode** pphead)
{assert(*pphead);SLTNode* first = *pphead;*pphead = (*pphead)->next;free(first);first = NULL;
}

单链表的初始化

这个非常简单,直接初始化就可以,因为只有一个值。直接创建一个结构体指针赋为NULL就可以

SLTNode* plist = NULL;

关于单链表函数操作中的有关于assert断言的问题

不是在参数里面碰到一个指针就assert一下,不是这么一根筋的。像这边单链表的话,当phead为NULL时我们都知道此时此刻表示一个空链表,但是空链表我就不能头插,尾插插入了吗?我照样可以这么插入;空链表难道我就不能打印了吗?我照样可以打印,只是什么都没有而已。但是对于删除而言,如果此时此刻你已经是一个空链表了,那么你还删个毛线啊?所以此时此刻呢又需要用assert断言一下,这种东西都是具体问题具体分析。

关于参数为二级指针的问题

1. 尤其要注意形参的改变不会影响实参,这个其实底层要理解的话,就是得通过函数栈帧。当传址调用的时候,实际上地址也是在拷贝,但由于你是在函数里面对指针进行解引用操作,因此产生的影响是持久性的,即使调用的函数退出回来了。

2. malloc向堆区动态申请内存的时候,是随机在内存里面划分一块区域的。

3. 当你的实参是一个指针的时候,虽然这时候函数传参看起来好像也是传址调用,但实际上调用函数内部执行的各种操作,对于函数外头的这个参数指针不会发生任何影响。因为实际上无论如何都会有拷贝这个环节会发生。

4. 在这边想要着重说明的是:我们在进行函数传参的时候,这时候就必须传二级指针。我们在函数体外已经先有一个指针,我们的函数内部操作都离不开要改变该指针的指向位置,要实现这个操作,就不能传一级指针,因为这样只有我这个一级指针自己在捣鼓;如果我传指针的地址(也就是二级指针),这样子我才能在函数体内去改变函数体外这个指针所指向的位置。

5. 我这个phead是一个实实在在的结构体指针,各种有关于单链表的操作,其中都需要phead指向的位置发生变化,如果在函数里面传一级指针的话,函数里面的各种乱七八糟的运转,跟我函数外面的phead指针一点关系都没有,因为你在函数内部自己有一个参数指针(形参),也许这个形参与phead指向的地址是一样的,但是当你传一级指针的时候,在函数里面各种捣鼓运算改变的都是你形参指向的位置。如果想要改变我这个phead指针指向的位置,就必须把phead的地址当成参数传给函数,因此这个参数也就是指针的地址,显而易见即为二级指针。

相关文章:

单链表的头插,尾插,头删,尾删等操作

前言顺序表要求是具有连续的物理空间,并且数据的话是在这些空间当中是连续的存储。但这样会带来很多问题,比如说在头部或者说中间插入的话,效率不是很高;并且申请空间可能需要扩容,并且越往后一般来说都是异地扩容&…...

Qt扫盲-QProcess理论总结

QProcess理论使用总结一、概述二、使用三、通过 Channel 通道通信四、同步进程API五、注意事项1. 平台特性2. 不能实时读取一、概述 QProcess 其实更多的是与外面进程进行交互的一个工具类,通过这个类来启动外部进程,获取这个进程的标准输出&#xff0c…...

JAVA进阶 —— Steam流

目录 一、 引言 二、 Stream流概述 三、Stream流的使用步骤 1. 获取Stream流 1.1 单列集合 1.2 双列集合 1.3 数组 1.4 零散数据 2. Stream流的中间方法 3. Stream流的终结方法 四、 练习 1. 数据过滤 2. 数据操作 - 按年龄筛选 3. 数据操作 - 演员信息要求…...

Ubuntu Protobuf 安装(测试有效)

安装流程 下载软件 下载自己要安装的版本:https://github.com/protocolbuffers/protobuf 下载源码编译: 系统环境:Ubuntu16(其它版本亦可),Protobuf-3.6.1 编译源码 cd protobuf# 当使用 git clone 下来的…...

驱动程序开发:FTP服务器和OpenSSH的移植与搭建、以及一些笔记

目录一、FTP服务器移植与搭建1、在ubuntu下安装vsftpd2、在window下安装FileZilla3、移植vsftpd到开发板上4、Filezilla 连接测试5、注意点二、开发板 OpenSSH 移植与使用1、移植 zlib 库2、移植 openssl 库3、移植 openssh 库4、openssh 使用测试三、关于u-boot上的操作及根文…...

优化改进YOLOv5算法之添加GIoU、DIoU、CIoU、EIoU、Wise-IoU模块(超详细)

目录 1、IoU 1.1 什么是IOU 1.2 IOU代码 2、GIOU 2.1 为什么提出GIOU 2.2 GIoU代码 3 DIoU 3.1 为什么提出DIOU 3.2 DIOU代码 4 CIOU 4.1 为什么提出CIOU 4.2 CIOU代码 5 EIOU 5.1 为什么提出EIOU 5.2 EIOU代码 6 Wise-IoU 7 YOLOv5中添加GIoU、DIoU、CIoU、…...

windows电脑pc如何使用svn获取文档和代码

一、安装svn 下载链接 也可通过其他方式下载 二、使用 2.1 随便找一个文件夹 2.2 点击右键,选择SVN Checkout 2.3输入网址 如当你在网页上访问时地址为https://10.197.78.78/!/#aaa/view/head/bbb 在这里不能直接填入,而是 https://10.197.78.78/sv…...

ROS1学习笔记:tf坐标系广播与监听的编程实现(ubuntu20.04)

参考B站古月居ROS入门21讲:tf坐标系广播与监听的编程实现 基于VMware Ubuntu 20.04 Noetic版本的环境 文章目录一、创建功能包二、创建代码2.1 以C为例2.1.1 配置代码编译规则2.1.2 编译整个工作空间2.1.2 配置环境变量2.1.4 执行代码2.2 以Python为例2.2.1 配置代码…...

​力扣解法汇总1590. 使数组和能被 P 整除

目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你一个正整数数组 nums,请你移除 最短 子数组(可以为 …...

Spring源码阅读(基础)

第一章:bean的元数据 1.bean的注入方式: 1.1 xml文件 1.2 注解 Component(自己写的类才能在上面加这些注解) 1.3配置类: Configuration 注入第三方数据源之类 1.4 import注解 (引用了Myselector类下…...

服务搭建篇(九) 使用GitLab+Jenkins搭建CI\CD执行环境 (上) 基础环境搭建

1.前言 每当我们程序员开发在本地完成开发之后 , 都要部署到正式环境去使用 , 在一些传统的运维体系中 , 开发与运维都是割裂的 , 开发人员不允许操作正式服务器 , 服务器只能通过运维团队来操作 , 这样可以极大的提高服务器的安全性 , 不经过安全保护的开放服务器 , 对于黑客…...

CDC 长沙站丨云原生技术研讨会:数字兴链,云化未来!

一、活动信息:活动主题:CDC 长沙站丨云原生技术研讨会活动时间:2023 年 3 月 14 日下午 14:30-17:30活动地点:长沙市岳麓区-拓维信息总部 1 楼多功能厅活动参与方式:免门票参与,戳此…...

A.特定领域知识图谱知识推理方案:知识图谱推理算法综述[二](DTransE/PairRE:基于表示学习的知识图谱链接预测算法)

推荐参考文章: A.特定领域知识图谱知识推理方案:知识图谱推理算法综述[一](基于距离的翻译模型:TransE、TransH、TransR、TransH、TransA、RotatE) A.特定领域知识图谱知识推理方案:知识图谱推理算法综述[二](DTransE/PairRE:基于表示学习的知识图谱链接预测算法) A.…...

香港酒店模拟分析项目报告--使用tableau、python、matlab

转载请标记本文出处 软件:tableau、pycharm、关系型数据库:MySQL 数据大量分析考虑电脑性能的情况。 文章目录前言一、爬虫是什么?二、使用tableau数据可视化1.引入数据1.1 制作直方图-各地区酒店数量条形图1.2 各地区酒店均价1.3 价格等级堆…...

第18天-商城业务(商品检索服务,基于Elastic Search完成商品检索)

1.构建商品检索页面 1.1.引入依赖 <!-- thymeleaf模板引擎 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- 热更新 --><…...

5.2 对射式红外传感器旋转编码器计次

对射式红外传感器1.1 接线图VCC GND分别接电源的正负极DO数字输出端&#xff0c;随意选择一个GPIO口1.2 硬件原理当挡光片或者编码盘在对射式红外传感器中间经过时&#xff0c;DO就会输出电平变化信号&#xff0c;电平跳变信号触发STM32 PB14号口中断&#xff0c;在中断函数中执…...

【数据库概论】第九章 关系查询处理和查询优化

第九章 关系查询处理和查询优化 本章主要介绍关系数据库查询管理和查询优化&#xff0c;主要分为代数优化&#xff08;又称逻辑优化&#xff09;和物理优化&#xff08;也称非代数优化&#xff09;。 9.1 关系型数据库系统的查询处理 查询处理是关系型数据库管理系统执行查询…...

(WIP) my cloud test bed (by quqi99)

作者&#xff1a;张华 发表于&#xff1a;2023-03-10 版权声明&#xff1a;可以任意转载&#xff0c;转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 问题 想创建一个local local test bed, 用来方便做各种云实验&#xff0c;如openstack, k8s, ovn, lxd等…...

git | git 2023 详细版

文章目录一、Git命令1.2 设计用户签名1.3 初始化本地库1.4 查看本地库状态1.5 添加至暂存区1.6 从暂存区删除1.7 将暂存区的文件提交到本地库1.8 查看版本信息二、Git分支2.1 查看分支2.2 创建分支2.3 切换分支2.4 合并分支三、GitHub3.1 代码克隆clone3.2 给库取别名3.3 推送本…...

camunda流程引擎基本使用(笔记)

文章目录一、camunda基础1.1 安装与部署流程引擎1.2 流程引擎结构1.3 流程引擎的基本使用1.3.1 创建一个BPMN Diagram1.3.2 实现一个外部工作者1.3.3 部署流程1.3.4 创建一个流程实例并消费1.3.5 向流程中添加用户任务1.3.6 添加网关1.3.7 业务规则二、Java 集成流程引擎2.1 为…...

JS之数据结构与算法

前言数据结构是计算机存储、组织数据的方式,算法是系统描述解决问题的策略。了解基本的数据结构和算法可以提高代码的性能和质量。也是程序猿进阶的一个重要技能。手撸代码实现栈,队列,链表,字典,二叉树,动态规划和贪心算法1.数据结构篇1.1 栈栈的特点&#xff1a;先进后出clas…...

CnOpenData·A股上市企业数字化转型指数数据

一、数据简介 企业数字化转型是近年来中国社会各界重点关注的领域&#xff0c;但基础数据的不完善在很大程度上制约了相关科学研究的开展。构建合理、科学的数字化转型指标体系有利于学者定量地研究企业数字化的相关问题&#xff0c;也有利于衡量企业的数字化水平。广东金融学院…...

VMware16pro虚拟机安装全过程

很多时候需要用到Linux系统&#xff0c;简单的一种方式可以是&#xff1a;Windows系统运行Linux&#xff08;Windows Subsystem for Linux&#xff09;不过有些时候还是需要虚拟机来运行Linux&#xff0c;也更方便点&#xff0c;比如在做嵌入式系统的烧录等操作都需要Linux环境…...

阿里云第六代云服务器最新价格表(计算型c6、通用型g6和内存型r6)

目前阿里云第六代云服务器有计算型c6、通用型g6和内存型r6实例。计算型c6实例有2核4G、4核8G、8核16G配置可选&#xff0c;主要适用于网站应用、批量计算、视频编码等场景。通用型g6实例有2核8G、4核16G、8核32G配置可选&#xff0c;适用于各种类型的企业级应用&#xff0c;网站…...

微小目标识别研究(2)——基于K近邻的白酒杂质检测算法实现

文章目录实现思路配置opencv位置剪裁实现代码自适应中值滤波实现代码动态范围增强实现代码形态学处理实现代码图片预处理效果计算帧差连续帧帧差法原理和实现代码实现代码K近邻实现基本介绍实现代码这部分是手动实现的&#xff0c;并没有直接调用相关的库完整的代码——调用ope…...

2022-06-14至2022-08-11 关于复现MKP算法的总结与反思

Prerequisite 自2022年6月14日至2022年8月11日的时间内&#xff0c;我致力于完成A Hybrid Approach for the 0–1 Multidimensional Knapsack problem 论文的复现工作&#xff0c;此次是我第一次进行组合优化方向的学习工作&#xff0c;下面介绍该工作内容发展过程以及该工作结…...

IBMMQ教程二(window版安装)

下载下载地址&#xff1a;https://public.dhe.ibm.com/ibmdl/export/pub/software/websphere/messaging/mqadv/我这里选择的是9.1.0.0版本安装将下载完成的压缩包解压双击Setup.exe直接运行点击软件需求查看系统配置是否满足&#xff0c;右边绿色的对号说明满足需求&#xff0c…...

Java | HashSet 语法

HashSet 基于 HashMap 来实现的&#xff0c;是一个不允许有重复元素的集合。 HashSet 允许有 null 值。 HashSet 是无序的&#xff0c;即不会记录插入的顺序。 HashSet 不是线程安全的&#xff0c; 如果多个线程尝试同时修改 HashSet&#xff0c;则最终结果是不确定的。 您必须…...

js学习4(运算符)

### 1.算数运算符&#xff1a; 、-、*、\、%&#xff08;取余&#xff09;、**&#xff08;幂方&#xff09; ## 优先级 同数学课程&#xff0c;可以加括号 ### 2.自增和自减 、--&#xff08;即数值变量加一或减一&#xff09; ### 3.赋值运算符 、、-、*、/、... ### 4.比较运…...

2月更新 | Visual Studio Code Python

我们很高兴地宣布&#xff0c;2023年2月版 Visual Studio Code Python 和 Jupyter 扩展现已推出&#xff01;此版本包括以下改进&#xff1a;从激活的终端启动 VS Code 时的自动选择环境 使用命令 Python: Create Environmen 时可选择需求文件或可选依赖项 预发布&#xff1a;改…...

html5如何实现网站开发/个人网站推广方法

导语&#xff1a;会议通知的种类有很多种&#xff0c;那么标准的会议通知是怎么样的呢&#xff0c;下面时候小编为大家整理的关于&#xff1a;会议通知&#xff0c;希望对大家有所帮助,欢迎阅读&#xff0c;仅供参考&#xff0c;更多相关的知识&#xff0c;请关注文书帮!由山东…...

想自己做点飘纱素材到网站上买/我想做网络推广

conda 1、conda create --name xlr python2.7 --name也可以缩写为-name python2.7是python的版本号,如果不写就默认为装anaconda时python版本 xlr是创建的新的虚拟环境的名字&#xff0c;创建完&#xff0c;可以在装anaconda的目录下找打envs/xlr(或直接find / -name xlr也可…...

湘西网站建设花垣/上海广告公司排名

本文翻译自&#xff1a;http://unews.utah.edu/news_releases/self-repairing-software-tackles-bugs/ 犹他大学关于信息安全的演讲 2014年11月13日——犹他大学的计算机科学家开发了一款软件&#xff0c;不仅可以检测和彻底清除从未出现过的病毒&#xff0c;也可以自动修复其…...

门户网站的主要功能/互联网营销的优势

一。手机和蓝牙耳机配对 1.首先打开蓝牙耳机电源&#xff0c;进入配对状态&#xff0c;一般都是长安那个大的”接听键“&#xff0c;当指示灯闪的时候不要松手&#xff0c;要一直按着&#xff0c;直到指示灯一直亮。&#xff08;蓝牙耳机不同可能配对时需要安的键也不同&#x…...

拍摄宣传片费用明细/google seo是什么意思

我有一个AJAX调用敲定表单时在更新数据库中的字段。但是&#xff0c;通话似乎没有到达控制器。当我提醒时&#xff0c;它就会起作用。由于这个问题我目前已经设置为同步&#xff0c;但即使如此&#xff0c;没有警报&#xff0c;它每5到6次只能到达控制器1。这是AJAX位&#xff…...

做外贸的零售网站/优化推广公司哪家好

XMPP客户端部分无法连接&#xff0c;问题解决&#xff1a; No response from the server.: User: at org.jivesoftware.sm ack.NonSASLAuthentication.authenticate(NonSASLAuthentication 我有一个我在配置文件中设置的XMPP帐户。此JID能够通过XMPP服务器进行身份验证。然…...