题目
题目:给定单链表头节点,将单链表的链接顺序反转过来
例:
输入:1->2->3->4->5
输出:5->4->3->2->1
要求:按照两种方式实现
解决办法
方式一:
思路
单链表的结构如下所示:
如果所示。我们分析一下,如果要完成翻转需要思考什么:
- 循环遍历所有节点,直到结束。所以需要确认结束条件
- 安全地将当前节点指向它的前驱节点(直接指向的话会导致链表遍历失败,如下所示,找不到下一个操作节点了)
对于第1点,既然要循环遍历,那无非就是迭代器或者循环了,显然这里没办法使用迭代器,所以考虑使用while
循环。何时结束呢?不难发现,就是【当前节点的next节点为null的时候】,或者我们新增一个节点currNode
,表示当前操作节点,它随着遍历深度,不断往后移。显然它初始值是head
头节点,所以可以使用currNode == null
表示遍历结束了。
对于第2点,如何才能安全地将当前节点指向它的前驱节点呢?正常来说需要以下2步才能保证:
- 记录当前节点原有的next指向节点,这里记录为
oldNextNode
(原因见上图) - 还需要一个前驱节点
preNode
记录下一个节点需要设置的前驱节点(也可以看上图,除了找不到next节点以外,其实next节点也找不到前面的节点了,所以也需要记录)
准备好了我们就可以尝试模拟了。
操作步骤:
- 设置
oldNextNode
为currNode
的next节点 - 将
currNode
的next节点指向preNode
preNode
设置为currNode
currNode
设置为oldNextNode
似乎没问题,那我们开始写代码吧
代码示例
代码如下:
public class ReverseLinkedList {
public static void main(String[] args) {
ListNode node5 = new ListNode(5, null);
ListNode node4 = new ListNode(4, node5);
ListNode node3 = new ListNode(3, node4);
ListNode node2 = new ListNode(2, node3);
ListNode node1 = new ListNode(1, node2);
reverseLinkedList(node1);
}
private static void reverseLinkedList(ListNode head) {
// 初始化我们的中间节点
ListNode currNode = head;
ListNode oldNextNode = null;
ListNode preNode = null;
// 循环遍历,currNode != null 则表示还没遍历到结尾
while (currNode != null) {
oldNextNode = currNode.next;
currNode.next = preNode;
preNode = currNode;
currNode = oldNextNode;
}
System.out.println("试试看");
System.out.println(preNode);
}
}
最后我们看看结果吧:
倒过来了!