此篇只說此方法排序的難點
和易錯點。
#include //合併過程
int maxn=1000;
void merge(int a,int l1,int r1,int l2,int r2)else
} while(i<=r1)
while(j<=r2)
//就在當前陣列中重新賦值
for(int i=0;i既是易錯點,也是難點的就是min()函式,很多人思考此題並沒有想過這裡的min()函式作用。
在**中min()函式用在了判斷r1,和r2的下標上(待合併序列的右端點下標)。
易錯的寫法為:r1=l1+width-1,r2=l1+2width-1,
那麼問題來了,使用min()的意義在於?
你有沒有考慮過r1,r2會越界?
用上述的例子,首先來看r2。
第一次排序後有:78 56 34 2
繼續第二次排序width==2時,在這裡就能看出r2的問題了:r2顯然越界了!
那麼r1又什麼時候會越界呢?
當第四次排序width==4時候,你會驚訝的發現r1超出陣列長度,
其實呢當r1越界了那麼代表l2,r2也都越界了。
本次分析到此結束。
題外話,思考下l2其實不用使用min函式,為什麼不會錯誤?
2 路歸併排序的非遞迴寫法
演算法筆記 中摘取 2 路歸併排序的非遞迴寫法主要考慮到這一點 每次分組時組內元素個數上線都是2的冪次。於是就可以想到這樣的思路 令步長step的初值為2,然後減陣列中每個step個元素作為一組,將其內部進行排序 即把左step 2個元素與右step 2個元素合併,而若元素個數不超過step 2,則...
歸併排序(遞迴 非遞迴 自然歸併排序)
演算法思想 歸併排序是分治法的典型應用,其思想是不斷地將兩個有序的陣列合併為乙個有序陣列。遞迴實現 include void merge int a,int left,int m,int right void mergesortaux int a,int left,int right void me...
歸併排序(2 路歸併排序)
遞迴寫法 include define maxn 100 void merge int a,int l1,int r1,int l2,int r2 將陣列a的區間 l1,r1 和區間 l2,r2 合併為乙個有序區間 else while i r1 while j r2 for int i 0 i非遞...