本文参考博客http://blog.csdn.net/feliciafay/article/details/6841115,利用其方法并使用Java语言进行实现。
首先,给出链表节点定义,使用了leetcode的节点模型进行声明。
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
常见的链表反转方法大约有以下三种:
一、使用3个指针遍历单链表,逐个链接点进行反转。
1 -> 2 -> 3 -> 4 -> 5
考虑这个链表,实现反转只需要逐步进行即可。
1 <- 2 -> 3 -> 4 -> 5
1 <- 2 <- 3 -> 4 -> 5
……
这是最容易直观的方法,实现的代码如下:
public class Solution {
public ListNode reverse(ListNode head) {
if (head == null)
return head;
ListNode prev = head, current = prev.next, last;
head.next = null;
while (current != null) {
last = current.next;
current.next = prev;
prev = current;
current = last;
}
return prev;
}
}
二、从第2个节点到第N个节点,依次逐节点插入到第1个节点(head节点)之后,最后将第一个节点挪到新表的表尾。
1 -> 2 -> 3 -> 4 -> 5
1 -> 3 -> 2 -> 4 -> 5
1 -> 4 -> 3 -> 2 -> 5
……
当然,以上是大致过程,考虑到首节点也需要变化,我们可以为链表新加一个头,这也是处理链表问题常用的手段之一。
public class Solution {
public ListNode reverse(ListNode head) {
if (head == null)
return head;
ListNode prev = new ListNode(0);
prev.next = head;
ListNode current = prev.next, last;
while (current.next != null) {
last = current.next;
current.next = last.next;
last.next = prev.next;
prev.next = last;
}
return prev.next;
}
}
三、递归
树的很多问题都可以通过递归实现,对于单链表,可以看做是颗永远只有左(右)子树的树,因此可以考虑用递归来解决。
具体思路直接套用原作者的想法,如果需要把A->B->C->D进行反转,可以先假设B->C->D已经反转好,已经成为了D->C->B,那么接下来要做的事情就是将D->C->B看成一个整体,让这个整体的next指向A,所以问题转化了反转B->C->D。那么,可以先假设C->D已经反转好,已经成为了D->C,那么接下来要做的事情就是将D->C看成一个整体,让这个整体的next指向B,所以问题转化了反转C->D。那么,可以先假设D(其实是D->NULL)已经反转好,已经成为了D(其实是head->D),那么接下来要做的事情就是将D(其实head->D)看成一个整体,让这个整体的next指向C,所以问题转化了反转D。
public class Solution {
public ListNode reverse(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode prev, last;
prev = head.next;
last = reverse(head.next);
prev.next = head;
head.next = null;
return last;
}
}
最后是测试代码:
public class Test {
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5, 6};
ListNode head = createList(nums);
Solution solution = new Solution();
printList(solution.reverse(head));
}
private static ListNode createList(int[] nums) {
ListNode head = new ListNode(0);
ListNode result = head;
for (int i : nums) {
ListNode node = new ListNode(i);
head.next = node;
head = head.next;
}
return result.next;
}
private static void printList(ListNode head) {
ListNode current = head;
while (current != null) {
System.out.print(current.val + " ");
current = current.next;
}
}
}