時限:1000ms 記憶體限制:10000k 總時限:3000ms
給定乙個數列,用歸併排序演算法把它排成公升序。
第一行是乙個整數n(n不大於10000),表示要排序的數的個數;
下面一行是用空格隔開的n個整數。
輸出排序後的數列,每個數字佔一行。
二路歸併:
自底向上:
自頂向下:
為什麼覺得自頂向下就是比自底向上要先多了一步分解呢……
好像也可以這麼理解,但是需要注意的是陣列按照歸併長度劃分,最後乙個子陣列可能不滿足長度要求,這個情況需要特殊處理。
自頂下下的歸併排序演算法一般用遞迴來實現,而自底向上可以用迴圈來實現。
歸併:(1) 申請空間,使其大小為兩個已經排序序列之和,該空間用來存放合併後的序列;
(2) 設定兩個指標,最初位置分別為兩個已經排序序列的起始位置;
(3) 比較兩個指標所指向的元素,選擇相對小的元素放入到合併空間,並移動指標到下一位置;
(4) 重複步驟3直到某一指標超出序列尾;
(5) 將剩下序列剩下的所有元素直接複製到合併序列尾;
(6) 將排好序的資料複製回原陣列;
(自頂向下)
#include
#include
int n;
int a[
10000];
using namespace std;
intmergesort
(int a,
int low,
int high)
;int
main()
mergesort
(a,0
,n-1);
for(
int j=
0;j)return0;
}void
merge
(int a,
int low,
int mid,
int high)
//之前在這裡少了},導致while迴圈出錯不輸出
while
(i<=mid)
while
(j<=high)
for(k=
0,i=low;i
1;k++
,i++
)free
(temp);}
intmergesort
(int a,
int low,
int high)
return0;
}
(自底向上)
#include
#include
int n;
int a[
10000];
using namespace std;
void
mergesort
(int a,
int n)
;int
main()
mergesort
(a,n)
;for
(int j=
0;j)return0;
}void
merge
(int a,
int low,
int mid,
int high)
//之前在這裡少了},導致while迴圈出錯不輸出
while
(i<=mid)
while
(j<=high)
for(k=
0,i=low;i
1;k++
,i++
)free
(temp);}
void
mergepass
(int a,
int n,
int length)
//一趟二路歸併排序}}
void
mergesort
(int a,
int n)
}
遞迴與分治 歸併排序
描述 給定乙個數列,用歸併排序演算法把它排成公升序。輸入 第一行是乙個整數n n不大於10000 表示要排序的數的個數 下面一行是用空格隔開的n個整數。輸出 輸出排序後的數列,每個數字佔一行。輸入樣例 5 3 2 1 4 5 輸出樣例 1 2345 基本思路 歸併排序是將一組無序的數列,先一分為二,...
分治法之歸併排序(遞迴 分治)
歸併排序 思想 1.分而治之,將乙個無序的數列一直一分為二,直到分到序列中只有乙個數的時候,這個序列肯定是有序的,因為只有乙個數,然後將兩個只含有乙個數字的序列合併為含有兩個數字的有序序列,這樣一直進行下去,最後就變成了乙個大的有序數列 2.遞迴的結束條件是分到最小的序列只有乙個數字的時候 時間複雜...
歸併排序演算法 分治 雙遞迴
歸併排序運用分治演算法與遞迴思想,那麼其雙遞迴究竟是怎樣的呢?今天被困擾了一會一直覺得並沒有完全理解,後通過思考以及查閱資料,弄懂了其遞迴的真正實現過程!寫給已了解歸併排序的coder code void merge int r,int r1,int s,int m,int t 歸併子串行 whil...