📜  门| GATE-CS-2017(套装2)|第 51 题(1)

📅  最后修改于: 2023-12-03 14:58:32.203000             🧑  作者: Mango

套装2 - 第51题

本题涉及递归和链表数据结构的应用。需要实现一个函数,将一个单向链表中数据的最大值放到链表的最后一个节点,并返回链表的头节点。

题目描述

给定一个单向链表,实现一个函数 move_max_to_end(),将该链表中最大的数据移到链表的最后一个节点,并返回链表的头节点。

链表节点定义如下:

struct Node {
    int data;
    Node* next;
    Node(int x) :
            data(x), next(NULL) {
    }
};
输入描述

输入的参数是一个链表的头节点。

输出描述

函数需要在原链表上修改数据,最后返回头节点。

示例
输入: 1->2->4->3
输出: 1->2->3->4
解题思路

可以先遍历整个链表,找到链表中最大的节点和其前驱节点。然后将最大节点从原链表中删除,并插入到链表末尾。

可以用递归实现。每次递归到链表末尾,再慢慢回溯返回,每次比较当前节点与之后节点的大小,如果当前节点的值比之后节点的值大,则交换两个节点的值。

代码实现
Node* move_max_to_end(Node* head) {
    if (head == nullptr || head->next == nullptr) {
        return head;
    }

    Node* max_node = head;
    Node* max_pre = nullptr;
    Node* cur = head;
    while (cur->next != nullptr) {
        if (cur->next->data > max_node->data) {
            max_node = cur->next;
            max_pre = cur;
        }
        cur = cur->next;
    }

    if (max_node != cur) { // 如果最大值不在最后一位,则先将最大值从原链表中删除
        if (max_pre != nullptr) {
            max_pre->next = max_node->next;
        } else {
            head = max_node->next;
        }
        max_node->next = nullptr;
    }
    cur->next = max_node; // 添加到链表末尾
    move_max_to_end(head); // 继续递归
    return head;
}
复杂度分析
  • 时间复杂度:O(n^2),单向链表的排序时间复杂度为 O(n^2)。
  • 空间复杂度:O(1),原地排序。