get to the points first. the article comes from lawsonabs!
update on 20200622
在給出真正可執行的**之前,我想給出乙個偽**,畢竟偽**更好理解和記憶。
const
int maxn =
100005
;int arr[maxn]
;int suc[maxn]
;
//歸併排序
//low high分別代表區間的上下限
void
megersort
(int low,
int high)
mergesort(0,4) ->
mergesort(0,2) ->
mergesort(0,1) ->
mergesort(0,0) return ->
mergesort(1,1) return ->
mergesort(0,1) 開始合併 ->
mergesort(2,2) return ->
mergesort(0,2) 開始合併
注意這個合併的基礎是在(0,2)範圍內,因為(0,1)(2,2)都已經合併好了,這個時候就可以對這兩個不同的區間進行合併了。但是如果之前區間(0,1)合併的結果沒有寫到arr陣列中,沒有寫到arr陣列中,就意味著arr陣列中「已排好序」的還沒有序。], 則合併的結果則是無序的,沒有任何意義。
mergesort(3,4) -> 繼續遞迴
mergesort(3,3) ->
mergesort(4,4) ->
mergesort(3,4) -> 開始合併
mergesort(0,4) -> 開始合併
在最後的mergesort(0,4)的合併過程同上述的分析。
具體實現**如下(請記住!)
#include
using
namespace std;
const
int maxn =
100005
;int arr[maxn]
;int suc[maxn]
;void
megersort
(int low,
int high)
int mid =
(low+high)/2
;megersort
(low,mid);;
//左區間
megersort
(mid+
1,high)
;//右區間
int i = low,j = mid+1;
//兩個區間的下限
int tempi = low;
while
(i<=mid && j<=high)
if(arr[i]
> arr[j])}
while
( j<=high )
while
(i <= mid )
for(
int i = low;i<=high;i++)}
intmain()
megersort(0
,n-1);
for(
int i =
0;i) cout << arr[i]
<<
" ";
cout <<
"\n"
;}
3
3 2 1
53 2 4 1 5
55 4 3 3 1
55 4 3 2 1
109 10 3 1 8 2 7 5 4 6
int mid =
(low+high)/2
;megersort
(low,mid);;
//左區間
megersort
(mid+
1,high)
;//右區間
這裡寫的歸併區間是[low,mid]
和[mid+1,high]
,而不是[low,mid-1]
和[mid,high]
。 就拿乙個區間[0,1]
劃分,按前者的方式可以正確得到結果,但是如果按照後者的劃分,則一直會因為區間相同而陷入死迴圈。 排序演算法 2 歸併排序
歸併排序使用了分治的思想,即將乙個陣列的排序分解為兩個子陣列 首先分解為規模更小的子問題 然後對這兩個子陣列分別排序 分而治之 最後對兩個已排序的子陣列進行合併 合併子問題結果 關鍵在於,合併操作只需要o n 的時間複雜度,那麼根據master定理,歸併排序的整體時間複雜度為o lg n 從漸進時間...
演算法模板 歸併排序 超短
歸併排序演算法 字面意思,歸併兩個有序的區間。基於分治思想 應用 排序中最經典,必須掌握 時間複雜度沒有平均和最壞,每次歸併排序時間複雜度都是o nlogn 空間複雜度o n 因為要開額外的陣列來儲存歸併的結果。1.劃分區間一分為二。2.先歸併排序左區間,再歸併排序右區間。3.左右兩個區間都是有序的...
歸併排序模板
歸併 將兩個或兩個以上的有序表組合成乙個新的有序表。一般情況不用這種方式排序,只有在將多個有序序列整合成乙個有序序列是才會用到歸併排序,才能想歸併效率體現的最高。演算法描敘 1 設初始序列含有n個記錄,則可看成n個有序的子串行,每個子串行長度為1。2 兩兩合併,得到 n 2 個長度為2或1的有序子串...