数据结构:图文详解单链表的各种操作(头插法,尾插法,任意位置插入,删除节点,查询节点,求链表的长度,清空链表)


目录

 一.什么是链表

二.链表的实现

节点的插入

头插法

尾插法

指定位置插入

节点的删除

删除第一次出现的关键字节点

删除所有关键字节点

节点的查找

链表的清空

链表的长度


前言:在上一篇文章中,我们认识了线性数据结构中的顺序表,而本篇文章则是介绍线性数据结构中的另一个结构——链表

想要了解顺序表相关操作的知识可以查看这篇文章:
图文详解顺序表的各种操作

 一.什么是链表

链表是一种数据结构,它由一系列节点(node)构成,每个节点中包含了数据(data)和指向下一个节点的指针(next)。链表中的节点可以在内存中任何位置,它们通过指针链接在一起,形成一个链式结构。链表相对于数组的优点在于它可以动态地增加、删除节点,而不需要移动大量的数据。链表的缺点是访问元素时需要遍历整个链表,效率较低。

二.链表的实现

链表由不同的节点相互串起来,每个节点由俩个部分组成,一个是数据域,用来放具体是数值内容,另一个是指针域,用来存放下一个节点的地址信息,彼此之间就像是用链条串起来一样,就像下图展示的这样,所以称之为链表。

对于上图这样的结构,我们可以如下定义一个链表,将链表作为一个类,并且在这个类中有一个内部类专门存储每一个节点的数据结构,还有一个头节点单独定义来记录链表的起始位置

public class MyLinkList{//节点的数据结构static class ListNode{public int val;public ListNode next;}//链表的属性public ListNode head;//记录链表的第一个元素:头节点
}

对一个链表,它应该完成以下这些功能,我们将这些功能抽象出一个接口,然后通过这个接口去实现一个真正的链表

public interface Ilist {//头插void addFirst(int data);//尾插void addLast(int data);//指定插入void addIndex(int index,int data);//查询是否存在boolean contains(int key);//删除节点void remove(int key);//删除所有与目标相同的节点void removeAllKey(int key);//得到链表的长度int size();//清空链表void clear();//输出链表的所有信息void display();
}

节点的插入

我们将节点的插入分为三种:

  • 头部插入:将节点插入到链表的最前面
  • 尾部插入:将节点插入到链表的最后面
  • 指定位置插入:将节点插入到链表的中间

头插法

如图,我们准备对于刚才的链表进行插入

我们这里分俩个步骤进行操作:

  1. 将新节点指向头节点
  2. 更新头节点的位置

我们更改要添加节点的指针域,让它指向新的节点 

在指向完成后,我们新添加的节点就已经是链表的第一个节点了,所以我们要更新头节点的信息,记录新节点才是第一个节点

这样我们就完成了头部插入节点,具体代码实现如下,先生成一个节点,然后按照上面图示的思路进行操作

    //头插法public void addFirst(int data) {ListNode newNode = new ListNode(data);newNode.next = this.head;this.head = newNode;}

尾插法

尾插法是将节点插入到链表的末尾,但是我们是并没有记录末尾节点的位置的,所以如果要使用尾插法的话就需要先找到尾部节点。那我们只需要根据最后一个节点特征进行遍历找到最后一个节点就可以了,而最后一个节点最大的特征就是,它只有数据域内有信息,指针域里面是空。如果链表为空的话,那我们直接在头节点之后添加就可以,整体流程如下:

整体代码实现如下,先判断是否为空链表,为空就直接在头节点之后添加,不为空就遍历找到最后一个节点,然后更改指针域内容,添加新节点

    //尾插法public void addLast(int data) {//当链表为空的时候,直接将节点插入到头节点的位置ListNode newNode = new ListNode(data);if (head == null) {head = newNode;}else{ListNode cur = head;while (cur.next != null){cur = cur.next;}//找到最后一个节点cur.next = newNode;//newNode.next = null;//默认新节点的指针域为空,所以这里可以不写这一行代码}}

