算法#11--用簡單的思維理解歸併排序和三向切分快速排序

歸併排序

1.原理

歸併操作(merge),也叫歸併算法,指的是將兩個已經排序的序列合併成一個序列的操作。歸併排序算法依賴歸併操作。

步驟:

  1. 申請空間,使其大小爲兩個已經排序序列之和,該空間用來存放合併後的序列
  2. 設定兩個指針,最初位置分別爲兩個已經排序序列的起始位置
  3. 比較兩個指針所指向的元素,選擇相對小的元素放入到合併空間,並移動指針到下一位置
  4. 重複步驟3直到某一指針到達序列尾
  5. 將另一序列剩下的所有元素直接複製到合併序列尾

2.特點

它能夠保證將任意長度爲N的數組排序時間和NlogN成正比,它的主要缺點是它所需的額外空間和N成正比。

3.代碼

詳細代碼下載地址:

https://github.com/tclxspy/Articles/blob/master/algorithm/Code/MergeSort.java

《算法第四版》裏對代碼邏輯作了很好的解釋:

4.複雜度

最差時間複雜度 О(nlogn)

最優時間複雜度 О(n)

平均時間複雜度 О(nlogn)

最差空間複雜度 總共О(n)

動態圖:

以及,

快速排序

1.原理

快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分爲兩個子序列(sub-lists)。它可能是應用最廣泛的排序算法了。

步驟爲:

  1. 從數列中挑出一個元素,稱爲”基準”(pivot)。
  2. 重新排序數列,所有元素比基準值小的擺放在基準前面,所有元素比基準值大的擺在基準的後面(相同的數可以到任一邊)。在這個分區結束之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。
  3. 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。

遞歸的最底部情形,是數列的大小是零或一,也就是永遠都已經被排序好了。雖然一直遞歸下去,但是這個算法總會結束,因爲在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。

2.特點

實現簡單,適用於各種不同的輸入數據且在一般應用中比其他排序算法都要快很多。

原地排序(只需要一哥很小的輔助棧),且將長度爲N的數組排序所需的時間和NlgN成正比。其他排序算法都無法將這兩個優點結合起來。

內循環比大多數排序算法都要短小,這意味着它無論在理論上海是在實際中都要快。

但是,它有一個潛在的缺點:在切分不平衡時這個程序會極爲低效。例如,如果第一次從最小的元素切分,第二次從第二小的元素切分,如此這般,每次調用只會移除一個元素。這會導致一個大子數組需要切分很多次。我們要在快速排序前將數組隨機排序的主要原因就是要避免這種情況。

3.代碼

在實際應用中經常會出現含有大量重複元素的數組。所以我們用“三向切分”,切分爲小於、等於和大於三部分。

詳細代碼下載地址:

https://github.com/tclxspy/Articles/blob/master/algorithm/Code/Quick3Way.java

《算法第四版》裏對代碼邏輯作了很好的解釋:

4.複雜度

最差時間複雜度 О(n^2)

最優時間複雜度 О(nlogn)

平均時間複雜度 О(nlogn)

最差空間複雜度 根據實現的方式不同而不同

動態圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章