每个人都知道该如何反转单链表,就是把next指向前一个node就可以了,但是实际写的时候却有很多问题,是不够熟练?还是没有深入了解?
这里写了两种方法反转单链表,第一种reverse()是非递归(循环)的方法来反转。
非递归方法:
理解:首先传入的参数是起始点,也可以说是head,① 传入之后要把每一个next的值改为它前面的node,但是这并不是简单地node.next = node.previous,因为我们 ② 既没有node.previous,③ 也没有考虑边界值,比如第一个点反转后的next应该为null,我们要解决的就是这三个问题和循环的边界条件。
但是第①个问题,我们修改了next的值,就不能通过next来跳转到下一个节点了,所以我们需要新建一个变量nextNode来保存next的值。
为了让next指向上一个节点,就要保存上一个节点,用previousNode,我们让previousNode 的初始值为null,那么第一次赋值时,第一点的next就是null了。
每次循环都会向下跳一次节点,最后一次会跳到null上,所以不要返回current,而是反悔previousNode。
递归方法:
循环是每次跳到下一个节点,直到该点为null时停止,递归就是处理这个节点后,把下一个节点作为参数再传进这个方法。
不过在递归方法中,我们只保存了nextNode而没有保存previousNode,因为递归方法有一个不同于循环的性质。一个链表,在方法里又递归调用了这个方法,则程序会先进入这个方法,直到递归到最后终止,然而再执行递归方法下面的代码,这样其实相当于一个链表走了一来一回,所以在链表回来的时候才对next进行了赋值。
以下是类和方法。
Node类
public class Node {
int value;
Node next;
public Node(int value){
this.value = value;
}
}
public class Main {
public static void main(String[] arg) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = null;
Node node = node1;
node = recursionReverse(node);
while (node != null) {
System.out.println(node.value);
node = node.next;
}
}
static public Node reverse(Node current) {
Node previousNode = null;
Node nextNode = null;
while (current != null) {
nextNode = current.next;
current.next = previousNode;
previousNode = current;
current = nextNode;
}
return previousNode;
}
static public Node recursionReverse(Node current) {
if (current != null && current.next != null) {
Node nextNode = current.next;
current.next = null;
Node retNode = recursionReverse(nextNode);
nextNode.next = current;
return retNode;
} else {
return current;
}
}
}