指定位置插入

在中间位置插入是最麻烦的,原因就在于我们不能立马获取到想要插入位置的信息,我们需要先进行判断,如果输入位置是在最前面,那就可以使用头插,如果是最后就使用尾插。在得知输入位置在链表中间后,我们就需要先找到这个位置前后的节点的信息,如下图,假如我们要插入的位置是第三个位置,那就需要知道第二个位置和第三个位置的信息,当我们找到了后可以分俩布进行操作(顺序不能更改):

  1. 先让节点指向后面的节点
  2. 再让前面的节点指向插入节点

第一步,让插入节点指向后面的节点

第二步,将前面的节点指向插入的节点

我们可以通过代码来实现这段过程,先是进行合法性的判断,然后是针对性的插入

    //指定位置添加public void addIndex(int index, int data) {if(index < 0 || index > size()) {//这里不一定非要抛出自定义异常,大家可以更具喜好自行设置throw new IndexException("index不合法: "+index);}//如果输入的位置在最前面就进行头插if (index == 0)addFirst(data);//如果输入的位置在链表最后就进行尾插if (index == size())addLast(data);//输入位置在中间,就先找到这个节点的位置ListNode cur = searchPrevIndex(index);ListNode newNode = new ListNode(data);//这俩步是顺序非常重要newNode.next = cur.next;cur.next = newNode;}//找到位置对应的节点private ListNode searchPrevIndex(int index) {ListNode cur = head;int count = 0;while (count != index-2) {cur = cur.next;count++;}return cur;}

节点的删除

对于节点是删除相当于插入简单了很多,我们依旧是分为俩种方式进行删除,一种是只删除第一次出现的节点,另一种是删除全部想要删除的节点。

删除第一次出现的关键字节点

我们依旧是用初始的链表进行举例,假如我们想要删除第三个节点

第一步,我们直接更改要删除节点的前面节点的指针域,让它指向要删除的节点后的节点

第二步,我们将要删除的节点的指针域置为空

这俩步的顺序同样也不能错,因为一旦我们先将要删除的节点的指针域置为空,我们就无法再找到后面的节点了,链表就相当于断开了

我们封装一个函数用来找到要删除节点的前一个节点,然后通过它再删除目标节点

    //删除第一个关键字public void remove(int key) {if (head == null)return;if (head.val == key){head = head.next;return;}//查找val等于key的节点ListNode cur = findKey(key);if (cur == null){System.out.println("查无此元素,无法删除");return;}ListNode delNode = cur.next;cur.next = delNode.next;//cur.next =cur.next.next;}//找到要删除的元素的前一个节点private ListNode findKey(int key){ListNode cur = head;while (cur.next != null){if (cur.next.val != key) {cur = cur.next;}else{return cur;}}return null;}

删除所有关键字节点

与刚才不同的是,删除一个节点是先找到前驱节点,然后通过这个前驱节点进行操作,而要删除所有的关键字节点,则是对整个链表进行遍历,一旦是关键字,那我们就进行覆盖删除,这里就不再画图了,毕竟整个流程相当于多执行几次单个删除操作

    //删除所有的关键字public void removeAllKey(int key) {if(head == null) {return;}ListNode prev = head;ListNode cur = head.next;while (cur != null) {if(cur.val == key) {prev.next = cur.next;cur = cur.next;}else {prev = cur;cur = cur.next;}}//除了头节点都删除完成了if(head.val == key) {head = head.next;}}

节点的查找

节点的查找就是遍历整个链表,如果找到就返回true,没有找到就返回false

    //查找是否存在public boolean contains(int key) {ListNode cur = head;while (cur != null){if (cur.val == key)return true;cur = cur.next;}return false;}

链表的清空

当链表的头节点为空,我们就视为链表被清空了

    //清空链表public void clear() {head = null;}

链表的长度

