與很多有用的演算法類似,合併排序基於這樣乙個技巧:將 2 個大小為 n/2 的已排序序列合併為乙個 n 元素已排序序列僅需要 n 次操作。這個方法叫做合併。
我們用個簡單的例子來看看這是什麼意思:
通過此圖你可以看到,在 2 個 4元素序列裡你只需要迭代一次,就能構建最終的8元素已排序序列,因為兩個4元素序列已經排好序了:
1) 在兩個序列中,比較當前元素(當前=頭一次出現的第乙個)
2) 然後取出最小的元素放進8元素序列中
3) 找到(兩個)序列的下乙個元素,(比較後)取出最小的
重複1、2、3步驟,直到其中乙個序列中的最後乙個元素
然後取出另乙個序列剩餘的元素放入8元素序列中。
這個方法之所以有效,是因為兩個4元素序列都已經排好序,你不需要再『回到』序列中查詢比較。
【注:合併排序詳細原理,其中乙個**(原圖較長,我做了刪減)清晰的演示了上述合併排序的過程,而原文的敘述似乎沒有這麼清晰,不動戳大。】
既然我們明白了這個技巧,下面就是我的合併排序偽**。
array mergesort(array a)
if(length(a)==1)
return a[0];
end if
//recursive calls
[left_array right_array] := split_into_2_equally_sized_arrays(a);
array new_left_array := mergesort(left_array);
array new_right_array := mergesort(right_array);
//merging the 2 small ordered arrays into a big one
array result := merge(new_left_array,new_right_array);
return result;
合併排序是把問題拆分為小問題,通過解決小問題來解決最初的問題(注:這種演算法叫分治法,即『分而治之、各個擊破』)。如果你不懂,不用擔心,我第一次接觸時也不懂。如果能幫助你理解的話,我認為這個演算法是個兩步演算法:
在拆分階段過程中,使用3個步驟將序列分為一元序列。步驟數量的值是 log(n) (因為 n=8, log(n)=3)。【譯者注:底數為2,下文有說明】
我怎麼知道這個的?
我是天才!一句話:數學。道理是每一步都把原序列的長度除以2,步驟數就是你能把原序列長度除以2的次數。這正好是對數的定義(在底數為2時)。
在排序階段,你從一元序列開始。在每乙個步驟中,你應用多次合併操作,成本一共是 n=8 次運算。
第一步,4 次合併,每次成本是 2 次運算。
第二步,2 次合併,每次成本是 4 次運算。
第三步,1 次合併,成本是 8 次運算。
因為有 log(n) 個步驟,整體成本是 n*log(n) 次運算。
【注:這個完整的**演示了拆分和排序的全過程,不動戳大。】
為什麼這個演算法如此強大?
因為:你可以更改演算法,以便於節省記憶體空間,方法是不建立新的序列而是直接修改輸入序列。
注:這種演算法叫『原地演算法』(in-place algorithm)
你可以更改演算法,以便於同時使用磁碟空間和少量記憶體而避免巨量磁碟 i/o。方法是只向記憶體中載入當前處理的部分。在僅僅100mb的記憶體緩衝區內排序乙個幾個gb的表時,這是個很重要的技巧。
注:這種演算法叫『外部排序』(external sorting)。
你可以更改演算法,以便於在 多處理器/多執行緒/多伺服器 上執行。
比如,分布式合併排序是hadoop(那個著名的大資料框架)的關鍵元件之一。
這個演算法可以點石成金(事實如此!)
這個排序演算法在大多數(如果不是全部的話)資料庫中使用,但是它並不是唯一演算法。如果你想多了解一些,你可以看看 這篇**,**的是資料庫中常用排序演算法的優勢和劣勢。
合併排序演算法
陣列ary的m個元素,ary p ary q ary q 1 ary r 已按曾序排序 使得ary p ary r 按曾序排列 void clibrary merge int ary,int p,int q,int r,int m else k 0 for i p i r i ary i bp k ...
合併排序演算法
主要思想 不斷將已經有序的子陣列a p.q 和a q 1.r 合併為新的有序的陣列a p.r 具體過程可如下操作 分解 將n個元素分成各含n 2個元素的子串行 解決 對兩個子陣列遞迴地排序 合併 合併兩個已經有序的子陣列得到最終的有序陣列。合併 歸併排序 分治策略 include include u...
合併排序演算法
合併排序是用分治策略實現的排序演算法之一。基本思想是 將待排序的元素分成大小大致相同的兩個子集合,分別對這兩個子集合進行排序,最後將排好序的子集合合併成所需要的集合。此方法的時間複雜度t n o nlogn 這種排序方法漸進最優演算法。合併排序 遞迴 include using namespace ...