連結串列排序,時間複雜度O(nlogn)
題目描述
對連結串列進行排序,要求時間複雜度O(nlogn)
解題思路
因題目要求複雜第O(nlogn),故可以考慮歸併排序
(1)將待排序陣列(連結串列)取中點並一分為二;
(2)遞迴地對左半部分進行歸併排序
(3)遞迴地對右半部分進行歸併排序
(4)將兩部分進行合併(merge),得到結果
關鍵問題
(1)找出連結串列中點(快慢指標,快指標一次走兩步,慢指標一次走一步,快指標在連結串列末尾時,滿指標剛好來到連結串列中點)
(2)寫出歸併排序函式
程式碼示例
class Solution {
public:
ListNode *sortList(ListNode *head) {
if (head == NULL || head->next == NULL) {
return head;
}
ListNode *p = head;
ListNode *q = head->next;
while (q != NULL && q->next != NULL) {
p = p->next;
q = q->next->next;
}
ListNode *right = sortList(p->next);
p->next = NULL;//超級重要,如何將一個連結串列分成前後兩部分,在取後半部分之後,將中點的next置為NULL,斷開鏈
ListNode *left = sortList(head);
return merge(left, right);
}
ListNode *merge(ListNode *left, ListNode *right) {
ListNode dummy(0);
ListNode *p = &dummy;
while (left && right){
if (left->val < right->val) {
p->next = left;
left = left->next;
}
else {
p->next = right;
right = right->next;
}
p = p->next;
}
if (left) p->next = left;
if (right) p->next = right;
return dummy.next;
}
};