最近在複習資料結構與演算法,聊聊快速排序的幾種劃分演算法。
快速排序是一種基於分治策略的排序演算法。
對於待排序陣列,其核心操作是:
pivot不斷地進行劃分,遞迴,最後能保證整個陣列有序。
一般來說,基準數有幾種選取方法:
O(n^2)下面以最無腦的方法1為例。
主要的劃分方法有:
中國大陸教材中經常出現的是第三種,即 Hoare 劃分,也叫哨兵劃分。
思路很無腦。直接開一個新陣列,把比 pivot 小的放左邊,比 pivot 大的放右邊,最後把陣列複製回到原陣列。需要 O(n) 的額外空間。
1 | const int N; |
Lomuto 劃分即使用單個指標,從左到右掃描陣列,交換,維持劃分順序。
1 | int Lomuto_Partition(int left, int right) { |
Hoare 劃分採用雙指標,進行交換。
1 | int Hoare_Partition(int left, int right) { |
掃描順序對於結果有影響。pivot 在最左邊時,應該先從右往左掃描。
如果先從左往右掃,找第一個大於 pivot 的數 a,而第一個小於 pivot 的數在 a 左側,此時進行 pivot 和 A[left] 的交換,會導致交換錯誤。故應該優先保證 pivot 左側都小於等於 pivot,即先尋找第一個小於 pivot 的數,這樣交換是安全的。
對於某劃分函式 partition(int st, int end) -> pivot: int 有
1 | const int N; |
最近在複習資料結構與演算法,聊聊快速排序的幾種劃分演算法。
快速排序是一種基於分治策略的排序演算法。
對於待排序陣列,其核心操作是:
pivot不斷地進行劃分,遞迴,最後能保證整個陣列有序。
一般來說,基準數有幾種選取方法:
O(n^2)下面以最無腦的方法1為例。
主要的劃分方法有:
中國大陸教材中經常出現的是第三種,即 Hoare 劃分,也叫哨兵劃分。
思路很無腦。直接開一個新陣列,把比 pivot 小的放左邊,比 pivot 大的放右邊,最後把陣列複製回到原陣列。需要 O(n) 的額外空間。
1 | const int N; |
Lomuto 劃分即使用單個指標,從左到右掃描陣列,交換,維持劃分順序。
1 | int Lomuto_Partition(int left, int right) { |
Hoare 劃分採用雙指標,進行交換。
1 | int Hoare_Partition(int left, int right) { |
掃描順序對於結果有影響。pivot 在最左邊時,應該先從右往左掃描。
如果先從左往右掃,找第一個大於 pivot 的數 a,而第一個小於 pivot 的數在 a 左側,此時進行 pivot 和 A[left] 的交換,會導致交換錯誤。故應該優先保證 pivot 左側都小於等於 pivot,即先尋找第一個小於 pivot 的數,這樣交換是安全的。
對於某劃分函式 partition(int st, int end) -> pivot: int 有
1 | const int N; |