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