歸併排序的核心思想是將兩個已經排序的序列合併成乙個序列,那如何得到兩個已經排序的序列呢?我們知道, 如果乙個序列只有乙個元素,那該序列是已經排序的,這樣我們就可以利用分治的思想,將未排序的序列劃分成更小的序列,只到我們可以很方便的對小序列進行排序(比如劃分到序列只有乙個元素, 或者序列很小可以方便的使用其它排序演算法進行排序),然後再將小序列逐次合併,得到最後的排序結果。
#include#include#includeint num =0;
void merge(int in, int out, int l, int m, int r)
else
} while (l <= m)
while (k <= r)
}/** @brief 遞迴將序列劃分為只有乙個元素的子串行, 然後逐次對子序列進行合併
*/void m_sort(int in, int out, int l, int r)
/* 計算 l 和 r 的中間值, 防止溢位 */
int m = (l & r) + ((l ^ r) >> 1);
m_sort(out, in, l, m);
m_sort(out, in, m + 1, r);
merge(in, out, l, m, r);}/*
* @brief merge sort
* 統一申請空間, 避免反覆申請釋放
*/int merge_sort(int a, int n)
return -1;
}int main()
; merge_sort(a,9);
for(int i=0;i<9;i++)
printf("%d ",a[i]);
printf("\n");
return 0;
}
這是乙個遞迴演算法,這個演算法的理解其實可以借助下面這個圖:
對於原始的陣列2,1,3,8,5,7,6,4,10,在整個過程執行的是順序是途中紅色編號1-20。雖然我們描述中說的是程式先分解,再歸併,但實際過程是一邊分解一邊歸併,前半部分分先排好序,後半部分再拍好,最後整個歸併為乙個完整的序列,途中的merge過程它所在層的兩個序列的merge過程:下圖展示了每個merge過程對作用於陣列的哪部分(紅色)。
整個過程就像乙個動態的樹,執行順序就是對樹的先序遍歷順序。
最後實驗驗證,對10000個倒序的陣列進行排序,直接插入排序需1024ms,二歸併排序只需20ms。
歸併排序詳解
一.概念 歸併是指將若干個已排序的子檔案合併成乙個有序的檔案。二.基本思路 設兩個有序的子檔案 相當於輸入堆 放在同一向量中相鄰的位置上 r low.m r m 1.high 先將它們合併到乙個區域性的暫存向量r1 相當於輸出堆 中,待合併完成後將r1複製回r low.high 中。合併過程中,設定...
歸併排序 詳解
歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用,歸併排序將兩個已排序的表合併成乙個表。優點1.歸併排序的效率達到了巔峰 時間複雜度為o nlogn 這是基於比較的排序演算法所能達到的最高境界 2.歸併排序是一種穩定的...
歸併排序詳解
分治法在每層遞迴時都有三個步驟 1.分解原問題為若干個子問題,這些子問題是原問題規模較小的例項 2.解決子問題,遞迴求解各子問題,如果子問題規模足夠小,則直接求解 3.合併子問題得到原問題的解。歸併排序完全遵循分治法 1.分解待排序的n個元素的序列,分成各具有n 2個元素的兩個子串行 2.使用歸併排...