深入理解基本数据结构:链表详解

引言

在计算机科学中,数据结构是存储、组织和管理数据的方式。链表是一种重要的线性数据结构,广泛应用于各种编程场景。在这篇博客中,我们将详细探讨链表的定义、特点、操作及其在不同编程语言中的实现。


什么是链表?

链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表的特点是节点在内存中不一定是连续存储的。

链表的特点

  1. 动态大小:链表可以根据需要动态调整大小。
  2. 插入和删除操作高效:在链表中插入和删除元素非常高效,只需调整指针即可。
  3. 不连续存储:链表的节点在内存中可以是不连续存储的。
  4. 随机访问不方便:链表不支持通过索引随机访问元素,需要从头节点开始遍历。

链表的基本类型

单向链表

单向链表的每个节点包含一个数据域和一个指向下一个节点的指针。

head
节点1
节点2
节点3
节点4
null

双向链表

双向链表的每个节点包含一个数据域,一个指向下一个节点的指针和一个指向前一个节点的指针。

null
节点1
节点2
节点3
节点4
null

循环链表

循环链表的最后一个节点的指针指向头节点,形成一个环。

head
节点1
节点2
节点3
节点4

链表的基本操作

创建链表

Java中创建链表
class Node {int data;Node next;Node(int data) {this.data = data;this.next = null;}
}public class LinkedList {Node head;// 添加节点到链表末尾public void add(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;}}// 输出链表中的所有节点public void printList() {Node current = head;while (current != null) {System.out.print(current.data + " ");current = current.next;}}public static void main(String[] args) {LinkedList list = new LinkedList();list.add(1);list.add(2);list.add(3);list.add(4);list.printList();}
}

插入节点

Java中插入节点
public class LinkedList {Node head;// 在链表开头插入节点public void insertAtBeginning(int data) {Node newNode = new Node(data);newNode.next = head;head = newNode;}// 在链表末尾插入节点public void add(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;}}// 输出链表中的所有节点public void printList() {Node current = head;while (current != null) {System.out.print(current.data + " ");current = current.next;}}public static void main(String[] args) {LinkedList list = new LinkedList();list.insertAtBeginning(1);list.add(2);list.add(3);list.add(4);list.printList();}
}

删除节点

Java中删除节点
public class LinkedList {Node head;// 删除链表中的第一个节点public void deleteFirst() {if (head != null) {head = head.next;}}// 删除链表中的最后一个节点public void deleteLast() {if (head == null || head.next == null) {head = null;return;}Node current = head;while (current.next.next != null) {current = current.next;}current.next = null;}// 输出链表中的所有节点public void printList() {Node current = head;while (current != null) {System.out.print(current.data + " ");current = current.next;}}public static void main(String[] args) {LinkedList list = new LinkedList();list.add(1);list.add(2);list.add(3);list.add(4);list.printList();System.out.println();list.deleteFirst();list.printList();System.out.println();list.deleteLast();list.printList();}
}

查找节点

Java中查找节点
public class LinkedList {Node head;// 查找链表中的节点public boolean search(int key) {Node current = head;while (current != null) {if (current.data == key) {return true;}current = current.next;}return false;}// 添加节点到链表末尾public void add(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;}}// 输出链表中的所有节点public void printList() {Node current = head;while (current != null) {System.out.print(current.data + " ");current = current.next;}}public static void main(String[] args) {LinkedList list = new LinkedList();list.add(1);list.add(2);list.add(3);list.add(4);list.printList();System.out.println();System.out.println("查找2: " + list.search(2));System.out.println("查找5: " + list.search(5));}
}

图解:链表的基本操作

创建链表
创建链表
创建头节点
节点1
节点2
节点3
null
插入节点
插入节点
创建新节点
调整指针
新节点插入完成
删除节点
删除节点
找到要删除的节点
调整指针
节点删除完成
查找节点
查找节点
从头节点开始遍历
检查当前节点
找到目标节点
继续遍历
未找到目标节点

总结

链表作为一种重要的数据结构,具有动态大小插入和删除操作高效不连续存储随机访问不方便的特点。通过对链表的基本操作和实现的学习,我们可以更好地理解和使用链表。在实际编程中,链表的应用广泛且灵活,是每个程序员都必须掌握的基础知识。


参考资料

  1. Java LinkedList Documentation
  2. Python List Documentation
  3. JavaScript Array Documentation

希望这篇博客能帮助你更好地理解链表。如果你喜欢这篇文章,请给我点赞,并点击关注,以便第一时间获取更多优质内容!谢谢你的支持!


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

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

相关文章

Mobile ALOHA前传之VINN, Diffusion Policy和ACT对比

VINNDiffusion PolicyACT核心思想1.从离线数据中自监督学习获得一个视觉编码器;2.基于视觉编码器,从采集的示例操作数据中检索与当前观测图像最相似的N张图像以及对应的动作;3.基于图像编码器的距离对各个动作进行加权平均,获得最…

Open3D loss函数优化的ICP配准算法(精配准)

目录 一、概述 1.1ICP的基本步骤 1.2损失函数的设计 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2配准后点云 3.3计算数据 一、概述 ICP(Iterative Closest Point)配准算法是一种用于对齐两个点云的经典算法。其目标是通过迭代优化…

Istio实战教程:Service Mesh部署与流量管理

引言 Istio是一个开源的服务网格,它提供了一种统一的方法来连接、保护、控制和观察服务。本教程将指导你从零开始部署Istio,并展示如何使用Istio进行基本的流量管理。 环境准备 Kubernetes集群:Istio运行在Kubernetes之上,确保…

W25Q64 Flash存储器与STM32:硬件与软件的完美结合案例

