📜  门| GATE-CS-2017(Set 2)|问题21(1)

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

介绍 GATE CS 2017 (Set 2) 的问题 21

该问题主要考察了程序员的排序算法知识,要求理解了常用排序算法的时间复杂度以及如何对链表进行排序。

问题描述

给定一个单向链表,要求按照降序对链表进行排序并返回新排序后的链表,且算法的时间复杂度不能超过 O(nlogn)。

链表的结构如下:

struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
解题思路

单向链表的排序需要用到归并排序(Merge Sort)。

归并排序是一种典型的分治策略,可以被平衡地划分为两个子序列进行递归操作,然后将子序列的结果组合起来。

递归操作需要处理的三个基本情况:

  1. 当序列为空或只包含一个元素时,递归终止。
  2. 针对每个子序列,分别排序并合并。
  3. 合并所有子序列,返回整个排序序列。

具体实现细节可以参考下面的代码片段。

代码实现
ListNode *merge(ListNode *l1, ListNode *l2) {
    if (!l1) return l2;
    if (!l2) return l1;
    if (l1->val > l2->val) {
        l1->next = merge(l1->next, l2);
        return l1;
    } else {
        l2->next = merge(l1, l2->next);
        return l2;
    }
}

ListNode *sortList(ListNode *head) {
    if (!head || !head->next) return head;
    ListNode *slow = head;
    ListNode *fast = head->next;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    ListNode *temp = slow->next;
    slow->next = NULL;
    ListNode *left = sortList(head);
    ListNode *right = sortList(temp);
    return merge(left, right);
}
总结

本题考察了程序员的排序算法知识以及链表操作的基本功,归并排序时间复杂度为 O(nlogn),可以满足本题的要求。在实现上,还需要注意链表的特殊操作,如链表的访问和修改。