单链表的模拟实现

单链表的模拟实现

  • 一:单链表的概念:
  • 二:单链表中的方法:
    • 1:得到单链表的长度
    • 2:查找是否包含关键字key是否在单链表当中
    • 3:打印单链表中的数据:display()
    • 3: 头插法
    • 4:尾插法
    • 5:任意位置插入:
    • 6:删除第一次出现关键字为key的节点
    • 6:删除所有值为key的节点

一:单链表的概念:

单链表是一种在内存上不连续,而逻辑上连续的一种线性表。
单链表是由若干个节点和头节点组成的数据结构;
每个节点又分为数值域和next域:
数值域用来存储数据;
next域用来存储下一个节点的地址;

下图就是一个节点:
在这里插入图片描述
链表由若干个节点组成:
在这里插入图片描述

二:单链表中的方法:

// 1、无头单向非循环链表实现
public interface IList {//头插法public void addFirst(int data);//尾插法public void addLast(int data);//任意位置插入,第一个数据节点为0号下标public void addIndex(int index,int data);//查找是否包含关键字key是否在单链表当中public boolean contains(int key);//删除第一次出现关键字为key的节点public void remove(int key);//删除所有值为key的节点public void removeAllKey(int key);//得到单链表的长度public int size();//打印单链表public void display();//清空单链表public void clear();
}

我们将模拟实现这些方法。

1:得到单链表的长度

public int size();

