递归反转单链表

上篇https://www.cnblogs.com/PlumBlossoms/p/14211026.html写了如何以迭代的方式反转单链表,本篇记录递归的方式。理解递归的方式不要陷入循环中,而是要明确一个函数输入的是什么,返回的是什么。以 {1,2,3,4,5,6,7} 为例:

1. 反转整个链表

public static LinkNode Reverse(LinkNode head) {
    if (head.next == null) return head;
    LinkNode last = Reverse(head.next);  //假设{2,3,4,5,6,7}→{7,6,5,4,3,2}已经反转完成,last 指向节点 7
    head.next.next = head;              //将{1}与 last 连接起来
    head.next = null;
    return last;        
}

2. 反转链表的前N个节点

LinkNode next = null;
public LinkNode ReverseN(LinkNode head, int n) {
    if (n == 1) {
        next = head.next;
        return head;
    }
    LinkNode last = ReverseN(head.next, n-1);
    head.next.next = head;
    head.next = next;
    return last;        
}

设 head 节点索引为1,则反转1到n 的节点,相当于递归反转 2 到 n-1,3 到 n-2 ... 的节点,last 始终指向反转好的链表的头节点。

3. 反转区间 [a, b) 内的节点

public LinkNode Reverse(LinkNode head, int m, int n) {
    if (m == 1) {
        return ReverseN(head, n); //然后开始反转
    }
    //首先递归找到第 m 个节点
    head = Reverse(head.next, m-1, n-1);        
    return head;        
}
posted @ 2020-12-30 19:13  wamxz  阅读(131)  评论(0)    收藏  举报