分治法下的歸並算法(merge sort)
分支模式的三個步驟:
分解:將原問題分解為若干個子問題,子問題為原問題規模較小的問題
解決:遞歸求解子問題,若足夠小,直接求解
合並:將子問題的解合並為原問題的解
歸並算法(merge sort)
分解:分解待排序的n個元素的序列成各具n/2個元素的子序列
解決:使用歸並算法解決兩個子序列的排序
合並:合並兩個已排序的子序列
偽代碼實現歸並的過程
MERGE(A,p,q,r) //A代表一個數組,pqr分別代表下標(p<=q<r) 1 n1 = q-p+1 2 n2 = r-q 3 let L[1,2…,n1+1] and R[1,…n2+1] be new arrays 4 for i = 1 to n1 5 L[i]=A[p+i-1] 6 for j=1 to n2 7 R[j]=A[q+j] 8 L[n1+1]=∞ 9 R[n2+1]=∞ 10 i=1 11 j=1 12 for k = p to r 13 if L[i] <= R[j] 14 A[k]=L[i] 15 i = i+1 16 else A[k] =R[j] 17 j=j+1
這里是歸並過程的偽代碼,歸並過程作為本算法的另一個核心,其代碼過程也充分體現了排序的過程
總程序
MERGE-SORT(A,p,r) 1 if p<r 2 q=(p+r)/2 3 MERGE-SORT(A,p,q) 4 MERGE-SORT(A,q+1,r) 5 MERGE(A,p,q,r)
這里的總程序運用了遞歸的思想,這樣達到了將程序分解的目的,同時也體現了分治的思想
c++語言實現函數(僅有函數部分,未經過測試)
1 const int maxn= 100; 2 const int max = 100000; 3 int * Merge(int * &A,int p,int q,int r) 4 { 5 int L[maxn]={0}; 6 int R[maxn]={0}; 7 int n1=q-p+1; 8 int n2=r-q; 9 for(int i=0;i<n1;i++) 10 L[i]=A[p+i-1]; 11 for(int j=0;j<r;j++) 12 R[j]=A[q+j]; 13 L[n1+1]=max; 14 R[n2+1]=max; 15 int a=1,b=1; 16 for(int i=p;i<r;i++) 17 { 18 if(L[a]<=R[b]) 19 { 20 A[i]=L[a]; 21 a++; 22 } 23 else 24 { 25 A[i]=R[b]; 26 b++; 27 } 28 } 29 return A; 30 } 31 32 void MergeSort(int * &A,int p,int r) 33 { 34 if(p<r) 35 { 36 int q=(p+r)/2; 37 MergeSort(A,p,q); 38 MergeSort(A,q+1,r); 39 Merge(A,p,q,r); 40 } 41 }