歸併排序 分治策略

2021-09-21 17:53:14 字數 1677 閱讀 7916

歸併排序(merge-sort)是利用歸併的思想實現的排序方法,該演算法採用經典的分治(divide-and-conquer)策略(分治法將問題(divide)成一些小的問題然後遞迴求解,而治(conquer)的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。

private var arrtest:array=[9, 8, 7, 6, 5, 4, 3, 11, 21, 12, 2, 1, 0, 63];

/** 輔助陣列,避免頻繁new陣列開闢記憶體空間以及傳遞不必要的陣列,這裡直接在外面new一次,歸併排序時直接呼叫 */

private var temp:array=;

/*** 將兩個有序陣列arr[left...mid]和arr[mid...right]合併

* @param arr

* @param left

* @param mid

* @param right

* 總的時間複雜度為o(n)

*/private function mergerarr(arr:array, left:int, mid:int, right:int):void

else

k++;

}//某乙個子陣列掃瞄完了,另乙個子陣列還有元素沒有被掃瞄過,則直接往新陣列末尾插入

while (i <= mid)

while (j <= n)

//時間複雜度為o(n)

var a:array=;

for (var l:int=0; l < k; l++)

console.log("--------" + a.join(',') + "--------");

} /**

* 將無序陣列arr遞迴拆分成有序子陣列(陣列長度為1時視為有序)

* @param arr

* @param left

* @param right**/

private function mergersort(arr:array, left:int, right:int):void

else

}console.log("合併了子陣列[" + arrleft.join(',') + "]和[" + arrright.join(',') + "]");}}

通過新增列印資訊可以看到歸併排序的內部排序過程

先將無序陣列拆分成長度為1的陣列,此時視為有序,然後對左邊子陣列遞迴呼叫歸併排序,再對右邊子陣列遞迴呼叫歸併排序,最後對左右兩個子陣列呼叫歸併排序。

歸併排序每次將子陣列一分為二,直至子陣列長度為1或者0,需要拆分的次數為

考慮到歸併排序每次都是在相鄰的資料中進行操作,所以歸併排序在o(nlgn)的幾種排序方法中(快速排序,歸併排序,希爾排序,堆排序)相對而言,效率較高。

分治思想常用於海量資料處理,例如,計算機記憶體只有1g,但是現在需要對2g的資料進行排序,無法一次性將所有資料載入到記憶體,這時候就可以採用分治策略,將資料根據某種方法拆分為小的陣列集合(小於計算機記憶體),對各部分資料集合單獨載入到計算機記憶體排序,各部分排完序之後,再將各部分資料集合合併成大的資料集合。

歸併排序(分治)

把乙個陣列 a 分成兩個部分 s,m m 1,e 假設兩部分分別有序,把這兩部分合併到另一陣列中 tmp 保證該陣列有序,然後再把資料 e s 1拷貝回陣列a 分治的原理。把資料無限二分,最後比較兩個數即可。遞迴實現。includeusing namespace std int a 10 int b...

歸併排序 分治

歸併 將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有 序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。歸併的本質 空間換時間,通過申請乙個額外陣列儲存中間變化,從而實現排序 歸併排序核心步驟 歸併排序的特性總結 歸併的缺點在於需要o n 的空間複雜度,歸併排序的思...

分治 歸併排序

將兩個排序好的陣列歸併過程如下 紅色的 1 是左邊起始位置 綠色的 2 是右邊起始位置 灰色的 最右邊 是右邊終點位置 include using namespace std typedef int elementtype l 左邊起始位置,r 右邊起始位置,rightend 右邊終點位置 void...