148.排序链表

86 阅读1分钟

方法1:自顶向下、归并排序

/**

 * Definition for singly-linked list.

 * struct ListNode {

 *     int val;

 *     ListNode *next;

 *     ListNode() : val(0), next(nullptr) {}

 *     ListNode(int x) : val(x), next(nullptr) {}

 *     ListNode(int x, ListNode *next) : val(x), next(next) {}

 * };

 */

class Solution {

public:

    // 合并两个有序链表

    ListNode* merge(ListNode* l1, ListNode* l2) {

        ListNode* dummy = new ListNode();

        ListNode* curr = dummy;

        while(l1 && l2) {

            if(l1->val < l2->val) {

                curr->next = l1;

                curr = curr->next;

                l1 = l1 -> next;

            }

            else {

                curr->next = l2;

                curr = curr->next;

                l2 = l2 -> next;

            }

        }

        // 一定是两个链表其中的一个走到了末尾

        if(l1) {

            curr->next = l1;

        }

        else {

            curr->next = l2;

        }

        return dummy->next;

    }

    ListNode* sortList(ListNode* head) {

        //  链表为空或者只有一个节点,直接返回,递归出口

        // 递归并不会出现head 为 nullptr的情况,加入nullptr只是处理初始输入为nullptr的边界条件

        if(!head || !head->next) {

            return head;

        }

  


        ListNode* slow = head;

        ListNode* fast = head->next;

        while(fast && fast->next) {

            slow = slow->next;

            fast = fast->next->next;

        }

        // 循环结束,即fast走到了原链表的尾部

       

        // 将链表一分为二

        ListNode* mid = slow->next;

        slow->next = nullptr;

        ListNode* left = sortList(head);

        ListNode* right = sortList(mid);

        // 此时left和right均为有序链表

        return merge(left, right);

    }

};

本题思路为分治、归并排序,将原链表拆分为两部分,递归拆,直到每个部分只有一个元素,只有一个元素的链表自然有序。再用合并两个有序链表解决即可。

注意if(!head || !head->next) {return head;} 中的!head只是为了处理初始链表为nullptr的边界条件