遞迴分治篇 歸併排序NOJ1002

2021-10-25 07:47:32 字數 2339 閱讀 5478

時限: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...