基本思想:
反转入口从head.next开始,通过递归,如果当前结点有下一个结点,就递归调用反转函数,直到到最后一个结点时,让头结点指向这个结点。其他的结点:让后一个结点指向前一个结点
代码:
//用于反转整个链表
public void reverse(){
if (isEmpty()){
return;
}
reverse(head.next);
}
//反转每一个结点,参数curr是当前被反转的结点
public Node reverse(Node curr){
//当反转到最后一个结点时,让首结点指向最后一个结点
if (curr.next==null){
head.next = curr;
return curr;
}
//递归反转当前结点的下一个结点,返回直就是当前结点的上一个结点
Node pre = reverse(curr.next);
pre.next = curr;
curr.next = null;
return curr;
}
解释:
1、第一个reserve用于反转整个链表
2、第二个reserve(Node curr)用于反转每一个结点,入口为head.next。所以要在第一个reverse中调用reserve(head.next)。
3、对于每一个结点curr(非尾结点),都递归调用reserve(curr.next),并把curr.next返回,用Node pre接收,并设置pre的下一个结点为当前结点curr。
反转之前curr指向的是curr.next(即pre),反转之后curr.next(pre)指向curr,所以要把之前curr指向curr.next断掉,否则就会形成双向链表,头结点即指向反转之前的第一个结点,又指向反转之后的第一个结点,遍历链表时会不正常