第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;}
步骤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
- 第5天 反转链表
- 链表中倒数第 K 个结点-反转链表
- 反转链表和查找倒数第K个节点
- 剑指offer第15题(反转链表)
- 反转链表,(5)
- 链表反转
- 反转链表
- 单向链表反转
- 链表反转:
- 链表的反转
- 链表反转
- 反转单向链表
- 链表反转
- 单向链表反转
- 单向链表反转
- 链表的反转
- 链表反转
- 反转链表
- 黑马程序员_Date
- 成熟男人的标准 你达到几条
- 认识JavaScript中的作用域和上下文
- Maximum Subarray
- 除了陆展博和关谷,其他人の收入,一辈子在上海也只能蜗居吧?
- 第5天 反转链表
- .Net Framework CLR 托管程序执行机制
- 黑马程序员-接口
- Parse XML Using Java DOM API
- IOS开发之苹果私有API的使用
- 入门训练 A+B问题
- HDU-1272 小希的迷宫 并查集
- 多线程与临界区
- 真的好想你