数据结构:链表(1)
顺序表的优缺点
缺点:
1.插入数据必须移动其他数据,最坏情况下,就是插入到0位置。时间复杂度O(N)
2.删除数据必须移动其他数据,最坏情况下,就是删除0位置。时间复杂度O(N)
3.扩容之后,有可能会浪费空间。
优点:
在给定下标进行查找的时候
总结:顺序表比较适合进行给定下路查找的场景
🆗链表可以完美解决顺序表的缺点
链表是什么?
一个链表其实就是一辆火车

火车的每个车厢相当于一个节点,链表节点长这样

其中,数据域存储数据
而火车之间要有挂钩链接,这就需要next域出马了,next读取下一个节点的地址并把它记录在next域里面,下面这个图也是单向链表,一条路走到黑

分类
有六种分类

常见的是红色圈起来的两个
带头的长啥样?头部存的数据是无效的,跟这个链表没有关系,这个头节点的值永远不会改变

循环的?

双向的?两边都能走

链表结构特点:物理上不一定是连续的,但逻辑上是连续的
单向链表
手搓一个
初始化
实现方法有下面这些
//IList.java 接口
public interface IList {//头插法void addFirst(int data);//尾插法void addLast(int data);//任意位置插入,第一个数据节点为0号下标void addIndex(int index,int data);//查找是否包含关键字key是否在单链表当中boolean contains(int key);//删除第一次出现关键字为key的节点void remove(int key);//删除所有值为key的节点void removeAllKey(int key);//得到单链表的长度int size();void clear();void display();
}
再新建一个模块重写这些方法
public class MySingleList implements IList{@Overridepublic void addFirst(int data) {}@Overridepublic void addLast(int data) {}@Overridepublic void addIndex(int index, int data) {}@Overridepublic boolean contains(int key) {return false;}@Overridepublic void remove(int key) {}@Overridepublic void removeAllKey(int key) {}@Overridepublic int size() {return 0;}@Overridepublic void clear() {}@Overridepublic void display() {}
}
ok!接下来我们要设置一个节点的内部类把要用到的属性加上
static class ListNode{public int val;public ListNode next; //定义next域//节点类构造方法public ListNode(int val){this.val = val;}}
为什么是static呢?因为每个节点都一样,都由数据域和next域组成的,直接static定义共同特点。
那第三行的ListNode next 怎么理解呢?因为next指向的是下一个节点的地址,而下一个节点的类型也是ListNode,所以这里的next一定是ListNode类型

好接下来定义一个链表的头
public ListNode head;
注意不要放到内部类里面,因为head是链表的成员而不是节点的成员
给几个节点赋上值

1.如何让node1的下一个节点是node2

node1.next = node2 //表示node2地址0x46给到node1
node1.next = node2; node2.next = node3; node3.next = node4; node4.next = node5;

node1是局部变量,整个过程走完之后node1会被回收怎么办?
两种方法:
第一种,把刚刚那个函数类型改成ListNode,函数返回node1
第二种,我们不是定义了head了吗,直接在函数末尾写上
this.head = node1; 这样就行了
检验结果

遍历列表
1.怎么从一个节点走到下一个节点

2.怎么判断所有节点都遍历完了

一个循环,循环终止条件是head为空,我们按照这个思想把display代码完成

这个代码有一个问题,遍历完列表之后head为空,整个头节点地址和值全都无了
解决办法是创一个中间变量cur把head锁死,遍历完之后cur为空了,但是head本质上不会变
@Overridepublic void display() {ListNode cur = this.head;while(cur != null){System.out.println(cur.val + " ");cur = cur.next;}}
有这个代码的基础,链表长度和包含函数也不在话下
@Overridepublic int size() {int count = 0;ListNode cur = this.head;while(cur != null){cur = cur.next;count++;}return count;}@Overridepublic boolean contains(int key) {ListNode cur = this.head;while(cur != null){if(cur.val == key){return true;}cur = cur.next;}return false;}
头插法
链表里面有节点


三步走
1. 实例化一个节点
2.改变插入节点的next
3.改变head
无节点
直接把head定义成这个节点
@Overridepublic void addFirst(int data) {//实例化节点对象ListNode node = new ListNode(data);//无节点if(this.head == null){this.head = node;//有节点}else{node.next = this.head;this.head = node;}}
注意这个插入是倒叙插入
尾插法
指的是将待插入的节点存放到链表的最后一个位置
步骤:
1.实例化一个节点
2.把cur走到最后一个节点
3.cur.next = node; //插入下一个节点


@Overridepublic void addLast(int data) {ListNode node = new ListNode(data);ListNode cur = this.head;if (this.head == null){this.head = node;}else {//找到尾巴while (cur.next != null) {cur = cur.next;}//cur现在指向最后一个节点cur.next = node;}}
如果想要让cur停在最后一个节点的位置 cur.next != null;

如果想把整个链表都遍历完,就是cur != null;

注意:尾插法时间复杂度是O(N),因为要遍历完整个链表n个节点后才插入元素
在任意位置插入节点

1.让cur走index-1步
2.node.next = cur.next;
cur.next = node;
在插入一个节点的时候,一定要先绑定后面这个节点
@Overridepublic void addIndex(int index, int data) {if(index < 0 || index > size()){return;}if(index == size()){addLast(data);return;}ListNode cur = searchPrev(index);ListNode node = new ListNode(data);node.next = cur.next;cur.next = node;}private ListNode searchPrev(int index){ListNode cur = this.head;int count = 0;while(count!=index-1){cur = cur.next;count++;}return cur;}
删除元素

现在我们想删除第三个节点,把第三个节点设成del
在一个循环里面让cur遍历整个链表
判断 cur.next.val == key,找到cur的位置
后面cur = cur.next
@Overridepublic void remove(int key) {if(this.head == null){//一个节点都没有,删除不了return;}//删除头节点if(this.head.val == key){this.head = this.head.next;return;}//1、找到前驱ListNode cur = findPrev(key);//2、判断返回值是否为空?if(cur == null){System.out.println("没有你要删除的数字");return;}//3、删除ListNode del = cur.next;cur.next = del.next;}//找到关键字key的前一个节点的地址private ListNode findPrev(int key){ListNode cur = this.head;while(cur.next!=null){if(cur.next.val == key){return cur;}}return null;}
删除所有值为key的节点
比如下面删除所有值为23的节点

定义cur为当前要删除的节点
prev为当前要删除的节点的前驱

cur找到了就直接把prev的next地址改成cur下一个节点的地址,cur继续往下遍历
while(cur!=null){
if(cur.val == key){
prev.next = cur.next; //删除操作
cur = cur.next;
}else{
prev = cur;
cur = cur.next
}
}
@Overridepublic void removeAllKey(int key) {if(this.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;}}
清空链表
把一个节点的val = null, next = null
再把链表的head = null

注意:这里的val = null不是直接让你 cur.val = null,拿第一个节点来说,如果你把值置为空,那么0x46被替换成null,cur找不到下一个节点的地址0x46了
我们可以拿一个变量curNext来记录cur下一个节点的位置,把cur.next 置为空之后,cur往后挪到curNext的位置,继续置空下一个节点
注意别忘了头节点,整个遍历完之后还要把头节点也置为空
@Overridepublic void clear() {ListNode cur = this.head;while(cur!=null){ListNode curNext = cur.next;cur.next = null;cur = curNext;}head = null;}
相关文章:
数据结构:链表(1)
顺序表的优缺点 缺点: 1.插入数据必须移动其他数据,最坏情况下,就是插入到0位置。时间复杂度O(N) 2.删除数据必须移动其他数据,最坏情况下,就是删除0位置。时间复杂度O(N) 3.扩容之后,有可能会浪费空间…...
软件测试之概念篇2(瀑布模型、螺旋模型、增量模型和迭代模型、敏捷模型,V模型、W模型)
目录 开发模型 (1)瀑布模型 (2)螺旋模型 (3)增量模型和迭代模型 (4)敏捷模型 (5)测试模型(V模型、W模型) V模型 W模型 开发模型…...
【【萌新的SOC学习之重新起航SOC】】
萌新的SOC学习之重新起航SOC ZYNQ PL 部分等价于 Xilinx 7 系列 FPGA PS端:Zynq 实际上是一个以处理器为核心的系统,PL 部分可以看作是它的一个外设。 我们可以通过使用AXI(Advanced eXtensible Interface)接口的方式调用 IP 核,系统通过 AX…...
ElasticSearch 学习7 集成ik分词器
网上找了一大堆,很多都介绍的不详细,开始安装完一直报错找不到plugin-descriptor.properties,有些懵这个东西不应该带在里面吗,参考了一篇博客说新建一个这个,新建完可以启动,但是插入索引数据会报错找不到…...
[NewStarCTF 2023 公开赛道] week1
最近没什么正式比赛,都是入门赛,有moectf,newstar,SHCTF,0xGame都是漫长的比赛。一周一堆制。 这周newstar第1周结束了,据说py得很厉害,第2周延期了,什么时候开始还不一定,不过第一周已经结束提交了&#…...
ThreeJS-3D教学六-物体位移旋转
之前文章其实也有涉及到这方面的内容,比如在ThreeJS-3D教学三:平移缩放物体沿轨迹运动这篇中,通过获取轨迹点物体动起来,其它几篇文章也有旋转的效果,本篇我们来详细看下,另外加了tween.js知识点࿰…...
BC v1.2充电规范
1 JEITA Reference to https://www.mianbaoban.cn/blog/post/169964 符合 JEITA 规范的锂离子电池充电器解决方案 2 Battery Fuel Gauge 2.1 Cycle Count(充放电循环次数) 此指令回传一只读字段,代表电芯组已经历的完整充放电循环数。当放电容…...
判断一个整数是否回文
回文数字的定义:第一位和最后一位相等,第二位和倒数第二位相等...依次类推,比如1221,12321等等,也就是说一个数字如果是回文,那么将它反转之后,一定和原来的值相等 解法一:投机取巧,…...
【广州华锐互动】车辆零部件检修AR远程指导系统有效提高维修效率和准确性
在快速发展的科技时代,我们的生活和工作方式正在被重新定义。这种变化在许多领域都有所体现,尤其是在汽车维修行业。近年来,AR(增强现实)技术的进步为这个行业带来了前所未有的可能性。通过将AR技术与远程协助系统相结…...
简单实现接口自动化测试(基于python+unittest)
简介 本文通过从Postman获取基本的接口测试Code简单的接口测试入手,一步步调整优化接口调用,以及增加基本的结果判断,讲解Python自带的Unittest框架调用,期望各位可以通过本文对接口自动化测试有一个大致的了解。 引言 为什么要…...
【算法|双指针系列No.4】leetcode11. 盛最多水的容器
个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望…...
数据结构全集介绍
以下列举了部分常见的数据结构: 数组(Array):数组是一种线性数据结构,可以用来存储固定大小的数据集合。在数组中,每个元素都有一个对应的索引,可以通过索引直接访问和更新元素。数组的优点是访…...
力扣刷题-字符串-反转字符串
344 反转字符串 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 你可以假设数组中的所有字符都是 ASCII 码表中…...
【CCNP】第七章 动态路由协议-BGP
第一节 BGP的基本概念 BGP(Border Gateway Protocol),边界网关协议 是运行在网络和网络之间的协议,是一款EGP(外部网关协议) BGP基于TCP协议工作,目的端口号179。源端口随机,由路由…...
java学习--day24(stream流)
文章目录 今天的内容1.Stream【难点】1.1获取流的对象1.2Stream流对象下面1.2.1count和forEach1.2.2filter方法1.2.3limit1.2.4map方法1.2.5skip1.2.6concat 1.3收集流 1.基于接口和抽象类的匿名内部类的写法 abstract class Person {public abstract void eat(); } public sta…...
Multi-Grade Deep Learning for Partial Differential Equations
论文阅读:Multi-Grade Deep Learning for Partial Differential Equations with Applications to the Burgers Equation Multi-Grade Deep Learning for Partial Differential Equations with Applications to the Burgers Equation符号定义偏微分方程定义FNN定义PI…...
Docker部署rustdesk
查看镜像版本 https://hub.docker.com/r/rustdesk/rustdesk-server/tags 拉取镜像 docker pull rustdesk/rustdesk-server:1.1.8-2创建挂载目录 mkdir -p /opt/rustdesk/{hbbr,hbbs}/root运行hbbs –nethost 仅适用于 Linux,它让 hbbs/hbbr 可以看到对方真实的…...
win1011安装MG-SOFT+MIB+Browser+v10b
文章目录 安装MG-SOFTSNMP服务配置安装MG-SOFT启动MIB-Browser以及错误解决MIB Browser使用 安装MG-SOFT win10和win11安装基本一样,所以参照下面的操作即可! SNMP服务配置 打开设置,应用和功能,可选功能,选择添加功…...
PCL点云处理之Pcd文件读取、法线与曲率计算、多线程加速、属性字段合并 (二百零八)
PCL点云处理之Pcd文件读取、法线与曲率计算、多线程加速、属性字段合并(二百零八) 一、相关介绍二、算法实现1.代码一、相关介绍 (夜深人不静) 法线和曲率的计算是点云处理中常用的关键特征,PCL提供了特有的点类型PointNormal来记录这些信息,通过OMP多线程对相关的计算函…...
JavaEE-文件IO操作
构造方法 一般方法,有很多,我们以下只是列举几个经常使用的 注意在上述的操作过程中,无论是绝对路径下的这个文件还是相对路径下的这个文件,都是不存在的 Reader 使用 --> 文本文件 FileReader类所涉及到的一些方法 Fil…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
