题目大意:时间复杂度O(nlogn),空间复杂度O(1)对链表排序
分析:满足时间空间复杂度的排序方法——非递归归并(bottom-to-up)。1个和1个合并=>2个和2个合并=>4个和4个合并,自底向上完成归并排序。
代码:
/**
* 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) {
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode *h = head, *h1, *h2, *pre;
int length = 0, unit = 1;
while (h) {
h = h->next;
length++;
}
while (unit < length) {
pre = dummy; //用pre来牵引合并的过程
h = dummy->next; //h指向两组要合并的unit的头节点
while (h) {
//接下来要获取两组的头h1和h2,还有两组的长度c1和c2
int i = unit;
h1 = h;
while (i > 0 && h) {
h = h->next;
i--;
}
if (i > 0) break; //剩下的结点个数不够unit,无法做两组unit合并
i = unit;
h2 = h;
while (i > 0 && h) {
h = h->next;
i--;
}
int c1 = unit, c2 = unit - i; //即将合并的两段的长度
while (c1 > 0 && c2 > 0) { //利用pre牵引从小到大的结点
if (h1->val < h2->val) {
pre->next = h1;
h1 = h1->next;
c1--;
}
else {
pre->next = h2;
h2 = h2->next;
c2--;
}
pre = pre->next;
}
pre->next = c1 == 0 ? h2 : h1;
while (c1 > 0 || c2 > 0) { //pre牵引到合并后的两组unit的尾结点
pre = pre->next;
c1--;
c2--;
}
pre->next = h; //合并后的两组unit的尾结点与下一组头节点相连
}
unit *= 2;
}
return dummy->next;
}
};