關於分治法歸併排序的個人筆記
阿新 • • 發佈:2019-02-10
一.分治法
1. 定義 將原問題分解成兩個或者更多的相似的子問題,再用同樣的方法分解子問題,直到子問題可以輕鬆求解,原問題的解就是子問題解的集合。
2.步驟 分解:分解原問題為若干個子問題。
解決:求解子問題,遞迴的求解子問題。
歸併:子問題的解的集合就是原問題的解。
二.歸併排序
1. 演算法思想:遵循分治法思想,首先分解原問題,將待排序的n個元素的序列分解成兩個具有n/2個元素的子序列。然後使用歸併並排序遞迴地排序兩個子序列。最後合併兩個已經排序的子序列得到已排序的原問題的解。
2. 演算法過程:歸併排序中的關鍵步驟在於合併兩個已排序的序列,我們需要呼叫一個輔助過程MERGE(A,p,q,r)來完成合並過程,其中A表示陣列,p、q、r都是陣列下標,其中A[p…q]和A[q+1…r]代表已排序的兩個序列。
關於MERGE(A,p,q,r)函式的虛擬碼如下:
MERGE(A,p,q,r)
1. n1=q-p+1;
2. n2=r-q;
3. int B[1...n1+1],C[1...n2+1];//定義兩個輔助陣列
4. for i=1 to n1 do
5. B[i]=A[i+p-1];
6. for j=1 to n2 do
7. C[j]=A[j+q];
8. B[n1+1]=∞,C[n2+1]=∞;//哨兵作用
9. i=1,j=1;
10. for k=p to r
11. if(B[i]>C[j])
12. A[k]=C[j];
13. j++;
14. else
15. A[k]=B[i];
16. i++;
然後是歸併排序的虛擬碼:
MERGE-SORT(A,p,r)
1.if p<r
2. q=(p+q)/2;
3. MERGE-SORT(A,p,q);
4. MERGE-SORT(A,q+1,r);
5. MERGE(A,p,q,r);
測試:
#include <iostream>
#define INF 10000000
using namespace std ;
void Merge(int *A,int p,int q,int r)
{
int n1=q-p+1;
int n2=r-q;
int* B = new int[n1+1];
int* C = new int[n2+1];
for(int i=0;i<n1;i++)
{
B[i]=A[i+p];
}
for(int i=0;i<n2;i++)
{
C[i]=A[i+q+1];
}
B[n1]=INF;
C[n2]=INF;
int i=0,j=0;
for(int k=p;k<=r;k++)
{
if(B[i]>C[j])
{
A[k]=C[j];
j++;
}
else
{
A[k]=B[i];
i++;
}
}
}
void Merge_Sort(int* A,int p,int r)
{
if(p<r){
int q=(p+r)/2;
Merge_Sort(A,p,q);
Merge_Sort(A,q+1,r);
Merge(A,p,q,r);
}
}
int main()
{
int A[5]={1,4,7,2,5};
Merge_Sort(A,0,4);
for(int i=0;i<5;i++)
{
cout<<A[i]<<endl;
}
return 0;
}
時間複雜度:O(nlogn)