现在我们用递归来实现这个功能,当然,使用这种方式的前提是你要对递归足够熟练,不然等一会儿可能会懵逼掉:
用递归写起来就贼简单啦:
/**
* 递归方式反转单链表。
* @param p 当前节点
* @return 反转后的链表的头节点
*/
public ListNode reverseList2(ListNode p) {
// 如果当前节点为空或者下一个节点为空,说明已经到了链表的最后一个节点,直接返回当前节点
if (p == null || p.getNext() == null) {
return p;
}
// 递归地反转子链表,并获取反转后的链表头节点
ListNode last = reverseList2(p.getNext());
// 将当前节点的下一个节点的下一个指向当前节点,实现反转
p.getNext().setNext(p);
p.setNext(null); // 断开当前节点的下一个节点的指向,避免循环
return last;
}
没错,完了,就这点。
逻辑是这样的:
- 先递归到最后一个节点,把最后一个节点直接返回。就是那个return p;
- 最后一个个节点我们直接返回了一个对象,从倒数第二给节点开始(也就是归的过程),把当前节点赋给下一个节点的下一个节点。比如:有一个节点 [1,2,3,4,5,null],5这里直接返回了就不用看了,到了4这里,p.getNext()是不是就是5,它的下一个值本来是null吧,现在改成p,也就是4--->[1,2,3,4,5,4],这样刚才返回的那个节点5的下一个节点就指向了4,最后也别忘了最后一个节点的后面是null,所以要开:p.setNext(null),,这样返回值中,4指向3,3指向2,依次往复