链表反转(反转全部,前n个,中间)

链表反转

反转全部

// 迭代
struct ListNode *reverseList(struct ListNode *head) {
    struct ListNode *pre = NULL;
    struct ListNode *next;
    struct ListNode *cur = head;

    // 原地反转
    while (cur != NULL) {
        next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }
    return pre;
}
// 递归
struct ListNode *reverseList(struct ListNode *head) {
    // 递归出口
    if (head == NULL || head->next == NULL) return head;
    // 递归式
    struct ListNode *newHead = reverseList(head->next); // 递归反转后面的链表
    head->next->next = head; // 下个结点也就是反转后的尾节点,指向自己
    head->next = NULL; // 自己作为新的尾节点
    return newHead;
}

反转前n个

// 第n个节点的直接后继
struct ListNode *successor = nullptr;

// 反转前n个节点(递归)
struct ListNode *reverseListFront(struct ListNode *head, int n) {
    if (head == nullptr || head->next == nullptr) return head;
    if (n == 1) {
        // 记录下原来顺序中第n+1个节点
        successor = head;
        return head;
    }

    // 反转后面n-1个节点
    ListNode *newHead = reverseListFront(head->next, n ### 1);
    // 添加到反转后的n-1个节点的最后面
    head->next->next = head;
    // 反转全部链表时,这里是null;反转前n个时,这里是原链表中第n+1个节点
    head->next = successor;
    return newHead;
}

反转中间

// 反转[start, end],下标从1开始
struct ListNode *reverseListMid(struct ListNode *head, int start, int end) {
    // 递归出口:反转前end个
    if (start == 1) return reverseListFront(head, end);
    // 递归体:反转以head.next为头节点的链表
    head->next = reverseListMid(head->next, start ### 1, end ### 1);
}
struct ListNode *reverseBetween(struct ListNode *head, int left, int right) {
    if (head == NULL || head->next == NULL || left >= right) return head;
    // 虚拟头节点
    struct ListNode *dummyHead = (struct ListNode *) malloc(sizeof(struct ListNode));
    dummyHead->next = head;
    struct ListNode *preNode = dummyHead;
    int count = left - 1;
    // preNode为left的直接前驱
    while (count-- > 0) preNode = preNode->next;
    // 暂存反转后的子链表的尾节点
    struct ListNode *newTail = preNode->next;

    // 反转子链表
    struct ListNode *pre = NULL, *next = NULL, *cur = preNode->next;
    count = right - left + 1;
    while (count-- > 0) {
        next = cur->next;
        cur->next = pre;
        pre = cur;
        cur = next;
    }
    // pre是right节点,即反转后子链表的头节点,next是原链表中right的直接后继
    preNode->next = pre;
    newTail->next = next;
    return dummyHead->next;
}
posted @ 2022-07-07 15:00  n1ce2cv  阅读(51)  评论(0编辑  收藏  举报