3 3 歸併排序法的優化

2021-08-08 04:46:25 字數 1533 閱讀 2232

3-3 歸併排序法的優化

1、在mergeoftwosortarray對兩個有序的陣列進行歸併的時候,如果兩個陣列合併之前就是有序的陣列,就不用再複製來複製去的了;

2、在歸併的子過程中,如果待排序的陣列元素個數很少的情況下,可以使用插入排序,因為插入排序對於近乎有序的陣列而言,可以提前終止迴圈,從而提高整體排序的效率

下面我們具體來說明:

1、歸併排序寫好以後,我們可以嘗試將其與插入排序進行乙個 5000 級別的資料排序的比較測試。

結論是顯而易見的,因為插入排序的時間複雜度是 o(n^2),歸併排序的時間複雜度是 o(nlogn)。所以,在絕大多數情況下,歸併排序的效能較好,插入排序的效率較低

2、但是我們還要認識到一點,在待排序的陣列在近乎有序的前提下,插入排序可以達到 o(n) 的時間複雜度,效果非常好;

3、歸併(merge)排序的優化思路:

(1)事實上,當 arr[mid]<=arr[mid+1] 的時候是不用 merge 的,如圖所示:

**實現:

if (arr[mid] < arr[mid + 1])
(2)遞迴到底的時候,可以使用插入排序優化,例如在處理 16 個元素的陣列時候,不用繼續遞迴,此時使用插入排序提公升效能。

「遞迴到底」這件事情可以由我們自己定義:

原來我們定義的遞迴到底這件事情是:當陣列區間裡只有乙個元素的時候,這個元素就是有序的,所以遞迴不能再進行下去了。

現在我們定義的遞迴到底這件事情是:當陣列區間裡的元素是有限個的時候,我們改用插入排序法來完成排序。

**實現:

if(right-left<=15)
**實現:

/**

* 對陣列給定的部分使用插入排序

* *@param arr 給定陣列

*@param left 左邊界,能取到

*@param right 右邊界,能取到

*/private

void

insertsort(int arr, int left, int right) else

}arr[j] = temp;}}

使用 15 是不是效果最優的呢?這是乙個經驗值。

下面編寫測試用例:

/**

* 測試歸併排序及其效能優化

*/@test

public

void

test07()

執行結果:

您所使用的排序演算法是 => merge sort(歸併排序)

排序演算法耗時 => 0.181 秒

您所使用的排序演算法是 => 歸併排序效能優化1

排序演算法耗時 => 0.101 秒

給定陣列按照公升序排序!

給定陣列按照公升序排序!

歸併排序法及優化

將陣列分成兩半,然後分別對其排序 在將兩部分在分別分成兩半,然後對其排序 直到每部分只剩下乙個元素 最後再使用遞迴merge兩邊的陣列。merge時,需要借助三個指標。乙個指向左半部分 乙個指向右半部分 乙個指向輔助陣列。class solution int j low 左半部分指標 int k m...

歸併排序以及歸併排序的優化

1 歸併排序的實現 歸併排序也利用了分治法的思想,首先將序列分成左右兩部分,將左右兩部分分別排序,然後將有序的兩個子串行進行合併 即merge操作 程式是遞迴進行的,主函式實現如下 歸併排序主函式 void merge sort int a,int first,int last else while...

歸併排序的優化 自然歸併排序

不知道怎麼將這個演算法思想表達的更好,也不知道自己的理解的是否對 黑體的注釋是普通的自然歸併,從相鄰長度為1的子陣列段進行合併也就是一開始將每兩個相鄰元素進行歸併,然後再相鄰四個元素左右兩組都有序的合併成4個有序的.自下向上不斷往上歸併直到有序 自然合併排序是合併排序演算法的一種改進.自然合併排序 ...