深入解析链表:解锁数据结构核心奥秘

一. 链表的定义

链表是一种线性数据结构,由一系列节点组成。每个节点包含两个部分:

  1. 数据域(Data):存储节点的数据。
  2. 指针域(Pointer):存储指向下一个节点的地址。

链表的第一个节点称为头节点(Head),最后一个节点的指针域指向空(NULL),表示链表的结束。

二. 链表的结构

1) 单向 / 双向

2) 带头 / 不带头

3)  循环 / 非循环

 链表种类丰富多样 重点掌握 单向不带头非循环 链表  可作为其他数据结构的子结构,如 哈希桶、图的邻接表等   笔试常考

  

三.  实现链表

 1) 节点类

定义链表节点类,每个节点包含数据和指向下一个节点的指针。

public class Node {int data;Node next;public Node(int data) {this.data = data;this.next = null;}
}

2) 链表类:

用于实现链表的功能 

public class MySingleList {private ListNode head;static class ListNode {int val;ListNode next;ListNode(int val) {this.val = val;this.next = null;}}public ListNode cur; // 临时头节点
}
 插入节点: 

                                                         插入节点  图示

// 在链表的末尾插入一个新节点void append(int data) {Node newNode = new Node(data);if (head == null) {head = newNode;} else {Node current = head;while (current.next != null) {current = current.next;}current.next = newNode;}usedSize++;}// 在链表的开头插入一个新节点void prepend(int data) {Node newNode = new Node(data);newNode.next = head;head = newNode;usedSize++;}// 在指定位置插入一个新节点void insertAt(int index, int data) {if (index < 0 || index > usedSize) {throw new IndexOutOfBoundsException("Index out of bounds");}Node newNode = new Node(data);if (index == 0) {newNode.next = head;head = newNode;} else {Node current = head;for (int i = 0; i < index - 1; i++) {current = current.next;}newNode.next = current.next;current.next = newNode;}usedSize++;}
 删除节点: 
// 删除指定位置的节点void deleteAt(int index) {if (index < 0 || index >= usedSize) {throw new IndexOutOfBoundsException("Index out of bounds");}if (index == 0) {head = head.next;} else {Node current = head;for (int i = 0; i < index - 1; i++) {current = current.next;}current.next = current.next.next;}usedSize--;}
 查找节点:
// 查询指定位置的节点Node getNodeAt(int index) {if (index < 0 || index >= usedSize) {throw new IndexOutOfBoundsException("Index out of bounds");}Node current = head;for (int i = 0; i < index; i++) {current = current.next;}return current;}

 四. 链表OJ 实战 ! 

 1)  开胃小菜  删除所有值域为val的节点

力扣链接: . - 力扣(LeetCode)

class Solution {public ListNode removeElements(ListNode head, int val) {while(head!= null && head.val == val){head = head.next;}ListNode cur = head;while(cur != null && cur.next != null){if(cur.next.val == val){cur.next = cur.next.next;}else{cur = cur.next;}}return head;} 
}

2)  反转链表 重要程度 五颗星 !!!

力扣链接: . - 力扣(LeetCode)

//    反转链表public ListNode reverseList(ListNode head) {// 定义两个指针,pre初始化为null,用于存储反转后的链表ListNode pre = null;// cur初始化为head,表示当前处理的节点ListNode cur = head;// 循环直到cur为null,表示已经处理完所有节点while(cur != null){// temp临时存储cur的下一个节点,因为接下来要修改cur.nextListNode temp = cur.next;// 将cur的next指针指向pre,实现反转cur.next = pre;// pre和cur都前进一步pre = cur; // pre移动到cur的位置cur = temp; // cur移动到下一个待处理的节点}// 当cur为null时,pre就是新链表的头节点return pre;}

 思路: 在遍历链表时逐步反转每个节点的指针方向 

3) 快慢指针算法 

快慢指针: 处理环形链表或数组非常有用

其实不单单是环形链表或者是数组,如果我们要研究的问题出现循环往复的情况时,均可考虑使用快慢指针的思想。

力扣链接: 876. 链表的中间结点 - 力扣(LeetCode)

public ListNode middleNode(ListNode head) {// 定义快慢指针,都初始化为头节点headListNode fast = head;ListNode slow = head;// 循环条件,快指针fast及其next不为nullwhile (fast != null && fast.next != null) {// 快指针fast每次向前移动两步fast = fast.next.next;// 慢指针slow每次向前移动一步slow = slow.next;}// 当快指针到达链表末尾时,慢指针正好到达中间节点return slow;}

 原理 : 因为fast的速度是 slow的速度的二倍, 而fast走完,slow 必然在中间位置.

 4) 合并两个有序链表:

思路 : 使用 虚拟节点 为了简化头节点的处理逻辑

