// L = 左边起始位置, R = 右边起始位置, RightEnd = 右边终点位置voidMerge( ElementType A[], ElementType TmpA[],int L,int R,int RightEnd ){
LeftEnd = R -1;//左边终点位置。假设左右两列挨着
Tmp = L;//存放结果的数组的初始位置
NumElements = RightEnd - Left +1;while( L <= LeftEnd && R<=RightEnd ){if( A[L]<= A[R]) TmpA[Tmp++]= A[L++];else TmpA[Tmp++]= A[R++];}while( L <= LeftEnd )//直接复制左边剩下的
TmpA[Tmp++]= A[L++];while( R<= RightEnd )//直接复制右边剩下的
TmpA[Tmp++]= A[R++];for( i=0; i<NumElements; i++, RightEnd--)
A[RightEnd]= TmpA[RightEnd];}
递归算法
分而治之
voidMsort( ElementType A[], ElementType TmpA[],int L,int RightEnd ){int Center;if( L<RightEnd ){
Center =( L + RightEnd )/2;Msort( A, TmpA, L, Center );Msort( A, TmpA, Center+1, RightEnd );Merge( A, TmpA, L, Center+1, RightEnd );}}
T
(
N
)
=
T
(
N
/
2
)
+
T
(
N
/
2
)
+
O
(
N
)
−
>
T
(
N
)
=
O
(
N
l
o
g
N
)
T(N)=T(N/2)+T(N/2)+O(N) \space->T(N)=O(NlogN)
T(N)=T(N/2)+T(N/2)+O(N)−>T(N)=O(NlogN)
统一函数接口
voidMerge_sort( ElementType A[],int N ){
ElementType *TmpA;
TmpA =malloc( N *sizeof( ElementType ));if( TmpA !=NULL){Msort( A, TmpA,0, N-1);free( TmpA );}elseError("空间不足");
}
避免了在merge中多次声明临时数组
非递归算法
额外空间复杂度是O(N)
voidMerge_pass( ElementType A[], ElementType TmpA[],int N,int length )//length = 当前有序子列的长度{for( i=0; i<=N-2*length; i +=2*length )Merge1( A, TmpA, i, i+length, i+2*length-1);if( i+length < N )//归并最后两个子列Merge1( A, TmpA, i, i+length, N-1);else// 最后只剩一个子列for( j=i; j<N; j++) TmpA[j]= A[j];}
voidMerge_sort( ElementType A[],int N ){int length =1;//初始化子序列长度
ElementType * TmpA;
TmpA =malloc( N*sizeof( ElementType ));if( TmpA !=NULL){while( length < N ){Merge_pass( A, TmpA, N, length );
length *=2;Merge_pass( TmpA, A, N, length );
length *=2;}free( TmpA );}elseError("空间不足");}
具有稳定性
/* 归并排序 - 递归实现 *//* L = 左边起始位置, R = 右边起始位置, RightEnd = 右边终点位置*/voidMerge( ElementType A[], ElementType TmpA[],int L,int R,int RightEnd ){/* 将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列 */int LeftEnd, NumElements, Tmp;int i;
LeftEnd = R -1;/* 左边终点位置 */
Tmp = L;/* 有序序列的起始位置 */
NumElements = RightEnd - L +1;while( L <= LeftEnd && R <= RightEnd ){if( A[L]<= A[R])
TmpA[Tmp++]= A[L++];/* 将左边元素复制到TmpA */else
TmpA[Tmp++]= A[R++];/* 将右边元素复制到TmpA */}while( L <= LeftEnd )
TmpA[Tmp++]= A[L++];/* 直接复制左边剩下的 */while( R <= RightEnd )
TmpA[Tmp++]= A[R++];/* 直接复制右边剩下的 */for( i =0; i < NumElements; i++, RightEnd --)
A[RightEnd]= TmpA[RightEnd];/* 将有序的TmpA[]复制回A[] */}voidMsort( ElementType A[], ElementType TmpA[],int L,int RightEnd ){/* 核心递归排序函数 */int Center;if( L < RightEnd ){
Center =(L+RightEnd)/2;Msort( A, TmpA, L, Center );/* 递归解决左边 */Msort( A, TmpA, Center+1, RightEnd );/* 递归解决右边 */Merge( A, TmpA, L, Center+1, RightEnd );/* 合并两段有序序列 */}}voidMergeSort( ElementType A[],int N ){/* 归并排序 */
ElementType *TmpA;
TmpA =(ElementType *)malloc(N*sizeof(ElementType));if( TmpA !=NULL){Msort( A, TmpA,0, N-1);free( TmpA );}elseprintf("空间不足");}
/* 归并排序 - 循环实现 *//* 这里Merge函数在递归版本中给出 *//* length = 当前有序子列的长度*/voidMerge_pass( ElementType A[], ElementType TmpA[],int N,int length ){/* 两两归并相邻有序子列 */int i, j;for( i=0; i <= N-2*length; i +=2*length )Merge( A, TmpA, i, i+length, i+2*length-1);if( i+length < N )/* 归并最后2个子列*/Merge( A, TmpA, i, i+length, N-1);else/* 最后只剩1个子列*/for( j = i; j < N; j++) TmpA[j]= A[j];}voidMerge_Sort( ElementType A[],int N ){int length;
ElementType *TmpA;
length =1;/* 初始化子序列长度*/
TmpA =malloc( N *sizeof( ElementType ));if( TmpA !=NULL){while( length < N ){Merge_pass( A, TmpA, N, length );
length *=2;Merge_pass( TmpA, A, N, length );
length *=2;}free( TmpA );}elseprintf("空间不足");}