所謂歸併排序,就是把一段需要排序的序列分成2部分,分別完成排序之後,然後進行合併,從而完成對整個序列的排序。眾所周知,歸併排序用了分治的思想,即把原任務分成和原任務相同,但規模更小的幾個子問題。分別解決,從而達到解決原問題的效果。
ex:給定以下陣列a[10]=,要求按從大到小的順序排序,歸併的思路如下:
1.將其分成兩部分6 5 7 1 4 和 3 2 5 9 8
2.(以前半部分為例,下同)顯然需要繼續分,前半部分分成 6 5 7 和1 4,
3.再次分成 6 5 和 7
4.將 6 5分成 6 和5
5.接下來就是歸併了,歸併函式merge()裡有兩個"指標",記錄兩部分的頭,然後分別進行比較,將小的(或大的)先放在b陣列裡,比如對以上過程,先放5,再放6,放好之後拷貝進原陣列,再與上次分好的進行比較,放7,以此類推(即新的組裡的每乙個元素都需要比較,而不是簡單的與排好的部分首元素或者尾元素比較),如何讓它回到上層呢,由此很自然想到遞迴解決。
**如下:
#include usingnamespace
std;
void sort(int a,int m,int n,int
b);void merge(int a,int m,int k,int n,int
b);int *a;
int *b;
intmain()
void sort(int *a,int m,int n,intb)}
void merge(int a,int m,int k,int n,int
b)
while(p1<=k)
b[pb++]=a[p1++];
while(p2<=n)
b[pb++]=a[p2++];
for(int i=0;i1;++i)
a[m+i]=b[i];
}
好了,既然已經掌握了歸併排序,接下來我們再來看乙個排序——快速排序。
同樣是分治的思想,同樣是剛才的陣列,具體怎麼實現排序呢。
1.我們選擇乙個標記數字,方便起見,選擇a[0],令k=a[0]
2.將比a[0]小的數移動到a[0]的左邊,比a[0]大的數移動到a[0]的右邊,例如,對於6 ,5 ,7 ,1 ,4 ,3 ,2 ,5 ,9 ,8,a[0]=6,設定乙個i,j分別從第乙個和最後乙個位置開始(即i=0,j=9),首先從j開始,此時i=0,如果a[j]>=k,--j,否則交換a[j],a[i],得到5,5,7,1,4,3,2,6,9,8,接下來j停止,從i開始,如果a[i]3.陣列已經被分成6左邊的和右邊的兩部分,此時我們繼續按步驟2對左右兩部分進行處理,一直處理到只剩下乙個數(遞迴終止條件),就可以得到我們想要的結果了。
**如下:
#include usingnamespace
std;
int b[10]=;
void swap(int &a,int &b);
void quicksort(int a,int s,int
e);int
main()
void swap(int &a,int &b)
void quicksort(int a,int s,int
e) quicksort(a,s,i-1
); quicksort(a,i+1
,e);
}
以上就是分治之歸併排序,快速排序了,如有什麼疏漏的地方和不足之處,歡迎批評指正。。。
分治之歸併,快速排序
所謂歸併排序,就是把一段需要排序的序列分成2部分,分別完成排序之後,然後進行合併,從而完成對整個序列的排序。眾所周知,歸併排序用了分治的思想,即把原任務分成和原任務相同,但規模更小的幾個子問題。分別解決,從而達到解決原問題的效果。ex 給定以下陣列a 10 要求按從大到小的順序排序,歸併的思路如下 ...
分治法舉例之快速排序,歸併排序
個人理解 分治就是將問題不斷地通過遞迴細化,然後將小的問題進行解決 運用分治策略解決的問題一般來說具有以下特點 1 原問題可以分解為多個子問題 這些子問題與原問題相比,只是問題的規模有所降低,其結構和求解方法與原問題相同或相似。2 原問題在分解過程中,遞迴地求解子問題 由於遞迴都必須有乙個終止條件,...
分治演算法 快速排序,歸併排序
快速排序 分析 資料結構p186.重要 當原始檔有序時複雜度是o n2 此時氣泡排序最好,無序時快速排序是最好的方法。void quicksort int a,int l,int r int i l int j r int x a i a l 即a i 就是第乙個坑 挖坑填數 while j i i...