比较大小 插入新链表

如果其中一个链表的节点全部被插入到新链表中,如果另一个链表还有剩余节点, 直 接将这些剩余节点链接到新链表的末尾。
记得最后返回虚拟节点的下一个节点.

力扣链接: . - 力扣(LeetCode)

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {ListNode dummy = new ListNode(-1);//虚拟节点// 创建一个指针cur,用来遍历并构建新的合并后的链表,初始指向哑节点ListNode cur = dummy;// 遍历链表直到其中一个为空while(list1 != null && list2 != null){if(list1.val > list2.val){cur.next = list2;list2 = list2.next;}else{cur.next = list1;list1 = list1.next;}cur = cur.next;}// 如果其中一个链表先遍历完,将另一个链表的剩余部分连接到新链表的末尾cur.next = (list1 == null) ? list2:list1;return dummy.next; //返回虚拟节点的下一个节点}

 五. ArrayList和LinkedList的区别

  • 数组: 适用于需要快速访问和固定大小的情况。
  • 链表: 适用于频繁插入和删除、且大小动态变化的情况。

 六. 总结 

链表作为数据结构中的佼佼者,凸显了其在动态数据操作场景下的独特价值,特别是对于需要频繁执行插入和删除操作的应用来说,更是不可或缺。掌握链表的基础操作,包括但不限于节点的创建、插入、删除及遍历,以及进阶技巧如链表的反转、合并操作,以及利用快慢指针解决复杂链表问题,是深化链表理解和应用实践的关键步骤。在链表与数组的权衡选择上,认识到两者各自的强项——数组的快速随机访问与链表的高效动态修改能力,是根据具体需求制定数据结构策略的先决条件。总而言之,链表的灵活高效使其在众多计算领域内占有一席之地,而深入探索其特性和应用,则是对每一位技术探索者的智慧挑战与能力提升之旅。

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

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

相关文章

【Linux】Wmware Esxi磁盘扩容

目录 一、概述 1.1 磁盘分区概念 1.2 LVM概念 二、扩容步骤 二、报错 一、概述 1.1 磁盘分区概念 在 Linux 中&#xff0c;每一个硬件设备都映射到一个系统的文件&#xff0c;对于硬盘、光驱等 IDE 或 SCSI 设备也不例外。Linux把各种 IDE 设备分配了一个由 hd 前缀组成的文…

论文辅导 | 基于贝叶斯优化-卷积神经网络-双向长短期记忆神经网络的锂电池健康状态评估

辅导文章 模型描述 准确估计电池健康状态是设备稳定运行的关键。针对当前健康状态研究中容量难以直接测量、估计模型调参费时等问题&#xff0c;提出基于多健康特征的贝叶斯优化&#xff08;BO&#xff09;算法优化卷积神经网络&#xff08;CNN&#xff09;与双向长短期记忆&a…

冯雷老师:618大退货事件分析

近日冯雷老师受邀为某头部电商36名高管进行培训&#xff0c;其中聊到了今年618退货潮的问题。以下内容整理自冯雷老师的部分授课内容。 一、引言 随着电子商务的蓬勃发展&#xff0c;每年的618大促已成为消费者和商家共同关注的焦点。然而&#xff0c;在销售额不断攀升的同时…

【详细教程】如何使用YOLOv10进行图片与视频的目标检测

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

datax入门(data-web的简单使用)——02

datax入门&#xff08;data-web的简单使用&#xff09;——02 1. 前言1.1 关于data-web官网1.1.1 源码下载1.1.2 datax-Web部署手册1.1.2.1 Linux环境部署手册1.1.2.2 本地开发环境部署手册 1.2 关于datax入门 2. 下载之后打包、启动、登录2.1 我的本地环境2.2 修改配置2.3 初始…

html纯原生网页引入vue3版本的quill editor

效果图 版本 vueup/vue-quill v1.2.0vue3.3.8Element Plus v2.4.2 引入流程 找一个vue3的项目, 然后安装插件vue版本的quill: vue-quill npm install vueup/vue-quill --save官方地址&#xff1a;https://vueup.github.io/vue-quill/ 安装完成之后&#xff0c;把vue-quil插件下…

解开孤独症谱系障碍:原因与症状的深度洞察

孤独症谱系障碍&#xff0c;这个日益受到关注的话题&#xff0c;让许多人感到困惑和担忧。那么&#xff0c;它究竟是由什么原因引起的&#xff0c;又有哪些表现症状呢&#xff1f; 引起孤独症谱系障碍的原因目前尚未完全明确&#xff0c;但研究表明&#xff0c;可能与以下因素有…

ROS2使用Python创建服务提供者、消费者

1.创建服务提供者 ros2 pkg create example_service_rclpy --build-type ament_python --dependencies rclpy example_interfaces --node-name service_server_02 service_server_02.py 代码 #!/usr/bin/env python3 import rclpy from rclpy.node import Node # 导入接口 …

量产工具一一显示系统(一)

目录 前言 一、项目介绍和应用 1.简单易用 2.软件可配置、易扩展 3.纯 C 语言编程 4.类似界面应用 二、项目总体框架 三、显示系统 1.显示系统数据结构抽象 &#xff08;1&#xff09;common.h &#xff08;2&#xff09;disp_manager.h 2.Framebuffer编程 &#x…

Unity数据持久化3——Json

概述 基础知识 Json文件格式 Json基本语法 练习 可以搜索&#xff1a;Json在线&#xff0c;复制代码进去解析是否写错了。 Excel转Json C#读取存储Json文件 JsonUtility using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine;[Sy…

AI周报(6.23-6.29)

AI应用-巴西医生成功用Vision Pro做手术 巴西外科医生布鲁诺戈巴托&#xff08;Bruno Gobbato&#xff09;在2024年4月22日首次成功使用Apple Vision Pro进行了肩袖撕裂的手术。这次手术采用了肩关节镜技术&#xff0c;通过关节内的摄像头捕捉图像&#xff0c;并通过高分辨率的…

基于Spring Boot的校园失物招领系统

1 项目介绍 1.1 研究的背景及意义 在网络时代飞速发展的今天&#xff0c;随着网络技术日臻完善&#xff0c;我们的生活方式正经历深刻变革。在物质追求日益增长的同时&#xff0c;提升个人精神境界也成为了现代人的共同向往&#xff0c;而阅读则是滋养心灵、丰富精神世界的重…

PyScript:在浏览器中释放Python的强大

PyScript&#xff1a;Python代码&#xff0c;直接在网页上运行。- 精选真开源&#xff0c;释放新价值。 概览 PyScript是一个创新的框架&#xff0c;它打破了传统编程环境的界限&#xff0c;允许开发者直接在浏览器中使用Python语言来创建丰富的网络应用。结合了HTML界面、Pyo…

WLAN 4-Way Handshake如何生成GTK?

关于Wi-Fi的加密认证过程&#xff0c;可以参考如下链接&#xff0c;今天我们来理解如何生成GTK。 WLAN数据加密机制_tls加密wifi-CSDN博客 1 GTK GTK&#xff08;Group Temporal Key&#xff09;是由AP通过GMK生成&#xff0c;长度为128位&#xff0c;并在四次握手的第三步中…

使用Netty框架实现WebSocket服务端与客户端通信(附ssl)

仓库地址&#xff1a; https://gitee.com/lfw1024/netty-websocket 导入后可直接运行 预览页面 自签证书&#xff1a; #换成自己的本地ip keytool -genkey -alias server -keyalg RSA -validity 3650 -keystore D:\mystore.jks -ext sanip:192.168.3.7,ip:127.0.0.1,dns:lo…

【STM32修改串口波特率】

STM32微控制器中的串口波特率调整通常涉及到USART&#xff08;通用同步接收器/发送器&#xff09;模块的配置。USART模块提供了多个寄存器来设置波特率&#xff0c;其中关键的寄存器包括BRR&#xff08;波特率寄存器&#xff09;和USART_CR1&#xff08;控制寄存器1&#xff09…

【云原生】加强理解Pod资源控制器

Pod控制器 文章目录 Pod控制器一、Replication Controller&#xff08;RC&#xff09;1.1、什么是RC1.2、RC应用1.3、RC滚动更新 二、Replication Set&#xff08;RS&#xff09;2.1、什么是RS2.2、RS应用 三、Deployment3.1、什么是Deployment3.2、更新节奏和更新逻辑3.3、自定…

uniapp - 微信小程序 - 自定义底部tabbar

废话不多说&#xff0c;直接行源码 这里需要的底部tabbar的图片在这里 我的资源里面呢 图片是这样的 先看成品吧 首先 - BaseApp\components\Tabbar.vue <script setup>import {ref,nextTick,watch} from "vue"// 核心 - 隐藏uniapp自带的底部tabbaruni.hi…

【机器学习】基于层次的聚类方法:理论与实践

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 基于层次的聚类方法&#xff1a;理论与实践引言1. 层次聚类基础1.1 概述1.2 距离…

python-斐波那契数列

[题目描述] 斐波那契数列是指这样的数列&#xff1a;数列的第一个和第二个数都为 1&#xff0c;接下来每个数都等于前面 2个数之和。 给出一个正整数 a&#xff0c;要求斐波那契数列中第 a 个数是多少。输入&#xff1a; 第 1 行是测试数据的组数 n&#xff0c;后面跟着 n 行输…