歸併排序是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。實現將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,也稱為二路歸併。
首先先來實現將兩個有序的子串行合併成乙個有序的序列。先將歸併的序列分成兩個,左邊的b和右邊的c,為了節省空間,我們將左邊的部分另申請空間儲存,即 b = new t,而右邊的部分並不申請記憶體,直接將位址賦值給 c,
合併的時候就像是有序鍊錶的合併一樣,每次比較 b 和 c中的元素,並將較小的儲存到a中。
注意到c中本來就儲存在a中,因而如果c中元素沒有用完,而b中的元素已經用完,那麼就可以直接跳出迴圈,因為c已然在a中對應的位置(字尾)。
最後刪除b即可,這時,最初的 elem陣列中 lo 到 hi 之間的元素就已經有序了。
複雜度:每次迴圈 都有c[k++], b[j++] ,最壞情況也只要o(n)。合併有序向量
template void merge(int lo,int mi,int hi,t *elem)
最終的複雜度
可以看出 每次遞迴只是將問題分成兩個 原來規模一半的問題,而每個問題只要進行上述 o(n)效率的merge,測試的主函式所以時間複雜度 t(n) = 2 * t(n/2) + o( n ), 也就是 o(n * log n).
int main()
{ int elem[110];
srand((unsigned)time(null));
for(int i = 0; i < 20;i++ )
elem[i] = rand();
cout<
執行結果
歸併排序(遞迴版本)C實現
歸併原理 第一步 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列 第二步 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置 重複步驟3直到某一指標超出序列尾 將另一串行剩下的所有元素直接複製到合併序列尾 實現 include includevoid merge int a...
歸併排序的簡單實現
學習遞迴最開始就是斐波那契和歸併排序。核心思想就是遞迴地把序列分成兩部分,直到只剩乙個元素。然後將每次劃分的兩部分再遞迴地合併起來,合併時候的順序覺決定了排序的順序還是逆序。劃分的過程可以看做是生成一顆葉子結點數為n的二叉樹,這個過程的複雜度為lgn 樹的高度 而合併的過程是相當於將每層的節點數相加...
歸併排序 C 實現
歸併排序跟快速排序一樣,也是基於 分治法 歸併排序與快速排序的區別 快速排序是先 分治 成兩個子串行,然後呼叫本身繼續遞迴進行 分治 歸併排序是先遞迴地分成子串行,然後按演算法合併。歸併排序是先遞迴地把待排序序列分成若干子串行,直到最後分成乙個乙個元素為子串行,然後對些子串行中每個元素,依照其大小合...