題目:
因為時間複雜度要求(n*logn),所以考慮歸併排序(但歸併排序並不滿足常數級的空間複雜度,還需要使用快慢指標?)。
歸併排序:
把乙個待排序列從中間分兩半,每半再各自應用歸併排序處理。分出來的左右兩半的歸併操作中,同樣也是先把每半序列再從中間劈開,分成兩個子串行,再應用歸併排序,以此類推,由此看是乙個遞迴操作。
因此由此看來是,在每次歸併函式呼叫中,先檢測傳進來的序列長度,如果序列中只有1個元素,則排不了序直接return返回。如果序列中的元素多於1個,則先把它從中間劈開,分出來的左右兩個序列先各自呼叫歸併排序,然後各自的歸併排序完成之後,再把左右兩個序列的所有元素合一起,來乙個排序,這樣排完,一次完整的歸併函式的主要操作就完成了。
快慢指標參考:
當我們直接在鍊錶原地進行排序的時候,空間複雜的即為常數級。
用序列0、3、5、2、7、1、9、8測試
debug的時候,發現5、2這組從mergesort()回傳的時候,2給丟了,只有5。
原因是這句話:
mergesort
(a);
mergesort
(slow)
;return
merge
(a, slow)
;
如果裡面的兩個mergesort()呼叫單獨拿出來寫成兩句話的話,必須要有兩個變數接著他們返回來的值,否則a和slow依然指著自己在呼叫mergesort()前的兩個原結構體,即是鍊錶被排序了他倆也還指著原來兩個結構體,之後再呼叫merge(a, slow)的話這個呼叫邏輯就出錯了。
所以要麼寫成這樣:
a =
mergesort
(a);
slow =
mergesort
(slow)
;return
merge
(a, slow)
;
要麼寫成這樣:
return
merge
(mergesort
(a),
mergesort
(slow)
);
原始碼:
#include
struct listnode // 鍊錶節點定義
listnode
(int x)
:val
(x),
next
(nullptr
)listnode
(int x, listnode *next)
:val
(x),
next
(next)};
void
dis_listnode
(listnode *head)
std::cout << std::endl;
}class
solution
;listnode* solution::
sortlist
(listnode *a)
listnode *fast,
*slow,
*pre;
// 先用快慢指標找到鍊錶a的中間節點,把a劈兩半,pre在while結束後最終指向左半部分的最後乙個節點
pre = fast = slow = a;
while
(fast && fast-
>next)
pre-
>next =
null
;return
merge
(sortlist
(a),
sortlist
(slow));
}listnode* solution::
merge
(listnode *left, listnode *right)
else
listnode *p = head;
// 開始排序,left和right誰小就往後接
while
(left && right)
else
}while
(left)
while
(right)
p->next =
nullptr
;dis_listnode
(head)
;return head;
}int
main()
; listnode *p =
newlistnode
(val[i--],
nullptr);
for(
; i >=0;
--i)
listnode *head = p;
std::cout <<
"待排鍊錶中的元素:"
;dis_listnode
(head)
;// 歸併排序
solution *solution =
new solution;
head = solution-
>
sortlist
(head)
; std::cout <<
"排序後的序列:"
;dis_listnode
(head)
;return0;
}
148 排序鍊錶 歸併排序
難度 中等 題目描述 解題思路 148.排序鍊錶 2020 8 13 1對鍊錶進行歸併排序 1 快慢指標找中間節點 2 遞迴呼叫mergesort 3 合併有序鍊錶 public listnode sortlist listnode head public listnode listmergesor...
力扣 148 排序鍊錶
傳送門 題目分析 題目要求時間複雜度為 o nlogn 空間複雜度為 o 1 根據時間複雜度,我們自然能想到二分,故這裡要用到歸併排序。對鍊錶的排序,可以通過修改指標來更改節點順序,無需像陣列一樣額外開闢儲存空間。歸併排序有遞迴和非遞迴的做法,這裡採用遞迴的做法。首先,講一下什麼是歸併排序?歸併排序...
力扣 148 排序鍊錶
給你鍊錶的頭結點 head 請將其按 公升序 排列並返回 排序後的鍊錶 高階 你可以在 o n log n 時間複雜度和常數級空間複雜度下,對鍊錶進行排序嗎?示例 1 輸入 head 4,2,1,3 輸出 1,2,3,4 示例 2 輸入 head 1,5,3,4,0 輸出 1,0,3,4,5 示例 ...