Java 链表
定义:链表是一种递归的数据结构,它或者为空(null),或者是指向一个结点(node)的引用,该结点含有一个泛型的元素和一个指向另一条链表的引用。
要构造链表,首先要定义结点(Node):
private class Node { Item item; Node next; }
一个 Node 对象含有两个实例变量,类型分别为 Item(类型参数)和 Node。
现在,根据递归定义,只需要一个 Node 类型的变量就能表示一条链表,只要保证它的值是 null 或者指向另一个 Node 对象且该对象的 next 域指向了另一条链表即可。
例如,下面构造了一条含有元素 to、be 和 or 的链表:
public class Test<Item> { private class Node { Item item; Node next; } public static void main(String[] args) { Node first = new Node(); Node second = new Node(); Node third = new Node(); first.item = "to"; second.item = "be"; third.item = "or"; first.next = second; second.next = third; } }
上述代码的结果是,third 是一条链表(它是一个结点的引用,该结点指向 null,即一个空链表), second 也是一条链表(它是一个结点的引用,且该结点含有一个指向 third 的引用,而 third 是一条链表), first 也是一条链表(它是一个结点的引用,且该结点含有一个指向 second 的引用,而 second 是一条链表)。
链表表示的是一列元素。也可以用一个数组来表示一列元素,但在链表中向序列插入元素或是从序列中删除元素更方便。
在表头插入结点
要在首结点为 first 的给定链表开头插入字符串 not,需要先将 first 保存在 oldfirst 中,然后用 first 指向一个新结点,并将它的 item 域设为 not,next 域设为 oldfirst。如图 1 所示。
![]() |
从表头删除结点
删除一条链表的首结点,只需将 first 指向 first. next。如图 2 所示。
![]() |
在表尾插入结点
如何才能在链表的尾部添加一个新结点?要完成这个任务,需要一个指向链表最后一个结点的链接,添加结点时,该结点的链接被修改并指向一个含有新元素的新结点。
链接表示对结点的引用。
在链表结尾插入新结点的过程如图 3 所示。
![]() |
需要谨慎考虑是否需要维护一个额外的链接,因为每个修改链表的操作都需要添加检查是否要修改该变量(以及作出相应修改)的代码。例如,刚刚讨论过的删除链表首结点的代码就可能改变指向链表的尾结点的引用——当链表中只有一个结点时,它既是首结点又是尾结点!另外,图 3 中的代码也无法处理链表为空的情况(oldlast.next 会产生空指针异常)。类似这些情况的细节使编写链表代码时需要格外细心。
其他位置的插入和删除操作
前面已经展示了在链表中如何通过若干指令实现以下操作,其中可以通过 first 链接访问链表的首结点并通过 last 链接访问链表的尾结点:
❏ 在表头插入结点;
❏ 从表头删除结点;
❏ 在表尾插入结点。
其他操作,例如以下几种,就不那么容易实现了:
❏ 删除指定的结点;
❏ 在指定结点前插入一个新结点。
例如,怎样才能删除链表的尾结点呢?last 链接帮不上忙,因为需要将链表尾结点的前一个结点中的链接(它指向的正是 last)值改为 null。在缺少其他信息的情况下,唯一的解决办法就是遍历整条链表并找出指向 last 的结点。这种解决方案并不理想,因为它所需的时间和链表的长度成正比。
实现任意插入和删除操作的标准解决方案是使用双向链表,其中每个结点都含有两个链接,分别指向不同的方向。
遍历
可以用以下循环处理链表中的每个结点,其中 first 指向链表的首结点:
for (Node x = first; x ! = null; x = x.next) { // 处理 x.item }
数组与链表
数组与链表是两种常见的表示对象集合的方式,两者非常基础,常常被称为顺序存储和链式存储。下面是(Java)数组和链表各自的优缺点:
![]() |
总结自《算法(第四版)》1.3 背包、队列和栈
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律