在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
1. 利用递归的归并排序,自顶向下递归解决问题。
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(!head) return NULL;
int length = 0;
ListNode* p = head;
if(head->next == NULL) return head;
while(p){
length++;
p = p->next;
}
int mid = length / 2;
//从中点分割链表
ListNode* later = cut(head, mid);
//前边部分的链表
ListNode* fore = sortList(head);
//后边部分的链表
ListNode* late = sortList(later);
ListNode *result = merge(fore, late);
return result;
}
ListNode* cut(ListNode* head, int n){
auto p = head;
int index = 0;
while(p){
index++;
if(index == n){
break;
}
p = p->next;
}
auto tmp = p->next;
p->next = NULL;
return tmp;
}
ListNode* merge(ListNode* head1, ListNode* head2){
ListNode dummyNode = ListNode(0);
//牵引结点
ListNode* p = &dummyNode;
while(head1||head2){
if(!head1){
p->next = new ListNode(head2->val);
p = p->next;
head2 = head2->next;
} else if(!head2){
p->next = new ListNode(head1->val);
p = p->next;
head1 = head1->next;
}else if(head1->val < head2->val){
p->next = new ListNode(head1->val);
p = p->next;
head1 = head1->next;
} else {
p->next = new ListNode(head2->val);
p = p->next;
head2 = head2->next;
}
//if(!head1 && !head2){}}
}
return dummyNode.next;
}
} ;
自底部向上,两两相邻链表相融合。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
if(!head) return NULL;
ListNode dummyHead(0);
dummyHead.next = head;
ListNode* p = head;
int len = 0;
while(p){
len++;
p = p->next;
}
//size:两两合并的链表长度
for(int size = 1; size < len; size <<= 1){
auto cur = dummyHead.next; //当前结点
auto tail = &dummyHead; //尾部结点
while(cur){
auto left = cur;
auto right = cut(left, size);
cur = cut(right, size);
tail->next = merge(left, right); //两链表相连
while(tail->next){
tail = tail->next;
}
}
}
return dummyHead.next;
}
ListNode* cut(ListNode* head, int n){
auto p = head;
int index = 0;
while(p&&--n){
p = p->next;
}
if(!p) return nullptr;
auto next = p->next;
p->next = NULL;
return next;
}
ListNode* merge(ListNode* head1, ListNode* head2){
ListNode dummyNode = ListNode(0);
//牵引结点
ListNode* p = &dummyNode;
while(head1||head2){
if(!head1){
p->next = new ListNode(head2->val);
p = p->next;
head2 = head2->next;
} else if(!head2){
p->next = new ListNode(head1->val);
p = p->next;
head1 = head1->next;
}else if(head1->val < head2->val){
p->next = new ListNode(head1->val);
p = p->next;
head1 = head1->next;
} else {
p->next = new ListNode(head2->val);
p = p->next;
head2 = head2->next;
}
//if(!head1 && !head2){}}
}
return dummyNode.next;
}
};
来源:oschina
链接:https://my.oschina.net/u/4371092/blog/3406277