题目描述
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
 
题目分析
根据题意,可以使用归并排序来对链表进行排序。归并排序是基于分治的思想,比较容易实现的就是自顶向下的递归方式来实现。
- 先找出链表的中点,可以使用快慢指针来完成;
 - 然后以中点为界,将链表拆分成两个子链表分别进行排序;
 - 将两个排序后的子链表进行合并,得到完整的排序后的链表;
 - 使用递归方式实现上述操作,递归终止条件为链表为空或者链表只包含一个节点。
 
Code
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        return sortList(head, nullptr);
    }
private:
    ListNode* sortList(ListNode* head, ListNode* tail) {
        if (nullptr == head) {
            return head;
        }
        if (head->next == tail) {
            head->next = nullptr;
            return head;
        }
        ListNode* slow = head, *fast = head;
        while (fast != tail) {
            slow = slow->next;
            fast = fast->next;
            if (fast != tail) {
                fast = fast->next;
            }
        }
        return merge(sortList(head, slow), sortList(slow, tail));
    }
    ListNode* merge(ListNode* head1, ListNode* head2) {
        ListNode dummy;
        ListNode* temp = &dummy, *l1 = head1, *l2 = head2;
        while (nullptr != l1 && nullptr != l2) {
            if (l1->val <= l2->val) {
                temp->next = l1;
                l1 = l1->next;
            } else {
                temp->next = l2;
                l2 = l2->next;
            }
            temp = temp->next;
        }
        temp->next = l1 ? l1 : l2;
        return dummy.next;
    }
};
                

















