原题链接:Leetcode 148. 排序链表
方法一:自顶向下归并排序
cpp
/**
* 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* merge2Lists(ListNode* head1,ListNode* head2){
if(!head1) return head2;
if(!head2) return head1;
if(head1-> val <= head2->val){
head1->next = merge2Lists(head1->next,head2);
return head1;
}
else {
head2->next = merge2Lists(head1,head2->next);
return head2;
}
}
ListNode* sortList(ListNode* head) {
if(head==nullptr || head->next==nullptr) return head;
// 快慢指针找到中间节点
ListNode * slow = head;
ListNode * fast = head;
ListNode * pre = slow;
while(fast && fast->next){
pre = slow;
slow = slow->next;
fast = fast->next->next;
}
// 找到中间节点 slow,断开slow的前一个节点pre和slow的关系,将链表拆分成两个子链表
pre ->next = nullptr;
// 对两个子链表分别排序
head = sortList(head);
slow = sortList(slow);
// 合并两个有序链表
return merge2Lists(head,slow);
}
};
方法二:自底向上归并排序
cpp
/**
* 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* merge2Lists(ListNode* head1,ListNode* head2){
if(!head1) return head2;
if(!head2) return head1;
if(head1-> val <= head2->val){
head1->next = merge2Lists(head1->next,head2);
return head1;
}
else {
head2->next = merge2Lists(head1,head2->next);
return head2;
}
}
ListNode* sortList(ListNode* head) {
if(head==nullptr || head->next==nullptr) return head;
int n=0;
ListNode* cur = head;
while(cur){
cur=cur->next;
n++;
}
ListNode* root = new ListNode (0,head);
for(int len=1;len<n;len*=2){
ListNode* pre = root;
cur = root->next;
while(cur!=nullptr){
ListNode* head1 = cur;
for(int i=1;i<len && cur->next!=nullptr;i++){
cur = cur->next;
}
ListNode* head2 = cur->next;
cur->next = nullptr;
cur= head2;
for(int i=1;i<len && cur!=nullptr && cur->next!=nullptr ;i++){
cur = cur->next;
}
ListNode* nxt = nullptr;
if(cur!=nullptr){
nxt = cur->next;
cur->next = nullptr;
}
ListNode* merged = merge2Lists(head1,head2);
pre->next=merged;
while(pre->next!=nullptr){
pre = pre->next;
}
cur = nxt;
}
}
return root->next;
}
};