一、前言
本文介绍了有关链表的算法第一部分的 Java 代码实现,算法实例:
- 新建链表
- 反转链表(递归和非递归实现)
- 获得链表倒数第k个结点
- 获得链表的中间结点
- 删除链表结点
- 交换链表结点
在本章的讨论当中,所有的链表都包含一个头结点Node,头结点不存储数据,其next指针指向第一个普通链表结点,每个普通链表结点包含一个int类型的数据项。
问题描述
输入一个int类型的数组,通过该数组创建一个链表,并打印出该链表的所有元素。
解决思路 首先我们创建一个首结点header,之后通过遍历数组p的方式获得数组中元素并创建对应的结点node,并进行两步操作:
- 将首结点的当前后继结点,作为新结点的新后继结点
- 将新结点作为首结点的新后继结点
因此,最终构建出来的链表中结点顺序是和原数组相反的。
实现代码
class Untitled { static class Node { public Node next; public int value; } static Node createList(int p[], int len) { Node header = new Node(); Node curNode = null; for (int i=0; i5->4->3->2->1
,那么反转后的链表为header->1->2->3->4->5
。解决思路 这里我们介绍两种方式:非递归实现和递归实现。
实现代码
class Untitled { static class Node { public Node next; public int value; } static Node createList(int p[], int len) { Node header = new Node(); Node curNode = null; for (int i=0; i4->3->2->1 KNode=4 4. 获得链表的中间结点
问题描述 输入一个链表,获得链表的中间结点:
- 如果链表的长度为1,那么返回唯一的一个结点
- 如果链表的长度为偶数,那么返回结点为其第len/2个结点,其中len为链表的长度
- 如果链表的长度为奇数,那么len/2的值为x.5,取第x.5+0.5个结点作为返回结点
解决思路 和 3 类似,采用 快慢指针 的方式,fast 每次走两步,而 slow 每次走一步,当fast遍历到尾结点时,slow所处的位置就是中间结点。
实现代码
class Untitled { static class Node { public Node next; public int value; } static Node createList(int p[], int len) { Node header = new Node(); Node curNode = null; for (int i=0; i2->1 KNode=2 3->1 6. 交换链表结点
问题描述 给定一个单链表的头结点header,和两个待交换的链表结点nodeA和nodeB,交换这两个链表结点
解决思路 交互链表结点的关键,在于找到这两个结点的前驱和后继结点,修改它们和对应结点的引用关系,这里需要注意的是 交换结点相邻 的情况。
实现代码
class Untitled { static class Node { public Node next; public int value; } static Node createList(int p[], int len) { Node header = new Node(); Node curNode = null; for (int i=0; i4->3->2->1 1->4->3->2->5