/******************************** * 分治排序法 * * A代排序数组 * * p 排序数组的开始下标 * * q 排序数组的中间下标 * * r 排序数组的结束下标 * ********************************/ #include<iostream> using namespace std; void merge(int A[], int p, int q, int r ){ int nl=q-p+1; int nr=r-q; int *L=new int[nl]; int *R=new int[nr]; for(int i=0;i<nl;i++){ L[i]=A[p+i]; } for(int j=0;j<nr;j++){ R[j]=A[q+j+1]; } int m=0; int n=0; //————打印中间的排序过程————– // cout<<“L(“<<nl<<“):”; // for(int i=0;i<nl;i++){ // cout<<L[i]<<” “; // } // cout<<endl; // cout<<“R:(“<< nr <<“):”; // for(int i=0; i<nr; i++ ){ // cout<<R[i]<<” “; // } // cout<<endl; //—————————————– for(int i=p;i<=r;i++){ if(m<nl && n<nr){ A[i]=L[m]<R[n]?L[m++]:R[n++]; } else{ if(m<nl){ A[i]=L[m++]; } else{ A[i]=R[n++]; } } } delete [] L; delete [] R; } void mergeSort(int A[], int p, int r ){ if(p<r){ int q=(p+r)/2; cout<<“一半:”<<q<<endl; mergeSort( A, p, q); mergeSort( A, q+1, r); merge( A, p, q, r); } } int main() { int a[]={3,9,3,20,21,54,32,45,66,32,1,0,10,5}; int total=sizeof(a)/sizeof(int); cout<<“排序前:”; for(int i=0;i<total;i++){ cout<<a[i]<<” “; } cout<<endl; cout<<“总数:”<<total<<endl; mergeSort(a,0,total-1); cout<<“排序后:”; for(int i=0;i<total;i++){ cout<<a[i]<<” “; } cout<<endl; }
分治法的每一层递归上都有三个步骤:
分解:将原问题分解为若干小问题
解决:递归的解决各子问题,当子问题足够小,可直接求解。
合并:将子问题的结果合并成原问题的解。
在合并排序中:
分解:将数组中n个元素分解成两个含有n/2个子元素的两个数组。
解决:用合并排序法对两个子数组进行递归排序
合并:合并两个排序好的数组,组成最后的结果。