题目描述
给你链表的头结点 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;}
};