Singly Linked List 即单向链表
链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。
一个单向链表的节点被分成两个部分。第一个部分保存或者显示关于节点的信息,第二个部分存储下一个节点的地址。单向链表只可向一个方向遍历。
对于一个单向链表来说,我们需要考虑如下的操作:
如何在Java中构建一个单向链表
首先需要构造一个 LinkedList class,它包含 Node class
对于每一个 Node 来说,它需要储存 data 和下一个 node 的 reference,这可以用构造器来完成
如何打印出整个链表中的元素
遍历(Iterative)整个链表
如何向链表中添加元素
向链表中添加元素分为三种情况:
在链表头添加
|
|
在链表中某个指定的位置添加
|
|
在链表尾添加
|
|
如何删除链表中的节点
删除链表中的节点又分为以下两种情况:
给定元素的值,删除该值第一次出现在链表中的那个节点
|
|
给定节点所在的位置(position),删除该节点
|
|
如何获取节点数目
有两种方法:Iterative 和 Recursive
Iterative method 获取节点数目
|
|
Recursive method 获取节点数目
|
|
给定两个数据x和y,如何交换包含数据的两个节点
(需要注意的是,在此处的“交换”指交换node,而非节点中的data)
这个操作略微有些复杂,我们需要考虑如下步骤:
1.如果x和y相等,直接return
2.找到x和y的节点和它们的前一个节点(应为我们需要交换它们,找到前一个节点能为我们提供reference)
3.如果x和y中有一个不存在(或都不存在),直接return
4.如果x为head,把y设为新的head;如果y为head,把x设为新的head
5.交换两个节点的下一个节点(使用temp,就像交换两个variable一样)
|
|
如何reverse单向链表
Example:
Input : Head of following linked list: 1->2->3->4->5->NULL
Output : Linked list should be changed to: 5->4->3->2->1->NULL
有两种方法:Iterative 和 Recursive
Iterative method to reverse a linked list
|
|
对于初学者来说,单看代码理解起来可能有些困难
这里有一个很好的 reference 材料,讲的清晰且易懂:
YouTube video on reserve a linked list using Iterative method (需要翻墙)
Recursive method to reverse a linked list
Recursive 地 reverse linked list 需要如下几个步骤:
1)Base Case: 当 “node” 为最后一个节点时,把它设为新的 head
2)递归的调用该函数(此时 node 跳到上一个 stack 中, node 为倒数第二个节点)
3)使 node.next 指向 node, node 本身指向 null
关于用 recursive method 去 reverse linked list,这里有个不错的学习资料:
Recursive method to reverse a linked list (需要翻墙)
除了以上这些基本方法以外,针对 linked list 还有一些稍微更复杂一点的操作:
给定两个已经排好序(从小到大)的 linked list 比如 a 和 b,如何把它们合并成一个单独的递增的 linked list
Example:
The first linked list a is 5->10->15
The second linked list b is 2->3->20
Then SortedMerge() should return a pointer to the head node of the merged list 2->3->5->10->15->20
|
|
了解了以上步骤后,在此基础上,我们来看另一个有些复杂的操作:
给定一个无序的 linked list,如何用 merge sort 对其排序
分为三个步骤:
1)找到中间节点 middle
如何在不知道 linked list 长度的情况下找到中间的节点呢?这里提供一种比较巧妙的思路:
创建两个指针,fastPointer 移动两格,slowPointer 移动一格,当 fastPointer 为 null 时,slowPointer 指向中间的 node,Java 代码实现如下:
2)此时 linked list 被分为左右两个部分,分别对其递归的使用 mergeSort
3)用我们已经讨论锅的上一个操作 sortedMerge 对左右两个进行合并
给定一个 Linked List 和 size k, 如何在 k 的范围内 reverse Linked List
Example:
Inputs: 1->2->3->4->5->6->7->8->NULL and k = 3
Output: 3->2->1->6->5->4->8->7->NULL.
Inputs: 1->2->3->4->5->6->7->8->NULL and k = 5
Output: 5->4->3->2->1->8->7->6->NULL.
|
|
Source: http://www.geeksforgeeks.org/reverse-a-list-in-groups-of-given-size/
对于 Singly LinkedList 的介绍和一些基本操作就讲到这里,以上内容如有疏漏或不足之处,欢迎与我讨论:
邮箱:entropy714@gmail.com
微信:cobain0714
Reference: