歸併排序的簡單實現(c 版本)

2021-07-06 01:15:21 字數 1114 閱讀 9258

歸併排序是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(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 實現

歸併排序跟快速排序一樣,也是基於 分治法 歸併排序與快速排序的區別 快速排序是先 分治 成兩個子串行,然後呼叫本身繼續遞迴進行 分治 歸併排序是先遞迴地分成子串行,然後按演算法合併。歸併排序是先遞迴地把待排序序列分成若干子串行,直到最後分成乙個乙個元素為子串行,然後對些子串行中每個元素,依照其大小合...