LInkedList的模拟实现
在之前的文章笔者介绍了链表的实现:无头单向非循环链表的实现!感兴趣的各位老铁可以点进来看看:https://blog.csdn.net/weixin_64308540/article/details/128397961?spm=1001.2014.3001.5502
对于此篇博客,在一写出来,便引起了巨大反响!!那么后续来了!!今日,笔者来带领大家走进:LinkedList的模拟实现!(底层是双向链表结构)
LinkedList的底层是一个双向链表结构,由于链表没有将元素存储在连续的空间中,元素存储在单独的节点中,然后通过引用将节点连接起来了,因此,在任意位置插入或者删除元素时,不需要搬移元素,因此,效率比较高!!

我们来看一下实现的主要代码:
总体的方法:
public class MyLinkdeList {
//无头双向链表的实现
//头插法
public void addFrist(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(){
}
}
那么接下来就跟着笔者的思路,来实现这些方法吧!!
实现该方法之前的准备!每个节点所必须的东西!!
static class ListNode{
public int val;
public ListNode prev;//前驱
public ListNode next;//后继
//重写构造方法
public ListNode (int val){
this.val=val;
}
}
在进行之前,我们还需要一个头节点和一个尾巴节点:
public ListNode head;//链表的头部
public ListNode last;//永远指向链表的最后一个节点
经过上述的准备,那么我们就可以安心实现上述的方法了!!
下面笔者便以下图的链表进行讲解:

- 打印链表:
//打印链表
public void display(){
ListNode cur=head;
while (cur !=null){
System.out.print(cur.val+" ");
cur=cur.next;
}
System.out.println();
}
很简单的一个代码,想必没有什么需要讲解的吧!!
2.得到链表的长度
//得到链表的长度
public int size(){
int len=0;
ListNode cur=head;
while (cur != null){
len++;
cur=cur.next;
}
return len;
}
这个就是在遍历链表的过程中,定义了一个len,每次进行++,从而得到链表的长度!
3.查找关键字key是否在链表当中
//查找关键字key是否在链表当中
public boolean contains(int key){
ListNode cur=head;
while (cur != null) {
if (cur.val == key){//找到的情况下
return true;
}
cur=cur.next;
}
return false;
}
这个思路很简单,遍历一遍链表,当有val的值等于key的时候,直接return true即可!!如果链表遍历完毕,没有值等于key那么最后return false就行了!
4.头插法
时间复杂度为O(1)
头插法,顾名思义就是插到头节点之前呗!!
//头插法
public void addFrist(int data){
//实列化一个新的节点
ListNode node =new ListNode(data);
if (head==null){
head=node;
last=node;
}else {//先绑后面
node.next=head;
head.prev=node;
head=node;//新的头节点
}
}
上述代码,我们可以从图中得出大致思路

5.尾插法
时间复杂度为O(1)
//尾插法
public void addLast(int data){
//实列化一个新的节点
ListNode node =new ListNode(data);
if (head==null){
head=node;
last=node;
}else {//先绑后面
last.next=node;
node.prev=last;
last=node;
}
}
其实尾插法跟头插法的情况差不多!!很类似!!

6。任意位置插入,第一个数据节点的下标为0
对于想要插入数据的下标,我们首先需要判断其合法性!!然后在判断是否为头插法或者尾插法!!最后在考虑在链表内部的插入!!由于该链表是双向的链表,那么,我们可以找到index位置所对应的节点!
//任意位置插入,第一个数据节点的下标为0
public void addIndex(int index,int data){
if(index <0 || index >size()){
System.out.println("输入的位置不合法,请重新确定想要插入的位置!");
}
if (index==0){//头插法
addFrist(data);
}
if (index==size()){//尾插法
addLast(data);
}
//此时的index就是真正需要插入的地方了!
//找到index位置的下标
ListNode cur=findIndex(index);
//实列化index位置处的data节点
ListNode node=new ListNode(data);
//开始插入
node.next=cur;
cur.prev.next=node;
node.prev=cur.prev;
cur.prev=node;
}
//找到index位置的下标
public ListNode findIndex(int index){
ListNode cur=head;
while (index !=0){
index--;
cur=cur.next;
}
return cur;
}
这个列子涉及很多分析地方!!所以需要珍惜一下!好好画图分析
7.删除第一次出现关键字为key的节点
对于该案列,我们需要找到想要删除的节点!若是头节点,我们应该怎么办??若是中间或者最后的节点,我们,又应该怎么办??这些都需要我们去认真思考!
//删除第一次出现关键字为key的节点
public void remove(int key){
ListNode cur=head;
while (cur !=null){
if (cur.val==key){
//删除的是头节点
if (cur==head){
head=head.next;
//只有一个节点
if (head !=null){
head.prev=null;
}
}else {
//中间 尾巴节点
cur.prev.next=cur.next;
//不是尾巴节点
if (cur.next !=null){
cur.next.prev=cur.prev;
}else {
//是尾巴节点
last=last.prev;
}
}
}
return;
}
cur=cur.next;
}
希望大家能够理性的分析!!
8.删除所有值为key的节点
对于这个案列,我们可以经过上面的简单改变一下就可以了!!
//删除所有值为key的节点
public void removeAllkey(int key){
ListNode cur=head;
while (cur !=null){
if (cur.val==key){
//删除的是头节点
if (cur==head){
head=head.next;
//只有一个节点
if (head !=null){
head.prev=null;
}
}else {
//中间 尾巴节点
cur.prev.next=cur.next;
//不是尾巴节点
if (cur.next !=null){
cur.next.prev=cur.prev;
}else {
//是尾巴节点
last=last.prev;
}
}
}
}
cur=cur.next;
}
9.清除所有节点
第一开始笔者的想法也是,直接:head==null, last==null但是,感觉这样写虽然是这个道理,却总感觉有点儿不得劲,所以最后决定,遍历一遍链表,将每个节点的prev与last全部都置为null!!
//清除所有节点
public void clear(){
while (head !=null){
head.prev=null;
head.next=null;
head=head.next;
}
head=null;
last=null;
}
经过上面的全部代码,笔者可算是将:LinkedList的模拟实现!(底层是双向链表结构)给整理完毕了!!不容易,下面请看笔者所整理的全部代码吧!!
public class MyLinkdeList {
//无头双向链表的实现
static class ListNode{
public int val;
public ListNode prev;//前驱
public ListNode next;//后继
//重写构造方法
public ListNode (int val){
this.val=val;
}
}
public ListNode head;//链表的头部
public ListNode last;//永远指向链表的最后一个节点
//头插法
public void addFrist(int data){
//实列化一个新的节点
ListNode node =new ListNode(data);
if (head==null){
head=node;
last=node;
}else {//先绑后面
node.next=head;
head.prev=node;
head=node;//新的头节点
}
}
//尾插法
public void addLast(int data){
//实列化一个新的节点
ListNode node =new ListNode(data);
if (head==null){
head=node;
last=node;
}else {//先绑后面
last.next=node;
node.prev=last;
last=node;
}
}
//任意位置插入,第一个数据节点的下标为0
public void addIndex(int index,int data){
if(index <0 || index >size()){
System.out.println("输入的位置不合法,请重新确定想要插入的位置!");
}
if (index==0){//头插法
addFrist(data);
}
if (index==size()){//尾插法
addLast(data);
}
//此时的index就是真正需要插入的地方了!
//找到index位置的下标
ListNode cur=findIndex(index);
//实列化index位置处的data节点
ListNode node=new ListNode(data);
//开始插入
node.next=cur;
cur.prev.next=node;
node.prev=cur.prev;
cur.prev=node;
}
//找到index位置的下标
public ListNode findIndex(int index){
ListNode cur=head;
while (index !=0){
index--;
cur=cur.next;
}
return cur;
}
//查找关键字key是否在链表当中
public boolean contains(int key){
ListNode cur=head;
while (cur != null) {
if (cur.val == key){//找到的情况下
return true;
}
cur=cur.next;
}
return false;
}
//删除第一次出现关键字为key的节点
public void remove(int key){
ListNode cur=head;
while (cur !=null){
if (cur.val==key){
//删除的是头节点
if (cur==head){
head=head.next;
//只有一个节点
if (head !=null){
head.prev=null;
}
}else {
//中间 尾巴节点
cur.prev.next=cur.next;
//不是尾巴节点
if (cur.next !=null){
cur.next.prev=cur.prev;
}else {
//是尾巴节点
last=last.prev;
}
}
}
return;
}
cur=cur.next;
}
//删除所有值为key的节点
public void removeAllkey(int key){
ListNode cur=head;
while (cur !=null){
if (cur.val==key){
//删除的是头节点
if (cur==head){
head=head.next;
//只有一个节点
if (head !=null){
head.prev=null;
}
}else {
//中间 尾巴节点
cur.prev.next=cur.next;
//不是尾巴节点
if (cur.next !=null){
cur.next.prev=cur.prev;
}else {
//是尾巴节点
last=last.prev;
}
}
}
}
cur=cur.next;
}
//得到链表的长度
public int size(){
int len=0;
ListNode cur=head;
while (cur != null){
len++;
cur=cur.next;
}
return len;
}
//打印链表
public void display(){
ListNode cur=head;
while (cur !=null){
System.out.print(cur.val+" ");
cur=cur.next;
}
System.out.println();
}
//清除所有节点
public void clear(){
while (head !=null){
head.prev=null;
head.next=null;
head=head.next;
}
head=null;
last=null;
}
}
相关文章
- Python循环部分学习总结
一、循环流程展示图: 以上是循环的一个简略图。 二、循环的类型 Python 提供了 for 循环和 while 循环(在 Python 中没有 do…while 循环) 1.while循环: 在给定的判断条件为 true 时执行循环体,否则退出循环体。 2.f…...
2023/3/26 19:25:57 - vim光速开发,你值得拥有
文章目录vim设计哲学vim的模式什么是可视模式光标移动动作(motion)操作符(operator)操作符(operator)动作(motion)实际使用大小写转换easymotionvim-surroundTIPSideavim的使用vim设计哲学 vim被称为编辑器之神。它的成名就是因为…...
2023/3/26 19:25:50 - 【软件分析第12讲-学习笔记】可满足性模理论 Satisfiability Modulo Theories
文章目录前言正文从SAT到SMTSMT历史z3求解器SMT求解命题逻辑、一阶逻辑和二阶逻辑小结参考文献前言 创作开始时间:2022年11月16日16:18:59 如题,学习一下可满足性模理论 Satisfiability Modulo Theories的相关知识。参考:熊英飞老师2018《软…...
2023/3/26 19:25:05 - 如何快速提升教育直播间人气
直播已经成为当下各企业标配的销售方式,对于教育企业也是如此,但要想把直播做好,最重要一点就是提升直播间人气,人气越高:直播间的互动就越频繁,氛围就越好,也能为品牌带来更多新粉,…...
2023/3/26 19:24:27 - Elasticsearch处理表关联关系的N种方式
Elasticsearch处理表关联关系是比较复杂的问题,处理不好会出现性能问题、数据一致性问题等; 今天我们特意分享一下几种方式,对象类型(宽表)、嵌套类型、父子关联关系、应用端关联,每种方式都有特定的业务需…...
2023/3/26 19:24:00 - 【C++】简述STL——string类的使用
文章目录一、STL的简述1.STL的框架2.STL版本二、编码铺垫三、string类四、常见构造五、operator[]六、访问及遍历七、iterator迭代器1.正向迭代器2.反向迭代器3.const迭代器八、Capacity容量操作1.常用接口2.扩容问题九、Modifiers修改操作十、非成员函数重载十一、总结一、STL…...
2023/3/26 19:23:49 - 毕业设计-基于机器视觉的银行卡号识别系统
目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科…...
2023/3/26 19:23:42 - java架构百度云视频_史上最牛44套Java架构师视频教程合集
视频课程包含:44套包含:架构师,高级课,微服务,微信支付宝支付,公众号开发,jA危a8新特忄生,P2P金融项目,程序设计,功能设计,数据库设计,…...
2023/3/26 19:23:39 - java-net-php-python-java西藏文库计算机毕业设计程序
java-net-php-python-java西藏文库计算机毕业设计程序 java-net-php-python-java西藏文库计算机毕业设计程序本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术:Layui、HTML、CSS…...
2023/3/26 19:22:38 - python数据分析及可视化(十四)数据分析可视化练习-上市公司可视化数据分析、黑色星期五案例分析
上市公司数据分析 从中商情报网下载的数据,表格中会存在很多的问题,查看数据的信息有无缺失,然后做数据的清晰,有无重复值,异常数据,省份和城市的列名称和数据是不对照的,删除掉一些不需要的数…...
2023/3/26 19:22:35 - 猿如意使用测评
本篇博客会记录使用猿如意这款产品的整体使用感受和相关建议,可以作为新人上手这款产品的参考 1. 猿如意的官方介绍 首先是官方对这款产品的介绍 猿如意是一款面向开发者的辅助开发工具箱,包含了效率工具、开发工具下载,教程文档࿰…...
2023/3/26 19:22:06 - 30分钟你也能搭建一个vue3.2+vite+pinia+Ts+element plus+axios的后台管理系统
demo demo预览 最下面有相关文档链接, 此文章提供大致步骤与部分封装 开始 第一步初始化项目 //初始化项目 1、npm init vuelatest 2、选装 (空格输入yes或者no, 一路yes即可)// 初始化包 3、npm install //运行 4、npm run dev//安装axios 5、npm install axios -D//安装…...
2023/3/26 19:21:13 - Appium自动化测试<三>
本文接着Appium自动化测试<二> 写:文章戳这里 一、Appium 元素定位方式 需要导入的库:from appium.webdriver.common.appiumby import AppiumBy 常用的元素定位方式: 1. id 定位元素2. class_name 定位元素3. con…...
2023/3/26 19:21:13 - 【python中级】Pillow包在图像中绘制中文
【python中级】Pillow包在图像中绘制中文 1、背景2、python图像中绘制中文3、下载1、背景 opencv-python到目前为止,还不支持在图像中绘制中文。 目标检测类项目一些场景需要在界面上绘制文字信息,而中文的显示需求很大。 目前使用python语言还不能在图像中高效率的绘制中文…...
2023/3/26 19:21:01 - MongoDB(4.0.9)数据从win迁移到linux
服务器从win迁移导了linux上了,对应的md里面的数据也需要做全量迁移,在网上找了一大堆方案,不是缺胳膊就是少腿,没有一个是完整的,最终加以分析和整理,得出这套方案,希望对你有用 第一步&#…...
2023/3/26 19:21:00 - 第二十二章 alibaba sentinel详解-sentinel持久化
将sentinel中的配置进行持久化到nacos中。对sentinel中的配置进行持久化需要两步 第一步:引入依赖 <!-- 引入 sentinel 持久化到 nacos 中的依赖 --><dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasourc…...
2023/3/26 19:20:31 - 实战:获取33种生活指数
需求:由于某用户需要生活指数内容,原来的爬取通道停服了,提出相关功能 步骤一:查找数据源 用一下万能的百度,搜索到数据源,展示了八种 步骤二:数据分析 打开调试页面,先看是否有接口,如果没有接口,查看是否是直接渲染到页面里了,如果没有渲染到页面里,看看是否是…...
2023/3/26 19:20:22 - java-php-python-ssm幼儿园管理系统计算机毕业设计
java-php-python-ssm幼儿园管理系统计算机毕业设计 java-php-python-ssm幼儿园管理系统计算机毕业设计本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术:Layui、HTML、CSS、JS、…...
2023/3/26 19:19:50 - sql怎么发音mysql_[原创]SQL发音考证(搜寻SQL-86标准)
据我观察,中国的开发者创造了一种独特的SQL发音:/sɜːkl/,既好听,又好读,挺好的。但是今年我开始做数据库相关的工作,作为一个专业人士,决定对SQL发音进行一些考证。直接说结论吧,很…...
2023/3/26 19:19:44 - 基于高精度单片机开发红外测温仪方案
红外人体测温仪是一种利用红外线照射的测温设备,在此之前,红外测温都是作为工厂生产的用的,用来检测产品的温度,和监测设备的运行发热状态。逐渐的人们突发奇想,转变用于人体测温,来规避人员之间身体直接接…...
2023/3/26 19:19:42
最新文章
- LInkedList的模拟实现
在之前的文章笔者介绍了链表的实现:无头单向非循环链表的实现!感兴趣的各位老铁可以点进来看看:https://blog.csdn.net/weixin_64308540/article/details/128397961?spm1001.2014.3001.5502对于此篇博客,在一写出来,便…...
2023/3/26 19:25:58 - Python循环部分学习总结
一、循环流程展示图: 以上是循环的一个简略图。 二、循环的类型 Python 提供了 for 循环和 while 循环(在 Python 中没有 do…while 循环) 1.while循环: 在给定的判断条件为 true 时执行循环体,否则退出循环体。 2.f…...
2023/3/26 19:25:57 - vim光速开发,你值得拥有
文章目录vim设计哲学vim的模式什么是可视模式光标移动动作(motion)操作符(operator)操作符(operator)动作(motion)实际使用大小写转换easymotionvim-surroundTIPSideavim的使用vim设计哲学 vim被称为编辑器之神。它的成名就是因为…...
2023/3/26 19:25:50 - 关于分布式的一些基础知识
1、分布式锁 (ngix,zoomkeeper,raft,kafka) 在单机场景下,可以使用语言的内置锁来实现进程或者线程同步。但是在分布式场景下,需要同步的进程可能位于不同的节点上,那么就需要使用分布式锁。 为了保证一个方法或属性在高并发情况下的同一时间…...
2023/3/26 19:25:38 - GPU服务器Ubuntu环境配置教程及各种踩坑
博主的GPU服务器快要过期了,为了让其发挥更多的光和热,博主打算将系统重装,来分别感受下不同系统下的GPU服务器。哈哈哈 博主为了快速运行项目,在购买服务器时选择的是Pytorch 1.9.1 Ubuntu 18.04 ,该系统下会帮我们安…...
2023/3/26 19:25:35 - Python-TCP网络编程基础以及客户端程序开发
文章目录一. 网络编程基础- 什么是IP地址?- 什么是端口和端口号?- TCP介绍- socket介绍二. TCP客户端程序开发三. 扩展一. 网络编程基础 - 什么是IP地址? IP地址就是标识网络中设备的一个地址 IP地址分为 IPv4 和 IPv6 IPv4使用十进制, IPv6使用十六进制 查看本机IP地址: l…...
2023/3/26 19:25:10 - Socket简单学习之UDP通信
UDP不可靠通信,不建立连接,只发送一次数据,不管对方是否接收服务器端using System; using System.Collections.Generic; using System.Linq; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading.Tasks;…...
2023/3/26 19:25:08 - 【软件分析第12讲-学习笔记】可满足性模理论 Satisfiability Modulo Theories
文章目录前言正文从SAT到SMTSMT历史z3求解器SMT求解命题逻辑、一阶逻辑和二阶逻辑小结参考文献前言 创作开始时间:2022年11月16日16:18:59 如题,学习一下可满足性模理论 Satisfiability Modulo Theories的相关知识。参考:熊英飞老师2018《软…...
2023/3/26 19:25:05 - 编程中常用的变量命名缩写查询表
原文链接:https://blog.csdn.net/qq_37851620/article/details/94731227 全称缩写翻译calculatecalc计算additionadd加subtractionsub减multiplicationmul乘法divisiondiv除法hexadecimalhex十六进制全称缩写翻译arrayarr数组、集合listlst列表SequenceseqSegment(…...
2023/3/26 19:24:57 - USBIP
USBIP USB/IP 是一个开源项目,已合入 Kernel,在 Linux 环境下可以通过使用 USB/IP 远程共享 USB 设备。 USB Client:使用USB的终端,将server共享的usb设备挂载到本地。 USB Server:分享本地的usb设备至远程。 USBIP…...
2023/3/26 19:24:54 - 如何快速提升教育直播间人气
直播已经成为当下各企业标配的销售方式,对于教育企业也是如此,但要想把直播做好,最重要一点就是提升直播间人气,人气越高:直播间的互动就越频繁,氛围就越好,也能为品牌带来更多新粉,…...
2023/3/26 19:24:27 - Elasticsearch处理表关联关系的N种方式
Elasticsearch处理表关联关系是比较复杂的问题,处理不好会出现性能问题、数据一致性问题等; 今天我们特意分享一下几种方式,对象类型(宽表)、嵌套类型、父子关联关系、应用端关联,每种方式都有特定的业务需…...
2023/3/26 19:24:00 - 【C++】简述STL——string类的使用
文章目录一、STL的简述1.STL的框架2.STL版本二、编码铺垫三、string类四、常见构造五、operator[]六、访问及遍历七、iterator迭代器1.正向迭代器2.反向迭代器3.const迭代器八、Capacity容量操作1.常用接口2.扩容问题九、Modifiers修改操作十、非成员函数重载十一、总结一、STL…...
2023/3/26 19:23:49 - 毕业设计-基于机器视觉的银行卡号识别系统
目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科…...
2023/3/26 19:23:42 - java架构百度云视频_史上最牛44套Java架构师视频教程合集
视频课程包含:44套包含:架构师,高级课,微服务,微信支付宝支付,公众号开发,jA危a8新特忄生,P2P金融项目,程序设计,功能设计,数据库设计,…...
2023/3/26 19:23:39 - java-net-php-python-java西藏文库计算机毕业设计程序
java-net-php-python-java西藏文库计算机毕业设计程序 java-net-php-python-java西藏文库计算机毕业设计程序本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术:Layui、HTML、CSS…...
2023/3/26 19:22:38 - 守护线程---多线程
什么叫做后台线程 如果当前线程是后台线程,那么就不会影响进程退出 如果线程不是后台线程,是前台线程,就会影响到线程退出 1)咱们的创建的Thread t1和Thread t2都默认是前台的线程,即使我们的main方法都执行完毕,进程…...
2023/3/26 19:22:36 - python数据分析及可视化(十四)数据分析可视化练习-上市公司可视化数据分析、黑色星期五案例分析
上市公司数据分析 从中商情报网下载的数据,表格中会存在很多的问题,查看数据的信息有无缺失,然后做数据的清晰,有无重复值,异常数据,省份和城市的列名称和数据是不对照的,删除掉一些不需要的数…...
2023/3/26 19:22:35 - 【云原生】k8s之HPA,命名空间资源限制
内容预知 1.HPA的相关知识 2.HPA的部署运用 2.1 进行HPA的部署设置 2.2 HPA伸缩的测试演示 (1)创建一个用于测试的pod资源 (2)创建HPA控制器,进行资源的限制,伸缩管理 (3)进入其中一个pod容器仲…...
2023/3/26 19:22:24 - 数据结构:第二章 线性表(顺序表)
音乐分享: Collapsing World 点击收听 基本知识点 1、顺序表的存储密度大、可以随机存取 2、插入操作的合法位置为0到n 3、插入运算的平均移动数据元素的次数是:n/2 推导:合法的插入位置有n1个 假设每个位置插入元素的概率都为:…...
2023/3/26 19:22:09