模拟实现:
定义一个变量count,用来计数;
这里我们采取遍历头结点的方法来获取长度:
当头节点不为空的时候,我们就让count++;

 public int size() {ListNode cur=head;int count=0;while(cur!=null){count++;cur=cur.next;//cur指向下一个节点}return count;}

2:查找是否包含关键字key是否在单链表当中

  public boolean contains(int key);

总体思路还是遍历链表节点中的数据,如果找到了返回true;如果链表遍历完了,仍没有找到,返回false。

public boolean contains(int key) {ListNode cur=head;while(cur!=null){if(cur.val==key){return true;}cur=cur.next;}return false;}

可能有人会想到:如果单链表为空呢?
上面的代码也是没问题的,因为单链表为空,不会进入循环,会返回false的。

3:打印单链表中的数据:display()

@Overridepublic void display() {ListNode cur=head;while(cur!=null){System.out.print(cur.val+" ");cur=cur.next;}System.out.println();}

3: 头插法

将一个节点放在头结点的位置:
在这里插入图片描述头插:在这里我们只需要将node指向他的下一个节点,然后再让头节点更新数据:
看到上图:可能有小伙伴和我有一样的疑问,为什么插入数据的时候,要先绑定后面的数据呢?
这是因为

head=node;
node.next=head;

具体代码实现:
当先更新head的指向时,这时,还没有修改node 的指向,那么原来head指向的节点就没有被指向了,这是它就会被回收!

  public void addFirst(int data) {ListNode node =new ListNode(data);//实例化一个单链表if(head==null){head=node;//如果单链表为空,插入的节点就是头结点}else{//node节点的next指向head;node.next=head;head=node;//node变成头节点}}

测试一下:

public class Test {public static void main(String[] args) {SingleLinkedList singleLinkedList=new SingleLinkedList();singleLinkedList.addFirst(1);singleLinkedList.addFirst(2);singleLinkedList.addFirst(3);singleLinkedList.addFirst(4);singleLinkedList.display();}
}

在这里插入图片描述

4:尾插法

在这里我们将最后一个节点的next域指向node即可!
head是指向头结点的,那么我们如何获得最后一个节点,进而修改它的next域呢?
很简单,我们看最后一个节点的特点:它的next域为null;那么我们只需要让cur节点从头结点往后移动,当cur.next==null时,说明cur节点指向最后一个节点

 public void addLast(int data) {ListNode node =new ListNode(data);if(head==null){head=node;}else {ListNode cur = head;while (cur.next != null) {cur = cur.next;}//此时cur指向最后一个节点cur.next = node;}}

测试一下:

public class Test{public static void main(String[] args) {SingleLinkedList singleLinkedList=new SingleLinkedList();singleLinkedList.addLast(1);singleLinkedList.addLast(2);singleLinkedList.addLast(3);singleLinkedList.addLast(4);singleLinkedList.display();}
}

在这里插入图片描述

5:任意位置插入:

在任意位置插入:我们首先要判断插入的位置是否有效;
然后判断单链表是否为空;
在根据插入的位置:
(1)index=0:往第一个节点也就是0下标的位置插入数据,也就是头插法;
(2)index=size():往最后一个位置插入数据,也就是尾插法
(3)其他情况下:
index就是插入中间数据:因为要修改节点的指向,我们需要让index的前一个位置(cur)的next域指向index节点,让index处的节点指向cur的下一个节点
在这里插入图片描述
代码实现:

public void addIndex(int index, int data) {if(index<0||index>size()){//判断index是否有效throw new IndexException("index越界"+index);}ListNode node =new ListNode(data);if(head == null) {//判断链表是否为空head = node;return;}if(index==0){//头插addFirst(data);return;}if(index==size()){//尾插addLast(data);return;}//中间插入ListNode cur=searchPrevIndex(index);//cur指向index下标的前一个节点ListNode curNext=cur.next;cur.next=node;node.next=curNext;}private ListNode searchPrevIndex(int index) {ListNode cur=head;int count=0;while(count!=index-1){count++;cur=cur.next;}return cur;}@Overridepublic boolean contains(int key) {ListNode cur=head;while(cur!=null){if(cur.val==key){return true;}cur=cur.next;}return false;}

测试一下:

public class Test{public static void main(String[] args) {SingleLinkedList singleLinkedList=new SingleLinkedList();singleLinkedList.addLast(1);singleLinkedList.addLast(2);singleLinkedList.addLast(3);singleLinkedList.addLast(4);singleLinkedList.display();System.out.println("===========================");singleLinkedList.addIndex(0,10);singleLinkedList.display();System.out.println("=================");singleLinkedList.addIndex(4,22);singleLinkedList.display();System.out.println("=================");singleLinkedList.addIndex(1,100);singleLinkedList.display();}
}

6:删除第一次出现关键字为key的节点

在这里定义一个cur指针用来表示要删除节点的头节点,

在这里插入图片描述

 public void remove(int key) {if(head==null){return;}if(head.val==key){head=head.next;return;}ListNode cur=searchPrevRemove(key);if(cur==null){return;}ListNode del=cur.next;cur.next=del.next;}private ListNode searchPrevRemove(int key){ListNode cur=head;while(cur.next!=null){if(cur.next.val==key){return cur;}cur=cur.next;}return null;}@Overridepublic void removeAllKey(int key) {}@Overridepublic int size() {ListNode cur=head;int count=0;while(cur!=null){count++;cur=cur.next;//cur指向下一个节点}return count;}@Overridepublic void display() {ListNode cur=head;while(cur!=null){System.out.print(cur.val+" ");cur=cur.next;}System.out.println();}@Overridepublic void clear() {}
}

测试一下:

public class Test{public static void main(String[] args) {SingleLinkedList singleLinkedList=new SingleLinkedList();singleLinkedList.addLast(1);singleLinkedList.addLast(2);singleLinkedList.addLast(3);singleLinkedList.addLast(4);singleLinkedList.addLast(5);singleLinkedList.display();singleLinkedList.remove(1);singleLinkedList.display();System.out.println("=============");singleLinkedList.remove(5);singleLinkedList.display();System.out.println("===============");singleLinkedList.remove(3);singleLinkedList.display();}
}

在这里插入图片描述

6:删除所有值为key的节点

定义两个指针:
prev表示可能要删除节点的前一个节点
cur表示要删除的节点。
我们在这里从第二个节点开始遍历,如果cur是要删除的节点,让prev.next=cur.next,也就是让prev指向下一个节点,prev是可能要删除的节点的前一个节点,当cur被删除后,prev仍然是cur下一个节点的前一个节点,所以cur被删除后,prev不能移动。
如果cur节点没有被删除,说明cur不是要被删除的节点,prev要移动到这个cur节点。
为什么此时prev移动呢?
cur节点没有被删除,说明可能删除节点的前一个节点就是cur节点了;判断cur移动到的下一个节点是否要被删除,prev表示可能要删除节点的前一个节点,所以当cur不被删除时,prev要移动

在这里插入图片描述

    public void removeAllKey(int key) {if(head==null){return;//单链表为空,直接返回}ListNode cur=head.next;//从第二个节点判断是否等于keyListNode prev=head;while(cur!=null){if(cur.val==key){prev.next=cur.next;cur=cur.next;}else{prev=cur;cur=cur.next;}}if(head.val==key){//判断头节点是否==keyhead=head.next;}}

测试一下:

public class Test{public static void main(String[] args) {SingleLinkedList singleLinkedList=new SingleLinkedList();singleLinkedList.addLast(1);singleLinkedList.addLast(2);singleLinkedList.addLast(6);singleLinkedList.addLast(3);singleLinkedList.addLast(4);singleLinkedList.addLast(5);singleLinkedList.addLast(6);singleLinkedList.display();System.out.println("==========================");singleLinkedList.removeAllKey(6);singleLinkedList.display();}
}

在这里插入图片描述

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

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

相关文章

WPF实现文字纵向排布的TabItem

文章目录 基本用法文字竖排显示 WPF布局 基本用法 WPF中的TabControl是一个容器控件&#xff0c;用于在单个窗体或页面中承载多个选项卡。每个选项卡可以包含不同的控件&#xff0c;用于显示不同的内容&#xff0c;其最简单的调用方法如下&#xff0c;只需在TabControl中无脑…

1.3 Linux文件系统

一、Linux文件系统结构 Linux下都是文件&#xff0c;所以没有Windows一样的盘&#xff0c;有的只有文件夹。 cd /    // 进入根目录 ls     // 查看根目录"/"下的文件及文件夹 /bin    &#xff1a;存储了很多系统命令&#xff0c; /usr/sbin 也存储了…

未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序报错的解决办法

当在本地计算机上使用Microsoft Office相关库时&#xff0c;可能会出现“未在本地计算机上注册microsoft.ACE.oledb.12.0”提供程序的报错。这是由于缺少相关的驱动程序或者未安装相应的软件所导致的。下面是解决该问题的完整攻略。 可能是因为没有安装数据访问组件&#xff0…

[蓝桥杯 2019 省 B] 特别数的和-C语言的解法

小明对数位中含有 2、0、1、9 的数字很感兴趣&#xff08;不包括前导 0&#xff09;&#xff0c;在 1 到 40 中这样的数包括 1、2、9、10 至 32、39 和 40&#xff0c;共 28 个&#xff0c;他们的和是 574。 请问&#xff0c;在 1 到 n 中&#xff0c;所有这样的数的和是多少&…

极智一周 | AI 算力国产化、MR、Cybertruck、华为造车、登月“造假“ And so on

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多技术分享 大家好&#xff0c;我是极智视界&#xff0c;带来本周的 [极智一周]&#xff0c;关键词&#xff1a;AI 算力国产化、MR、Cyberturck、华为造车、登月"造假" And so on。 邀您加入我的知识星球「极智…

蓝桥杯第1037题子串分值和 C++ 字符串 逆向思维 巧解

题目 思路和解题方法 方案一——遍历哈希表 仅能过60%样例,大多数同学都用的该方法&#xff0c;就不过多赘述 #include <iostream> #include <unordered_map> using namespace std; int main() {string s;cin >> s;int n s.size();int res n;for (int i 0…

各类声音数据集大合集—乐器、车辆、鸟鸣、蜜蜂声音、歌曲、喇叭、人类声音不同等类型的声音数据集

最近收集了一大波关于各类声音的数据集&#xff0c;包含乐器、车辆、鸟鸣、蜜蜂声音、歌曲、喇叭、人类声音不同等类型的声音数据集&#xff0c;废话不多说&#xff0c;给大家逐一介绍&#xff01;&#xff01; 1、吉他和弦大调、小调数据集 吉他和弦大调、小调数据集&#x…

Vue基础知识点梳理

在Vue中&#xff0c;被用来响应地更新HTML属性的指令是v-model页面挂载成功之后会触发哪一个钩子函数mounted挂载之后会进行页面的渲染v-on是动作元素不属于条件渲染指令 在Vue中&#xff0c;下列关于Vue实例对象说法不正确的是&#xff08;&#xff09;。A.Vue实例对象是通过n…

Linux docker批量安装软件

1.前提 具备docker-compose.yml 和 prometheus.yml 文件 常见报错&#xff1a; 1.没有配置network 配置network即可&#xff1a; 2.缺少相关依赖 docker-compose.yml加入相关配置 3.重复项 删除掉重复的 最后 执行 等待完成 下载后相当于有了这些软件包的镜像 启动的每…

思维模型 同体效应

本系列文章 主要是 分享 思维模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。我们是自己人。 1 同体效应的应用 1.1 同体效应在市场营销上的应用-耐克的“Just Do It”营销活动 耐克是一家全球知名的运动品牌&#xff0c;其“Just Do It”营销活动是市场营销领域的经…

深度学习常见回归分支算法逐步分析,各种回归之间的优缺点,适用场景,举例演示

文章目录 1、线性回归&#xff08;Linear Regression&#xff09;1.1 优点1.2 缺点1.3 适用场景1.4 图例说明 2、多项式回归&#xff08;Polynomial Regression&#xff09;2.1 优点2.2 缺点2.3 适用场景2.4 图例说明 3、决策树回归&#xff08;Decision Tree Regression&#…

Beta冲刺随笔-DAY6-橘色肥猫

这个作业属于哪个课程软件工程A这个作业要求在哪里团队作业–站立式会议Beta冲刺作业目标记录Beta冲刺Day6团队名称橘色肥猫团队置顶集合随笔链接Beta冲刺笔记-置顶-橘色肥猫-CSDN博客 文章目录 SCRUM部分站立式会议照片成员描述 PM报告项目程序&#xff0f;模块的最新运行图片…

制作一个RISC-V的操作系统二-RISC-V ISA介绍

文章目录 ISA的基本介绍啥是ISA为什么要设计ISACISCvsRISCISA的宽度知名ISA介绍 RISC-V历史和特点RISC-V发展RISC-V ISA 命名规范模块化的ISA通用寄存器Hart特权级别Control and Status Register&#xff08;CSR&#xff09;内存管理与保护异常和中断 ISA的基本介绍 啥是ISA …

【UE】UEC++获取屏幕颜色GetPixelFromCursorPosition()

目录 【UE】UE C 获取屏幕颜色GetPixelFromCursorPosition() 一、函数声明与定义 二、函数的调用 三、运行结果 【UE】UE C 获取屏幕颜色GetPixelFromCursorPosition() 一、函数声明与定义 创建一个蓝图方法库方法 GetPixelFromCursorPosition()&#xff0c;并给他指定UF…

【MATLAB】RLMD分解+FFT+HHT组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 RLMD分解FFTHHT组合算法是一种强大的分析方法&#xff0c;结合了局部均值分解&#xff08;LMD&#xff09;、快速傅里叶变换&#xff08;FFT&#xff09;和希尔伯特-黄变换&#xff08;H…

WIN10 WIN11 关闭更新的绝佳办法(极简单无副作用)

WIN10 WIN11 关闭更新的绝佳办法&#xff08;极简单无副作用&#xff09; 极其简单用实用可以关闭更新20年 winr&#xff0c;输入regedit 打开注册表打开注册表的这个路径&#xff1a; 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 右键空白的地方…

图文深入理解TCP三次握手

前言 TCP三次握手和四次挥手是面试题的热门考点&#xff0c;它们分别对应TCP的连接和释放过程&#xff0c;今天我们先来认识一下TCP三次握手过程&#xff0c;以及是否可以使用“两报文握手”建立连接&#xff1f;。 1、TCP是什么&#xff1f; TCP是面向连接的协议&#xff0c;…

QT 中使用 QTableView 和 QStandardItemModel 实现将数据导出到Excel 和 从Excel导入到 QTableView 的功能

简介 在Qt中&#xff0c;使用QTableView和QStandardItemModel来实现将数据导出到Excel和从Excel导入到QTableView的功能&#xff0c;而不使用第三方库&#xff08;如QXlsx&#xff09;。 效果 将 QTableView 中的数据导出到Excel //从tableview 导出到 EXcle void MainInterfa…

Vulhub-信息泄露

1.Jetty WEB-INF 敏感信息泄露漏洞&#xff08;CVE-2021-28164&#xff09; docker-compose up -d 启动环境&#xff0c;显示8080端口被占用 修改 docker-compose.yml 中的映射端口 curl 访问 http://192.168.48.129:8090/WEB-INF/web.xml 显示404&#xff1a; 通过 %2e 绕过…

STlink下载程序不能复位的说明

STLINK在MDK5.28或其他版本中下载程序后不能复位&#xff0c;需要手动按复位键&#xff0c;MCU 才正常运行。 首先判断是不是该MDK版本的问题&#xff0c;按照以下进行 点击魔法棒 点击Debug&#xff0c;Settings 勾选Reset and Run 如果还是不行&#xff0c;取消Enable…