第5天 反转链表

来源:互联网 发布:哈密顿方程 知乎 编辑:程序博客网 时间:2024/06/04 19:20


题目:定义一个函数,输入一个单向链表的头节点, 反转该链表并输出翻转后链表的头节点。

例如:

输入链表

1, 2, 3, 4, 5, 6, 7, 8, 9

翻转后输出的再次遍历输出的结果应该是:

9,  8,  7, 6, 5, 4 ,3 ,2, 1


分析解题步骤:

原本链表形式是 : 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> null

反转后的形式是:  null <- 1 <- 2 <- 3 <- 4 <- 5 <- 6 <- 7 <- 8 <- 9


可以使用循环或者递归两种方式实现需求,这里选择使用循环的方式实现。

先来看一下单链表的节点定义:

private class Node<T> {T data;Node<T> next;}

选择使用循环的方式实现,先来看看如何循环访问所有节点,mHeadeNode是根节点。以下是通过遍历打印功能展示如何循环访问所有单向链表结点

public void printList() {if (mHeadeNode == null) {return;}Node<T> currentNode = mHeadeNode;while (currentNode != null) {System.out.print(currentNode.data + " ");currentNode = currentNode.next;}}

问题主要操作是把当前指向下一个节点的引用指向自己的前一个节点,但是如果仅这样那原本当前的下一个节点的下一个节点以后如何获取呢?

我自己实现如下,后面进行一步步拆分进行解释

public void reverse1() {Node<T> currentNode = null;Node<T> cacheNode = mHeadeNode.next;while (cacheNode != null) {mHeadeNode.next = currentNode;currentNode = mHeadeNode;mHeadeNode = cacheNode;cacheNode = cacheNode.next;}mHeadeNode.next = currentNode;}


    用了3个变量currentNode记录当前的前一个节点,mHeadeNode记录当前节点,cacheNode记录当前的下一个节点,因为当前节点修改指向后,当前节点的下一个节点需要记录下来。而且还要注意遍历结束后因为判断条件是cacheNode != null,所以当currentNode不符合前面的判断条件,所以最终要mHeadeNode.next = currentNode;


步骤currentNodemHeadeNodecacheNode第一步null12
第二步
123
第三步
234
第四步
345
第五步
456
第六步
567
第七步
678
第八步
789
第九步
89null

从我给出的解法中可以看出遍历结束后还需要再一次赋值,这种解法很容易忽略最后一次赋值而且感觉理解起来也没书上给出的以下方式好理解:

public void reverse() {Node<T> prevNode = null;Node<T> node = mHeadeNode;Node<T> nextNode = null;while (node != null) {nextNode = node.next;if (nextNode == null) {mHeadeNode = node;}node.next = prevNode;prevNode = node;node = nextNode;}}



完整代码如下:

/** *  面试题16 定义一个函数,输入一个单向链表的头结点, *   反转该链表并输出翻转后链表的头结点。 *   *  2014-1-19 */public class ReverseList<T extends Comparable<? super T>> {private Node<T> mHeadeNode;public ReverseList() {mHeadeNode = new Node<T>();}private class Node<T> {T data;Node<T> next;}public void add(T data) {if (data == null) {throw new NullPointerException();}if (mHeadeNode.data == null) {mHeadeNode.data = data;return;}Node<T> currentNode = mHeadeNode;while (currentNode.next != null) {currentNode = currentNode.next;}Node<T> node = new Node<T>();node.data = data;currentNode.next = node;}public void reverse1() {Node<T> currentNode = null;Node<T> cacheNode = mHeadeNode.next;while (cacheNode != null) {mHeadeNode.next = currentNode;currentNode = mHeadeNode;mHeadeNode = cacheNode;cacheNode = cacheNode.next;}mHeadeNode.next = currentNode;}public void reverse() {Node<T> prevNode = null;Node<T> node = mHeadeNode;Node<T> nextNode = null;while (node != null) {nextNode = node.next;if (nextNode == null) {mHeadeNode = node;}node.next = prevNode;prevNode = node;node = nextNode;}}public void printList() {if (mHeadeNode == null) {return;}Node<T> currentNode = mHeadeNode;while (currentNode != null) {System.out.print(currentNode.data + " ");currentNode = currentNode.next;}}public static void main(String[] args) {ReverseList<Integer> reverseList = new ReverseList<Integer>();reverseList.add(1);reverseList.add(2);reverseList.add(3);reverseList.add(4);reverseList.add(5);reverseList.add(6);reverseList.add(7);reverseList.add(8);reverseList.add(9);reverseList.add(10);reverseList.reverse1();reverseList.printList();}}






参考资料:

《剑指offer》 面试题16

1 0
原创粉丝点击