【数据结构】链表重难点突破
目录
一、链表的概念
二、链表的实现
2.1 链表的构建
2.2 从链表头部添加元素
2.3 从链表尾部添加元素
2.4 链表任意位置添加元素
2.5 常规方法实现
2.6 获取指定位置的元素
2.7 获取指定元素的位置
2.8 修改链表中某一节点
2.9 删除链表的头结点
2.10 删除链表的尾节点
2.11 删除任意位置节点
三、力扣刷题
LCR 136. 删除链表的节点
链表进阶
(备注:本篇文章的代码是基于Java实现)
一、链表的概念
(该部分主要对链表进行简单的介绍,通过简洁易懂的语言带大家快速认识链表!)
链表和数组是数据结构中最为常用的两种存储结构,链表是如同链条一般的指针来连接元素,链表的特点是插入和删除数据十分方便,但查找和读取数据 与数组相比 则较为低效。
链表与数组之间的差异:
内容 | 链表 | 数组 |
存储连续性 | 逻辑连续,物理不连续 | 逻辑、物理都连续 |
添加数据 | O(1) | O(N) |
删除数据 | O(1) | O(N) |
查询数据 | O(N) | O(1) |
修改数据 | O(N) | O(1) |
我们可以发现,一条链表是由许多个节点构成,节点中存储数据,并存储下一个节点的引用(指针)
二、链表的实现
(该部分将通过Java语言模拟链表的底层实现)
2.1 链表的构建
2.1.1 首先创建节点对象
public class ListNode {public int val; //当前节点的值public ListNode next; //下一个节点的引用public ListNode() {}public ListNode(int val) {this.val = val;}public ListNode(int val, ListNode next) {this.val = val;this.next = next;}}
2.1.2 创建链表的异常处理对象(在链表的操作过程中我们要考虑对异常进行处理)
public class LinkedListException extends RuntimeException{public LinkedListException(String message){super(message);}
}
2.1.3 创建接口,定义链表要实现的方法
2.1.4 构建链表,并实现接口
public class MyLinkedList {private ListNode head; //头指针private ListNode tail; //尾指针private int size; //链表容量}
2.2 从链表头部添加元素
接口:
//头部添加void addFirst(int val);
实现类:(addFirst)
@Overridepublic void addFirst(int val) {//创建一个新节点ListNode newNode = new ListNode(val);//如果链表为空,则头指针和尾指针都指向新节点if (head == null) {head = newNode;tail = newNode;} else {//链表不为空,则新节点指向原来链表的头节点,并更新头指针指向新节点newNode.next = head;head = newNode;}//每次添加一个新节点,原链表长度加1size++;}
测试:
为了方便打印输出结果,大家也可以和上图一样,重写toString方法:
@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("[");ListNode curr = head;while (curr != null) {sb.append(curr.val).append(",");curr = curr.next;}if (size > 0) sb.deleteCharAt(sb.length() - 1);sb.append("]");return sb.toString();}
2.3 从链表尾部添加元素
接口:
//尾部添加void addLast(int val);
实现类:(addLast)
@Overridepublic void addLast(int val) {ListNode newNode = new ListNode(val);//链表为空,则头指针指向新节点if (head == null) {head = newNode;} else {//链表不为空,需要从头节点一直找到最后一个指向空的节点,再将新节点连接到表尾ListNode curr = head;while (curr.next!=null) curr= curr.next;curr.next = newNode;}size++;}
测试:
2.4 链表任意位置添加元素
接口:
/*** 任意位置添加* @param index 插入的位置* @param val 插入的元素*/void add(int index, int val);
实现类:(add)
@Overridepublic void add(int index, int val) {//入参判断if (index < 0 || index > size) throw new LinkedListException("链表索引越界异常");//创建新节点ListNode newNode = new ListNode(val);//头部添加if (index == 0) {addFirst(val);return;}//尾部添加if (index == size) {addLast(val);return;}//找到要插入位置的前一个节点ListNode curr = head;for (int i = 0; i < index - 1; i++) {curr = curr.next;}newNode.next = curr.next;curr.next = newNode;size++;}
测试:
2.5 常规方法实现
判断链表是否为空isEmpty、获取链表长度size、获取链表头节点getFirst、获取链表尾节点getLast
接口:(这几个方法的实现都较为简单,这里我一起进行演示)
//判断链表是否为空boolean isEmpty();//获取链表长度int size();//获取头节点的值int getFirst();//获取尾节点的值int getLast();
实现类:
//判断链表是否为空@Overridepublic boolean isEmpty() {return size == 0;}//获取链表长度@Overridepublic int size() {return size;}//获取头节点的值@Overridepublic int getFirst() {//这里链表为空要进行异常处理if (isEmpty()) throw new LinkedListException("链表为空");return head.val;}//获取尾节点的值@Overridepublic int getLast() {if (isEmpty()) throw new LinkedListException("链表为空");ListNode curr = head;while (curr.next != null) curr = curr.next;//O(N)return curr.val;}
测试:
2.6 获取指定位置的元素
接口:
//获取任意位置节点的值int get(int index);
实现类:
@Overridepublic int get(int index) {//判断索引是否合法if (index < 0 || index >= size) throw new LinkedListException("索引越界异");//直接返回头节点if (index == 0) {return getFirst();}//直接返回为节点if (index == size - 1) {return getLast();}//遍历ListNode curr = head;for (int i = 0; i < index; i++) {curr = curr.next;}return curr.val;}
测试:
2.7 获取指定元素的位置
接口:
/*** 通过值找索引* @param val 要查找的元素* @return 返回该元素的位置*/int indexOf(int val);
实现类:
@Overridepublic int indexOf(int val) {//若链表为空直接返回-1if (isEmpty()) return -1;ListNode curr = head;int index = 0;while (curr != null) {//如果找到 直接返回索引if (curr.val == val) {return index;}curr = curr.next;index++;}//未找到 返回-1return -1;}
测试:
2.8 修改链表中某一节点
接口:
/*** 修改元素* @param index 旧元素的位置* @param val 新元素的值*/void set(int index, int val);
实现类:
@Overridepublic void set(int index, int val) {//链表为空 无法修改if (isEmpty()) throw new LinkedListException("链表为空");//判断索引是否合法if (index < 0 || index >= size) throw new LinkedListException("索引越界");ListNode curr = head;for (int i = 0; i < index; i++) {curr = curr.next;}curr.val = val;}
测试:
2.9 删除链表的头结点
接口:
//删除头节点void removeFirst();
实现类:
@Overridepublic void removeFirst() {//链表为空要进行异常处理if (isEmpty()) throw new LinkedListException("链表为空");ListNode next = head.next;head.next = null;head = next;size--;}
测试:
2.10 删除链表的尾节点
接口:
//删除尾节点void removeLast();
实现类:
@Overridepublic void removeLast() {if (isEmpty()) throw new LinkedListException("链表为空异常,删除失败");if (size==1){head=null;size--;return;}ListNode pre = head;for (int i = 0; i < size -2; i++) {pre = pre.next;}ListNode target = pre.next;ListNode next = target.next;pre.next = next;target.next = null;size--;}
测试:
2.11 删除任意位置节点
接口:
//删除任意位置节点void remove(int index);
实现类:
@Overridepublic void remove(int index) {if (isEmpty()) throw new LinkedListException("链表为空");if (index < 0 || index >= size) throw new LinkedListException("索引越界");if (index == 0) {removeFirst();return;}ListNode pre = head;for (int i = 0; i < index - 1; i++) {pre = pre.next;}ListNode target = pre.next;ListNode next = target.next;pre.next = next;target.next = null;size--;}
测试:
三、力扣刷题
LCR 136. 删除链表的节点
大家可以尝试下这道题目:
LCR 136. 删除链表的节点 - 力扣(LeetCode)
链表进阶
【快慢指针】突破环形链表-CSDN博客
关于代码的优化或大家有更好的思路 欢迎在评论区分享你的观点!
🌸🌸🌸 完结撒花 🌸🌸🌸
博主WX:g2279605572 欢迎大家与我交流!
相关文章:

【数据结构】链表重难点突破
目录 一、链表的概念 二、链表的实现 2.1 链表的构建 2.2 从链表头部添加元素 2.3 从链表尾部添加元素 2.4 链表任意位置添加元素 2.5 常规方法实现 2.6 获取指定位置的元素 2.7 获取指定元素的位置 2.8 修改链表中某一节点 2.9 删除链表的头结点 2.10 删除链表的尾…...

大宗商品行业区块链应用
应用场景 区块链技术具有透明性、去中心化、不可篡改等特点,因此可以在大宗商品定价方面得到应用。通过区块链技术,相关交易的各方可以在无需依赖中心化第三方的情况下,实时、准确地获取定价信息。这种技术的应用能够提高效率、降低成本、提…...

Varjo:垂直起降机混合现实培训解决方案
混合电动垂直起降机(VTOL)作为一种新型的航空运输机具有超越传统汽车的安全性、与飞机相当的速度以及无与伦比的灵活起降功能。电动垂直起降机能够在建筑顶部、直升机场或是没有跑道的地区起飞或降落,且排放要远远低于由航空汽油驱动的传统飞…...

sqlite-vec一个SQLite3高效向量搜索扩展--JDBC环境使用
最近要用SQLite3,之前放出来了SQLiteUtile工具,方便操作。今天发现AIGC方面,RAG知识库需要使用向量数据库,来存储知识信息。一般呢都是用mysql,但无奈的是mysql就是不让用。突然又发现SQLite3有向量库扩展组件…...

10 基于深度学习的目标检测
首次完成时间:2024 年 11月 20 日 1. 使用OpenCV的dnn模块实现图像分类。 1)程序代码: import numpy as np import cv2# 解析标签文件 row open("model1/synset_words.txt").read().strip().split("\n") class_label …...

leetcode top100中的30道递归和贪心
21到30题,递归和贪心...

非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 2
七、创建前端项目 你下载了nodejs吗?从cn官网下载:http://nodejs.cn/download/,或者从一个国外org网站下载,选择自己想要的版本https://nodejs.org/download/release/,双击下载好的安装文件,选择安装路径安…...

shell脚本(完)—脚本互调重定向的学习
免责声明 学习视频来自B 站up主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下代码、网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 脚本互调 在Shell脚本中&a…...

ant-design-vue中table某一列进行合并
ant-design-vue中table某一列进行合并 1、在colums中配置自定义渲染 {title: 区域,dataIndex: cityName,key: cityName,align: center,width: 120,customCell: (record, rowIndex, column) > {return {rowSpan: record.rowSpan}} },2、处理请求来的数据 tableData.dataSo…...

基于Springboot+Vue社区养老服务管理系统(源码+lw+讲解部署+PPT)
前言 详细视频演示 论文参考 系统介绍 系统概述 核心功能 用户角色与功能 具体实现截图 1. 服务信息查看功能 主要代码实现 截图: 2. 服务申请功能 主要代码实现 截图: 3. 公告信息查看功能 主要代码实现 截图: 4. 服务信息…...

大数据调度组件之Apache DolphinScheduler
Apache DolphinScheduler 是一个分布式易扩展的可视化 DAG 工作流任务调度系统。致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用。 主要特性 易于部署,提供四种部署方式,包括Standalone、Cluster、Docker和…...

介绍一下strlwr(arr);(c基础)
hi , I am 36 适合对象c语言初学者 strlwr(arr);函数是把arr数组变为小写字母 格式 #include<string.h> strlwr(arr); 返回值为arr 链接分享一下arr的意义(c基础)(必看)(牢记)-CSDN博客 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #incl…...

meterpreter常用命令 上
Meterpreter 是 Metasploit 框架中的一个高级 Payload,广泛用于渗透测试和攻击模拟。以下是一些常用的 Meterpreter 命令: 1. 基本命令 sysinfo 显示目标系统的基本信息(操作系统、架构等)。 getuid 获取当前用户的身份信息。…...

【kubernetes】kubernetes各组件的调用关系
目录 1. 说明2. Kubernetes组件概述2.1 控制平面组件2.2 节点组件 3. Kubernetes组件调用关系4. 示例说明 1. 说明 1.Kubernetes是一个开源的容器编排工具,其各个组件之间存在着复杂的调用关系,共同构建起一个完整的容器编排系统。2.Kubernetes集群主要…...

Java-08 深入浅出 MyBatis - 多对多模型 SqlMapConfig 与 Mapper 详细讲解测试
点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatisÿ…...

Vue.js修饰符
Vue.js 是一个渐进式JavaScript框架,用于构建用户界面。在Vue.js中,修饰符(Modifiers)是一种增强指令行为的工具,它们可以改变指令的默认行为。本文将详细讲解Vue.js中的修饰符,并提供实际示例,…...

【数据分享】2024年我国省市县三级的住宿服务设施数量(8类住宿设施/Excel/Shp格式)
宾馆酒店、旅馆招待所等住宿服务设施的配置情况是一个城市公共基础设施完善程度的重要体现,一个城市住宿服务设施种类越丰富,数量越多,通常能表示这个城市的公共服务水平越高! 本次我们为大家带来的是我国各省份、各地级市、各区…...

【含文档】基于.NET的医院医保管理系统(含源码+数据库+lw)
1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 主要技术:mysql,vue 2.视频演示地址 3.功能 系统定义了两个角色:管理员和用户。 管理员进入主界面&…...

c++源码阅读__smart_ptr__正文阅读
文章目录 简介源码解析1. 引用计数的实现方式2. deleter静态方法的赋值时间节点3.make_smart的实现方式 与 好处4. 几种构造函数4.1 空构造函数4.2 接收指针的构造函数4.3 接收指针和删除方法的构造函数 , 以及auto进行模板lambda的编写4.4 拷贝构造函数4.5 赋值运算符 5. rele…...

图形化界面MySQL(MySQL)(超级详细)
1.官网地址 MySQL :: Download MySQL Workbench 1.1在Linux直接点击NO thanks..... 下载完后是这个页面 1.2任何远端登录,再把jj数据库给授权 1.3建立新用户 进行连接 点击这个就运行了 只执行show tables;要先选中 圆圈处支持自己输入 点击这个就执…...

【2024 Optimal Control 16-745】Julia语法
Lecture 2 θ和它的导数符号是通过 Julia 中的变量命名方式实现的 变量 θ 的输入: 在 Julia 中,θ 是一个合法的变量名,就像普通的字母 x 或 y 一样。要输入 θ,可以使用以下方法: 在 Jupyter Notebook 或 Julia REP…...

Opencv+ROS实现摄像头读取处理画面信息
一、工具 ubuntu18.04 ROSopencv2 编译器:Visual Studio Code 二、原理 图像信息 ROS数据形式:sensor_msgs::Image OpenCV数据形式:cv:Mat 通过cv_bridge()函数进行ROS向opencv转换 cv_bridge是在ROS图像消息和OpenCV图像之间进行转…...

网络安全,文明上网(2)加强网络安全意识
前言 在当今这个数据驱动的时代,对网络安全保持高度警觉已经成为每个人的基本要求。 网络安全意识:信息时代的必备防御 网络已经成为我们生活中不可或缺的一部分,信息技术的快速进步使得我们对网络的依赖性日益增强。然而,网络安全…...

深度学习实战图像缺陷修复
这里写目录标题 概述1. 图像缺陷修复的研究背景2. 传统图像缺陷修复方法的局限性(1) 基于纹理合成的方法(2) 基于偏微分方程(PDE)的方法 3. 深度学习在图像缺陷修复中的兴起(1) 深度学习的基本思路(2) 深度学习方法的优势(3) 关键技术的引入 4. 深度学习…...

jenkins 2.346.1最后一个支持java8的版本搭建
1.jenkins下载 下载地址:Index of /war-stable/2.346.1 2.部署 创建目标文件夹,移动到指定位置 创建一个启动脚本,deploy.sh #!/bin/bash set -eDATE$(date %Y%m%d%H%M) # 基础路径 BASE_PATH/opt/projects/jenkins # 服务名称。同时约定部…...

【数据库原理】创建与维护表,DDL数据定义语言
数据描述语言(数据定义语言) 就是管理数据库整个库,整个表,表的属性列的语句。 常用词儿就是数据库或表的增删改查:CREATE创建、DROP删除、ALTER修改、SHOW查看、USE进入表。 表的字段控制:PRIMARY KEY主键…...

驾驭Go语言中的不确定性:深入错误处理机制
驾驭Go语言中的不确定性:深入错误处理机制 在Go语言的编程世界中,错误处理是确保程序健壮性的关键。Go语言通过显式的错误返回值和panic/recover机制,提供了一套独特的错误处理策略。本文将深入探讨Go语言中的错误处理,包括原理、技术细节和实际案例,帮助读者在实际编程中…...

3D Gaussian Splatting在鱼眼相机中的应用与投影变换
paper:Fisheye-GS 1.概述 3D 高斯泼溅 (3DGS) 因其高保真度和实时渲染而备受关注。然而,由于独特的 3D 到 2D 投影计算,将 3DGS 适配到不同的相机型号(尤其是鱼眼镜头)带来了挑战。此外,基于图块的泼溅效率低下,尤其是对于鱼眼镜头的极端曲率和宽视野,这对于其更广泛…...

【Unity踩坑】在Mac上安装Cocoapods失败
在集成Unity Ad时,如果是第一次在iOS上集成,会在Mac上安装Cocoapods。 安装时提示下面的错误: Error installing cocoapods:The last version of drb (> 0) to support your Ruby & RubyGems was 2.0.5. Try installing it with gem…...

uni-app 认识条件编译,了解多端部署
一. 前言 在使用 uni-app 进行跨平台开发的过程中,经常会遇到需要针对不同平台或不同环境进行条件编译的情况。条件编译是一种在编译过程中根据指定条件选择不同代码路径的技术,可以帮助我们在不同平台或环境下编写不同的代码,以适应不同的平…...