【数据结构】单链表按位序插入元素e【前插】(带头结点的和不带头结点的)这篇很重要,文字说明比起其他篇是正确的
声明单链表的结构体成员
struct LNode {int data;struct LNode *next;
};typedef struct LNode LNode;// 或者: 两者是等价的
typedef struct LNode {int data;struct LNode *next;
}LNode;
按位序插入元素e:就是在第i个位置插入新结点,数据域为e
以下带头结点的:
思路:在第i个位置插入,就要找到第i-1个位置,然后在它的后面分配存储空间,创建新结点,再改变新结点以及其左右结点的指针指向,完成插入
- 由于单链表不具有随机存取的特点,不能想找i就找i,只能从头开始依次遍历,也就是从头指针L开始,即第0个结点,因为一开始的时候L是指向第一个(i=1)结点的,
- 就要用到循环,由于有条件判断,就用了while循环
- 单链表具有指针域,声明的L头指针是指向链表的第一个实际元素的,但是L的指向不能动,它必须指向链表的第一个元素,所以就要再声明一个新的指针变量p,让它初始化指向单链表的第一个结点,即让p=L,以此实现从头开始遍历
- 遍历到第i-1个位置,就可以停止,在其后面创建结点,分配存储空间
- 怎么能用代码表示,新结点一定是在i-1结点的后面呢:让新结点的指针域指向i-1的指向,再让i-1的指针域指向新结点,通过指针完成,再给新结点的数据域赋值e,新结点就插入完成了
- 注意:为了代码的健壮性,在执行上述代码时,我觉得有几个要注意的地方:
- 首先,要确保查找的位序是合法的,不然就不要执行了,会报错的,位序i从1开始,最多只能在第1 个位置插入新结点,<1肯定不合法
- 其次,如果查找的位序根本就不存在当前的单链表中,那么while循环走到最后,p指针应该是指向NULL,指向NULL的时候就不要再继续循环了,因为后面以及没有结点了
- 最后,由于是动态声明的单链表,可以动态分配存储空间,就不存在空间满了不能插入的情况,可以不做这个兼容
代码:
bool ListInsert(LinkList &L, int i, int e) {LNode *p;int j=0;p=L;if(i<1) {return false; // 位序不合法,返回false停止指向插入操作}while(p!=NULL && j<i-1) {p=p->next; // p结点的指针域存储的下一结点的地址赋值给p结点,表示p结点此时就走到了原p的下一节点,此时的P的指针域存的就是原p下一结点的指针域存的结点地址// 不能写成p->next=p,因为p->next=p表示p指针域指向的元素是p结点,就是自己指向自己了j++;}// 如果循环完整个单链表都没有找到要找的位序,最后p应该是指向null,如果p指向null,就不应该再指向插入操作了if(p==NULL) {// 我感觉,p最后会走向NULL,说明要找的位序都超过单链表的长度了,其实也可以在i<1的时候加个条件判断i>L.length也可以吧return false;}// 找到i-1,跳出循环,此时p指针指向i-1// 假设原顺序是p-q-r,现在想在p和q之间插入s,值为eLNode *s = (LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next; // p->next:p结点的指针域,存储下一结点的地址,即q结点的地址// s->next:s结点的指针域,存储下一结点的地址 // 将p结点的下一结点地址即q结点的地址,赋值给s结点的指针域存储,也就是说此时s指向的下一结点是qp-next=s; // s表示新结点,p->next表示p的指针域,存储下一结点的地址// s赋值给p->next,就是说p指向的下一节点是s,即形成了p-s-q-rreturn true;
}
分析一下时间复杂度:
- 最好时间复杂度,i=1时,循环0次,O(1)
- 最坏时间复杂度,插在表尾,i=n,循环n-1次,O(n)
- 平均时间复杂度,插在除表头和表尾之外的任意位置,他们的概率都是一样的p=1/(n-1)
平均循环次数=总次数*概率=(1+2+3+…+n-1)*1/(n-1)=n(n-1)/2 * 1/(n-1) = n/2,O(n)
以下是不带头结点的:
请注意,头指针L和头结点是两个东西,一个单链表,它可以没有头结点,但它一定有头指针,头指针指向链表的第一个结点,如果链表带头结点,头指针L就指向头结点,头结点不存储数据,如果链表不带头结点,头指针L就指向链表的第一个实际结点
思路:在第i个位置插入结点,就要找到第i-1个结点,在它的后面创建新结点,给新结点分配存储空间,然后通过改变指针指向来实现,与带头结点的步骤一致。
- 只是有一点,此时考虑的是不带头结点的单链表,所以L指向第一个实际结点,在位序i=1的位置插入结点时,找i-1的位置,就找不到,因为原先是把头结点当作位序为0的位置做插入的。所以此时就要单独考虑i=1时的情况。
- i=1时,第一个结点前面是头指针L,应该让头指针L指向新插入的i=1的结点,让新插入的i=1的结点的指针域存储原i=1的结点的地址,也就是原先头指针L存储的地址
- 原先带头结点的单链表查找i是从0开始遍历的,因为头结点可看作位序为0的结点,在第1个位置插入就是在头结点后面插,所以要从i-0=0开始遍历。现在没有头结点,i=1的位置单独写逻辑了,只要考虑从第二个位置开始之后的,也就是从i-1=1开始遍历
bool inserList_Nohead(LinkList &L, int i, int e) {if(i<1) {return false;}if(i==1) {LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=L;L=s;}int j=1;LNode *p;p=L;// 以下这段和上面带头结点的插入其实是一样的,可以用一个函数调用,就不要写那么多代码了while(p!=NULL && j<i-1) {p=p->next; // p->next:p结点的指针域,存储下一结点的地址,赋值给p结点就表示此时p结点变成了下一节点,// 如果写成p->next=p,就表示:p结点的指针域存储的结点是p结点,就是自己指向自己,这个链表就断了j++;}if(p==NULL) {return false;}LNode *s=(LNode *)malloc(sizeof(LNode));s->data=e;s->next=p->next;p->next=s;return true;
}
相关文章:
【数据结构】单链表按位序插入元素e【前插】(带头结点的和不带头结点的)这篇很重要,文字说明比起其他篇是正确的
声明单链表的结构体成员 struct LNode {int data;struct LNode *next; };typedef struct LNode LNode;// 或者: 两者是等价的 typedef struct LNode {int data;struct LNode *next; }LNode;按位序插入元素e:就是在第i个位置插入新结点,数据域为e 以下带…...
Maven Surefire Exclude 无效问题排查日志
昨天有个需求,要在单元测试的时候单线程执行,并且只执行单元测试类特殊结尾的,那么根据以往经验,直接在maven里面配置exclude并且指定include即可。如下尝试 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin&…...
ArcGIS笔记4_水动力模型验证不理想时如何修改局部水深地形
本文目录 前言Step 1 模型验证不理想的情况Step 2 修改确值点并重新插值 前言 本章主要服务于MIKE水动力模型的调整修改工作。水动力模型跑完之后,常常会出现验证结果不理想的情况,比如潮位验证中,实测站点数据与模拟数据相差很大࿰…...
介绍一下mysql有哪些索引类型
以下是MySQL的8种不同索引类型的比较,以帮助你了解它们的特点和适用场景: 索引类型用途和特点适用场景B-Tree 索引用于范围查询、等值查找和排序操作大多数查询 ,不适合全文搜索和空间数据。唯一索引保证索引列的值唯一,不允许重…...
#力扣:125. 验证回文串@FDDLC
125. 验证回文串 一、Java class Solution {public boolean isPalindrome(String s) {for (int l 0, r s.length() - 1; l < r; l, r--) {while (l < r && !Character.isLetterOrDigit(s.charAt(l))) l;while (l < r && !Character.isLetterOrDig…...
分享一下便利店怎么做微信小程序
便利店微信小程序开发,让生意更便捷! 在这个数字化时代,微信小程序已经成为一种新的生活方式。它不仅改变了人们的消费习惯,还为各行各业提供了无限商机。对于便利店来说,微信小程序是一个绝佳的营销工具,…...
Gitlab CI/CD 入门教程
前言 开发人员常常提到的 CI/CD 是什么? 是用于集成测试的工具,每次提交代码后自动检测、构建和进行单元测试的过程。这一整条流水线式的测试流程我们称之为 pipeline。 入门教程 如何使用 CI/CD? 首先需要确保有可用的 runner(如何确保…...
【mfc/VS2022】计图实验:绘图工具设计知识笔记
绘制曲线(贝塞尔曲线): 转自:CDC 类 | Microsoft Learn 绘制一条或多条贝塞尔曲线。 BOOL PolyBezier(const POINT* lpPoints,int nCount);参数 lpPoints 指向包含曲线端点和控制点的 POINT 数据结构数组。 nCount 指定 lpPo…...
C# PortraitModeFilter (人物图片)背景模糊
效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Windows.Forms; us…...
centos7下安装elasticsearch7.8.1并配置远程连接
1、下载安装包 sudo wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.8.1-linux-x86_64.tar.gz 2、解压 sudo tar -zxvf elasticsearch-7.8.1-linux-x86_64.tar.gz 3、添加用户并设置密码 sudo useradd es sudo passwd es # 设置密码 Lida15…...
MongoDB的作用和安装方法
MongoDB是一种非关系型数据库,其作用是存储和管理非结构化数据,例如文档、图像和视频等多媒体数据。它有以下几个特点: 数据存储的格式是类似JSON的文档格式,易于理解、存储和查询。可扩展性强,可以在多个服务器上分布…...
spring boot 使用SSE向前端推送数据
SSE(Server-Sent Events)是一种基于HTTP的实时通信协议,它允许服务器向客户端发送持久性的数据流。与WebSocket不同的是,SSE是单向通信,只能由服务器向客户端发送数据。Spring Boot通过Spring WebFlux模块提供了对SSE的…...
C++智能指针(三)——unique_ptr初探
与共享指针shared_ptr用于共享对象的目的不同,unique_ptr是用于独享对象。 文章目录 1. unqiue_ptr的目的2. 使用 unique_ptr2.1 初始化 unique_ptr2.2 访问数据2.3 作为类的成员2.4 处理数组 3. 转移所有权3.1 简单语法3.2 函数间转移所有权3.2.1 转移至函数体内3.…...
Composition Api 与 Options Api 有什么区别?
Vue 3.0采用的Composition API与Vue 2.x使用的Options API在编写Vue组件时有一些区别。 区别: 组织代码的方式不同: Options API:按照选项进行组织,将数据、计算属性、方法等声明在一个对象中。Composition API:按照逻…...
紫光同创FPGA实现UDP协议栈网络视频传输,基于YT8511和RTL8211,提供4套PDS工程源码和技术支持
目录 1、前言免责声明 2、相关方案推荐我这里已有的以太网方案紫光同创FPGA精简版UDP方案紫光同创FPGA带ping功能UDP方案 3、设计思路框架OV7725摄像头配置及采集OV5640摄像头配置及采集UDP发送控制视频数据组包数据缓冲FIFOUDP协议栈详解RGMII转GMII动态ARPUDP协议IP地址、端口…...
深度学习简述
⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...
【从零开始学习Redis | 第二篇】Redis中的数据类型和相关命令
前言: Redis是一种快速、高效的开源内存数据库,被广泛用于构建各种类型的应用程序。其被设计成支持多种数据类型,这使得Redis在处理各种场景的数据存储和操作中非常灵活。Redis的数据类型提供了对不同数据结构的直接支持,包括字符…...
数据结构 - 3(链表12000字详解)
一:LinkedList的使用 1.1 ArrayList的缺陷 上篇文章我们已经基本熟悉了ArrayList的使用,并且进行了简单模拟实现。由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移&am…...
Jmeter性能测试插件jpgc的安装
一、获取插件包 1.访问官网获取 官网地址: 2.百度网盘下载 链接:百度网盘 请输入提取码 提取码:blmn 二、安装路径 将下载到的plugins-manager.jar插件存放到%JMETER_HOME%/lib/ext目录下 三、安装插件 1.重启Jmeter 如果已启动了…...
关于safari浏览器浏览html video标签无法正常播放的问题
问题: 前端demo使用一个video标签包含一个非静态资源的mp4文件。在chrome浏览器下可以正常展示,但是safari却不可以。 原因: 1. mp4文件必须用ffmpeg合成的,其他压缩的mp4文件是不可能展示的。请确定mp4文件并用正常的ffmpeg进…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
