歸併排序(merge-sort)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。
歸併的基本思想是合併多路有序陣列,通常我們考慮兩路歸併演算法。
歸併排序是穩定的,這是因為,在進行多路歸併時,如果各個序列當前元素均相等,可以令排在前面的子串行的元素先處理,不會打亂相等元素的順序。
考慮元素比較次數,兩個長度分別為m和n的有序陣列,每次比較處理乙個元素,因而合併的最多比較次數為(m+n-1),最少比較次數為min(m,n)。對於兩路歸併,序列都是兩兩合併的。不妨假設元素個數為n=2^h,
第一次歸併:合併兩個長度為1的陣列,總共有n/2個合併,比較次數為n/2。
第二次歸併:合併兩個長度為2的陣列,最少比較次數是2,最多是3,總共有n/4次,比較次數是(2~3)n/4。
第三次歸併:合併兩個長度為4的陣列,最少比較次數是4,最多是7,總共有n/8次合併,比較次數是(4-7)n/8。
第k次歸併:合併兩個長度為2^(k-1)的陣列,最少比較次數是2^(k-1),最多是2^k-1,總共合併n/(2^k)次,比較次數是[2^(k-1)~(2^k-1)](n/2^k)=n/2~n(1-1/2^k)。
按照這樣的思路,可以估算比較次數下界為n/2*h=nlog2(n)/2。上界為n[h-(1/2+1/4+1/8+...+1/2^h)]=n[h-(1-1/2^h)]=nlog2(n)-n+1。
綜上所述,歸併排序比較次數為nlog2(n)/2~nlog2(n)-n+1。
歸併排序引入了乙個與初始序列長度相同的陣列來儲存合併後的結果,因而不涉及交換。
例如設有數列
初始狀態:6,202,100,301,38,8,1
第一次歸併後:,,,,比較次數:3;
第二次歸併後:,,比較次數:4;
第三次歸併後:,比較次數:4;
總的比較次數為:3+4+4=11;
逆序數為14;
第一步中比較三次指的是第一次讓6與202比,第二次100與301比第三次38與8比
第二步中比較四次分別是第一次100與6比,第二次100與202比,第三次是202與301比,第四次是1與8比
第三步中比較四次分別是第一次1與6比,第二次8與6比,第三次8與100比,第四次38與100比
所以一共11次
逆序數為14
什麼是逆序數?如果一對數的前後位置與大小順序相反,即前面的數大於後面的數,那麼它們就稱為乙個逆序。乙個排列中逆序的總數就稱為這個排列的逆序數。
例如4 3 2 1,43,41,42,32,31,21,均為逆序數,一共6對
歸併**:
void hebingsort(int l,int r)
else
}while(i<=mid)
while(j<=r)
for(i=l;i<=r;i++)
a[i]=c[i];
}
演算法之 歸併排序演算法
歸併排序是效率還是比較高的演算法。其中的分治法是常用的一種解決問題的方法,現在流行的雲計算其實就是一種分治法的應用。所謂的分治法,字面解釋就是 分而治之 就是把乙個複雜的問題分成兩個或更多的相同或相似的子問題,直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。這個思想在實際工作中的作用...
排序演算法之歸併排序演算法優化
之前寫了一篇介紹排序演算法的排序演算法之插入排序 希爾排序 歸併排序 c 發現計算陣列的逆序對,我的演算法速度比別人要慢很多倍。下面來分析一下為什麼這兩種歸併演算法會相差那麼多。第一種慢速歸併演算法,如下 歸併排序 public int mergesort int array 陣列擷取成左右兩個 i...
排序演算法之歸併排序
歸併排序也是經典的使用分治法思想的代表演算法之一。歸併排序的效率很高,而且是一種穩定的排序。其總體的思想思路就是將待排序的元素分成大致相同的兩個子集合,分別對兩個子集合進行排序,最終將排序的子集合合併成排好序的總集合 歸併排序c 實現如下 include void mergesort int arr...