遍历整个链表,使用计算器进行累加记录节点个数,然后返回就可以

    //求链表的长度public int size() {int count =0;ListNode cur = head;while (cur != null){count++;cur = cur.next;}return count;}



  本次的分享就到此为止了,希望我的分享能给您带来帮助,也欢迎大家三连支持,你们的点赞就是博主更新最大的动力!如有不同意见,欢迎评论区积极讨论交流,让我们一起学习进步!有相关问题也可以私信博主,评论区和私信都会认真查看的,我们下次再见

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

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

相关文章

K8s 中 Pod OOMKilled 原因

目录 Exit Code 137 解决方案 JVM 感知 cgroup 限制 使用 JDK9 的容器感知机制尝试 问题分析 容器内部感知 CGroup 资源限制 在 Java10 中&#xff0c;改进了容器集成 JVM 参数 MaxDirectMemorySize -XX:MaxDirectMemorySize 的默认值是什么&#xff1f; 其他获取 ma…

SQL server 2016安装

1、关系数据库的基本概念。 行&#xff1a;每行成为一条“记录”或“元组”&#xff0c;用于描述一个对象的信息。 列&#xff1a;每列称为一个“字段”或“属性”&#xff0c;用于描述对象的一个属性。 2、主键与外键。 主键&#xff1a;键&#xff0c;即关键字。主键由一个或…

【高效开发工具系列】驼峰下划线互转

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

微信小程序自定义tabBar简易实现

文章目录 1.app.json设置custom为true开启自定义2.根目录创建自定义的tab文件3.app.js全局封装一个设置tabbar选中的方法4.在onshow中使用选中方法最终效果预览 1.app.json设置custom为true开启自定义 2.根目录创建自定义的tab文件 index.wxml <view class"tab-bar&quo…

SQL Server 2016(创建数据表)

1、需求描述。 在名为“class”的数据库中创建表&#xff0c;表名称为“course”&#xff0c;其中要包含序号、课程、课程编号、学分、任课教师、上课地点、开始时间、结束时间、备注等列。 设置各个字段的数据类型。其中&#xff0c;"序号"列为标识列&#xff0c;从…

scrapy介绍,并创建第一个项目

一、scrapy简介 scrapy的概念 Scrapy是一个Python编写的开源网络爬虫框架。它是一个被设计用于爬取网络数据、提取结构性数据的框架。 Scrapy 使用了Twisted异步网络框架&#xff0c;可以加快我们的下载速度。 Scrapy文档地址&#xff1a;http://scrapy-chs.readthedocs.io/z…

如果你想成为一名提示词工程师(Prompt Engineer),这款工具你不能错过

我的新书《Android App开发入门与实战》已于2020年8月由人民邮电出版社出版&#xff0c;欢迎购买。点击进入详情 前言 我们知道&#xff0c;如果想要通过AI得到更好更精确的答案&#xff0c;那么提示词Prompt的好坏至关重要。 因此&#xff0c;提示词工程师这个岗位应运而出。…

优化问题,详解静态优化

优化问题&#xff0c;尤其静态优化问题&#xff0c;在控制系统设计中随处可见&#xff0c;例如基于燃油经济性和驾驶体验的多目标优化的汽车发动机 MAP 标定&#xff0c;基于性能指标优化的飞行器结构设计参数优化&#xff0c;以实验数据与模型输出匹配为目标的电池 RC 等效电路…

创建腾讯云存储桶---上传图片--使用cos-sdk完成上传

创建腾讯云存储桶—上传图片 注册腾讯云账号https://cloud.tencent.com/login 登录成功&#xff0c;选择右边的控制台 点击云产品&#xff0c;选择对象存储 创建存储桶 填写名称&#xff0c;选择公有读&#xff0c;私有写一直下一步&#xff0c;到创建 选择安全管理&#…

TCP三次握手过程

什么是TCP tcp是一个面向连接的、可靠的、基于字节流的传输层通信协议 面向连接&#xff1a;TCP连接是一对一的&#xff0c;不能实现一对多或多对一&#xff0c;TCP在通信前要首先建立连接&#xff0c;连接成功后才能开始进行通信可靠的&#xff1a;TCP连接要保证通信过程的可靠…