摘要 在嵌入式系统中,数据存储是关键组成部分之一。W25Q64 Flash存储器因其高容量、低功耗和高可靠性,成为STM32微控制器项目中优选的存储解决方案。本文将展示W25Q64与STM32微控制器集成的案例,包括硬件设计、SPI通信协议实现和软件编程策略…

记录在Windows上安装Docker

在Windows上安装Docker时,可以选择使用不同的后端。 其中两个常见的选择是:WSL 2(Windows Subsystem for Linux 2)和 Hyper-V 后端。此外,还可以选择使用Windows容器。 三者的区别了解即可,推荐用WSL 2&…

我们公司落地大模型的路径、方法和坑

我们公司落地大模型的路径、方法和坑 李木子 AI大模型实验室 2024年07月02日 18:35 北京 最近一年,LLM(大型语言模型)已经成熟到可以投入实际应用中了。预计到 2025 年,AI 领域的投资会飙升到 2000 亿美元。现在,不只…

Thinking--在应用中添加动态水印,且不可删除

Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想。 水印是一种用于保护版权和识别内容的技术,通常用于图像、视频或文档中。它可以是文本、图像或两者的组合,通常半透明或以某种方式嵌入到内容中,使其不易被移除或篡改…

【Linux】多线程_2

文章目录 九、多线程2. 线程的控制 未完待续 九、多线程 2. 线程的控制 主线程退出 等同于 进程退出 等同于 所有线程都退出。为了避免主线程退出,但是新线程并没有执行完自己的任务的问题,主线程同样要跟进程一样等待新线程返回。 pthread_join 函数…

【代码随想录_Day28】62. 不同路径 63. 不同路径 II

Day28 OK,今日份的打卡!第二十八天 以下是今日份的总结不同路径不同路径 II 以下是今日份的总结 62 不同路径 63 不同路径 II 今天的题目难度不低,尽量还是写一些简洁代码 ^ _ ^ 不同路径 思路: 1.确定dp数组(dp…

算法学习笔记(8.2)-动态规划入门进阶

目录 问题判断: 问题求解步骤: 图例: 解析: 方法一:暴力搜索 实现代码如下所示: 解析: 方法二:记忆化搜索 代码示例: 解析: 方法三:动态规划 空间…

每日复盘-20240709

今日关注: 20240709 六日涨幅最大: ------1--------300391--------- 长药控股 五日涨幅最大: ------1--------300391--------- 长药控股 四日涨幅最大: ------1--------603155--------- 新亚强 三日涨幅最大: ------1--------301300--------- 远翔新材 二日涨幅最大: ------1-…

基于antdesign封装一个react的上传组件

项目中遇到了一个上传的需求,看了一下已有的代码很粗糙,而且是直接引用andt的组件,体验不太好,自己使用FormData对象封装了一个上传组件,仅供参考。 代码如下: /*** FileUploadModal* description - 文件选…

Qt入门(二):Qt的基本组件

目录 Designer程序面板 1、布局Layout 打破布局 贴合窗口 2、QWidget的属性 3、Qlabel标签 显示图片 4、QAbstractButton 按钮类 按钮组 5、QLineEdit 单行文本输入框 6、ComboBox 组合框 7、若干与数字相关的组件 Designer程序面板 Qt包含了一个Designer程序 &…

Qt编程技巧总结篇(3)-信号-槽-多线程(二)

文章目录 Qt编程技巧总结篇(3)-信号-槽-多线程(二)主进程与子线程线程同步实例与应用 小结 Qt编程技巧总结篇(3)-信号-槽-多线程(二) 多线程学习,使用QMutex,…

RTK_ROS_导航(3):点云的压缩,PointCloud转scan

目录 1. 源码的安装2. 修改订阅的话题3. 可视化1. 源码的安装 安装过程如下 mkdir -p point_to_scan_ws/src cd point_to_scan_ws/src git clone https://github.com/BluewhaleRobot/pointcloud_to_laserscan.git cd .. catkin_make source devel/setup.bash2. 修改订阅的话题 …

2024.07.01校招 实习 内推 面经

绿*泡*泡VX: neituijunsir 交流*裙 ,内推/实习/校招汇总表格 1、校招 | 元戎启行2025校园招聘正式批正式启动(内推) 校招 | 元戎启行2025校园招聘正式批正式启动(内推) 2、提前批 | 多益网络2025届校园…

基于抽象 HandlerInterceptor 快速实现接口鉴权

欢迎关注公众号:冬瓜白 相关文章: 每天学习一点点之 Spring Web MVC 之抽象 HandlerInterceptor 快速实现常用功能(限流、权限等) 在[每天学习一点点之 Spring Web MVC 之抽象 HandlerInterceptor 快速实现常用功能&#xff08…

Numpy的广播机制(用于自动处理不同形状的数组)

NumPy 广播是一种强大的机制,允许 NumPy 在执行元素级运算时自动处理不同形状的数组。广播的规则使得无需显式地创建匹配形状的数组,直接进行运算,大大简化了代码并提高了效率。 基本概念 广播的基本思想是让较小的数组在需要的维度上进行扩…

【MySQL数据库之概念性问题】

1、关系型数据库和非关系型数据库 关系型数据库(Relational Database,简称RDBMS)和非关系型数据库(NoSQL Database)是两种不同的数据库类型。SQL本身叫做结构化查询语言1、关系型数据库:(MySQL…

Django 更新数据 save()方法

1,添加模型 Test/app11/models.py from django.db import modelsclass Post(models.Model):title models.CharField(max_length200)content models.TextField()pub_date models.DateTimeField(date published)class Book(models.Model):title models.CharFie…