***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************
隶属于递归与分治
合并排序
问题描述:实现对n个元素的排序。
算法描述:不断将待排序的元素分成大小大致相同的两个子集合各自排序,最终将排序好的两个子集合合并。集合不断递归分下去,直至集合元素个数为1。
算法程序:
<span style="font-family:Comic Sans MS;"> int a[6]={1,6,4,3,5,2},b[6]; template< class Type > void Merge( Type a[] , Type b[] , int left , int mid , int right ) { int i,j,k; i=left; j=mid+1; k=left; while( i<=mid && j<=right ) { if( a[i] < a[j] ) b[k++] = a[i++]; else b[k++] = a[j++]; } if( i <= mid ) { for( ; i <= mid ; ++i ) b[k++] = a[i]; } if( j <= right ) { for( ; j <= right ; ++j ) b[k++] = a[j]; } } template< class Type > void Copy( Type a[] , Type b[] , int left , int right ) { int i; for( i = left ; i <= right ; ++i ) a[i] = b[i]; } template< class Type > void MergeSort( Type a[] , int left , int right ) { if( left < right ) { int i = (left+right)/2; MergeSort(a,left,i); MergeSort(a,i+1,right); Merge(a,b,left,i,right); Copy(a,b,left,right); } }</span>
三个函数:
——MergeSort:对数组a的left到right位置进行排序
——Merge:将a[0:left] 与 a[mid+1:right] 合并到数组b中
——Copy:将数组b,复制到数组a中
算法分析:
Merge和Copy都可以在O(n)时间内算完,因此对n个元素进行排序,最坏情况下所需的计算时间T(n)满足:
T(n)
= O(1)
n≤1
2*T(n/2)+O(n)
n>1
解这个递归方程可得,T(n) = O(n*log(n) )
算法优化:
通过修改分治策略机制,将递归消除。算法MergeSort的递归过程只是将待排序集合一分为二,直至集合剩下一个元素位置,然后不断合并排好序的集合。
因此,我们可以直接相邻的元素两两配对,通过合并算法将它们排序,不断合并,最后达到排序的目的。
优化算法程序:
<span style="font-family:Comic Sans MS;">template< class Type > void Merge( Type a[] , Type b[] , int left , int mid , int right ) { int i,j,k; i=left; j=mid+1; k=left; while( i<=mid && j<=right ) { if( a[i] < a[j] ) b[k++] = a[i++]; else b[k++] = a[j++]; } if( i <= mid ) { for( ; i <= mid ; ++i ) b[k++] = a[i]; } if( j <= right ) { for( ; j <= right ; ++j ) b[k++] = a[j]; } } template<class Type> void MergePass( Type x[] , Type y[] , int s , int n ) { int i = 0; while( i <= n-2*s ) { Merge(x,y,i,i+s-1,i+2*s-1); i=i+2*s; } if( i+s < n ) Merge(x,y,i,i+s-1,n-1); else for(int j = i ; j <= n-1 ; ++j ) y[j] = x[j]; } template<class Type> void MergeSort(Type a[],int n) { Type *b = new Type[n]; int s = 1; while( s < n ) { MergePass(a,b,s,n); s+=s; MergePass(b,a,s,n); s+=s; } }</span>
优化算法分析:
这个就是 自然合并排序算法,按照这个方式进行合并排序所需的合并次数最少。例如对于给出n个元素数组排好序的极端情况的排序,自然合并排序算法不需要执行合并步,而普通合并算法需要执行 log(n) 次合并。因此,此时自然合并排序算法需要O(n)的时间,而普通合并算法需要O(n*log(n))时间。
***************************************转载请注明出处:http://blog.csdn.net/lttree********************************************