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個有序的.自下向上不斷往上歸併直到有序 自然合併排序是合併排序演算法的一種改進.自然合併排序 ...