php5构造无字母数字的webshell实现任意命令执行

目录 引言 如果是在php7 如果是在php5 现在我们来上传文件 最后的结果&#xff1a; 看本篇前可以先看这一篇&#xff1a;利用异或、取反、自增bypass_webshell_waf-CSDN博客 引言 上一篇介绍了如何构造出一个无字母数字的webshell&#xff0c;但是如果后端的代码变成了这…

校园门禁可视化系统解决方案

随着科技的持续进步&#xff0c;数字化校园在教育领域中的地位日益上升&#xff0c;各种智能门禁、安防摄像头等已遍布校园各个地方&#xff0c;为师生提供安全便捷的通行体验。然而数据收集分散、缺乏管理、分析困难等问题也逐渐出现&#xff0c;在这个数字化环境中&#xff0…

ZKP11.4 Use CI to instantiate Fiat-Shamir

ZKP学习笔记 ZK-Learning MOOC课程笔记 Lecture 11: From Practice to Theory (Guest Lecturer: Alex Lombardi) 11.4 Use CI to instantiate Fiat-Shamir Avoid Bad Challenges Def: Given false claim x x x and a first message α \alpha α, a challenge β \beta …

Selenium+Python自动化测试之验证码处理

两种方式&#xff1a; 验证码识别技术 (很难达到100%) 添加Cookie &#xff08;*****五星推荐&#xff09; 方式一&#xff1a;验证码识别技术 逻辑方式&#xff1a; 1&#xff1a;打开验证码所在页面&#xff0c;截图。获取验证码元素坐标&#xff0c;剪切出验证码图片&…

内存免杀--

通过分析Ekko项目了解内存加密过程&#xff0c;这对对抗内存扫描来说很重要。 概述 Edr会扫描程序的内存空间&#xff0c;检测是否存在恶意软件&#xff0c;这种检测恶意软件的方式&#xff0c;应该和静态检测没什么区别&#xff0c;只不过一个扫描的对象是硬盘&#xff0c;一…

flutter 自定义TabBar 【top 0 级别】

flutter 自定义TabBar 【top 0 级别】 前言一、基础widget二、tab 标签三、barView总结 前言 在日常开发中&#xff0c;tab 标签选项&#xff0c;是一个我们特别常用的一个组件了&#xff0c;往往我们在一个项目中&#xff0c;有很多地方会使用到它&#xff0c;每次单独去写&am…

vue 中 mixin 和 mixins 区别

目录 前言 用法 全局Mixin 局部Mixin 代码 理解 高质量的Mixin使用 在Vue.js框架中&#xff0c;Mixin是一种非常重要和强大的功能&#xff0c;它允许开发者创建可复用的代码片段&#xff0c;并将其应用到一个或多个组件中。Vue提供了两种方式来使用Mixin&#xff0c;分别…

Mybatis相关API(Sqlsession和sqlsessionFactroy)

代码 private static SqlSessionFactory sqlSessionFactory;static { ​try { // 获得核心配置文件String resource "mybits-config.xml"; // 加载核心配置文件InputStream inputStream Resources.getResourceAsStream(resource…

MATLAB 和 Simulink 官方文档下载地址

MATLAB 官方文档中文版下载网址&#xff1a; https://ww2.mathworks.cn/help/pdf_doc/matlab/index.html 如图&#xff1a; MATLAB 官方文档英文版下载网址&#xff1a; https://ww2.mathworks.cn/help/pdf_doc/matlab/index.html?langen 如图&#xff1a; Simulink 官…

Oracle(2-7)Instance and Media Recovery Structures

文章目录 一、基础知识1、体系结构详解2、Database Files 数据库文件3、Database Other Files 其他数据文件4、Dynamic Views 动态视图5、Large Pool6、DB Buffer Cache,DBWn7、Configuring Tablespaces 配置表空间8、Redo Log Buffer, LGWR9、Database Checkpoints 数据库检查…