Sort a linked list in O(n log n)
time using constant space complexity.
算法一 自顶向下折半归并,递归
使用递归。进行折半。
先使用快慢指针,找到中间结点。将链表一分为二。
对此两链表进行递归排序后,进行归并。
在leetcode上实际执行时间为62ms。
/**
* 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 || !head->next)
return head;
ListNode *walker = head;
ListNode *runner = head->next;
while (runner && runner->next) {
walker = walker->next;
runner = runner->next->next;
}
runner = sortList(walker->next);
walker->next = NULL;
head = sortList(head);
ListNode fake(0);
walker = &fake;
while (head && runner) {
if (head->val < runner->val) {
walker->next = head;
head = head->next;
}
else {
walker->next = runner;
runner = runner->next;
}
walker = walker->next;
}
walker->next = head ? head : runner;
return fake.next;
}
};算法二,自底向上进行归并。
第一趟是1个和1个进行归并。
第二趟是2个和2个进行归并。
第三趟是4个和4个进行归并。
如此2的指数递增,直到整体完成归并。
在leetcode上实际执行时间为60ms。
/**
* 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) {
int unit = 1;
while (head) {
ListNode fake(0);
ListNode *prev = &fake;
ListNode *p = head;
int times = 0;
while (p) {
ListNode *q = p;
int count = unit-1;
while (q && count--)
q = q->next;
if (!q || !q->next) {
if (!times)
return head;
else {
prev->next = p;
break;
}
}
ListNode *bak = q->next;
q->next = NULL;
q = bak;
count = unit;
while (p || q && count) {
if (!p || q && count && q->val < p->val) {
prev->next = q;
q = q->next;
--count;
}
else {
prev->next = p;
p = p->next;
}
prev = prev->next;
}
p = q;
++times;
}
head = fake.next;
unit <<= 1;
}
return head;
}
};原文地址:http://blog.csdn.net/elton_xiao/article/details/46403537