归并排序(循环)
模块一Merge_pass:
"length = 当前有序子列的长度"
void Merge_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 );
"看看最后剩下几个序列,1个还是2个"
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];
}
接口:
void Merge_Sort( ElementType A[], int N )
{
int length;
ElementType *TmpA;
length = 1; "初始化子序列长度"
TmpA = malloc( N * sizeof( ElementType ) );
if ( TmpA != NULL ) {
while( length < N ) { "length小于N,意味着有序长度小于序列全长,还没排完"
Merge_pass( A, TmpA, N, length );
length *= 2; "在这里做length的更新"
Merge_pass( TmpA, A, N, length );
length *= 2;
}
free( TmpA );
}
else printf( "空间不足" );
}
快速排序
模块一Median3:左中右三个数进行排序
ElementType Median3( ElementType A[], int Left, int Right )
{ "取中位数"
int Center = (Left+Right) / 2;
if ( A[Left] > A[Center] )
Swap( &A[Left], &A[Center] );
if ( A[Left] > A[Right] )
Swap( &A[Left], &A[Right] );
if ( A[Center] > A[Right] )
Swap( &A[Center], &A[Right] );
" 此时A[Left] <= A[Center] <= A[Right] "
"将基准Pivot藏到右边,因为此时right肯定大于center"
"那么center放在right前面,center和right就是有序的"
Swap( &A[Center], &A[Right-1] );
" 只需要考虑A[Left+1] … A[Right-2] "
return A[Right-1]; "返回基准Pivot"
}
模块二:
void Qsort( ElementType A[], int Left, int Right )
{ " 核心递归函数 "
int Pivot, Cutoff, Low, High;
if ( Cutoff <= Right-Left ) { " 如果序列元素充分多,进入快排 "
Pivot = Median3( A, Left, Right ); "选基准"
Low = Left; High = Right-1;
while (1) { "将序列中比基准小的移到基准左边,大的移到右边"
"找到左右两边第一个要对换的元素"
while ( A[++Low] < Pivot ) ;
while ( A[--High] > Pivot ) ;
"这边还是要判断一下Low是否小于High,是否是已经排好的序列了"
if ( Low < High ) Swap( &A[Low], &A[High] );
else break;
}
Swap( &A[Low], &A[Right-1] ); " 将基准换到正确的位置 "
Qsort( A, Left, Low-1 ); " 递归解决左边 "
Qsort( A, Low+1, Right ); " 递归解决右边 "
}
"处理元素较少的时候,快速排序没有简单排序来的快"
else InsertionSort( A+Left, Right-Left+1 ); "元素太少,用插入排序 "
}
接口:
void QuickSort( ElementType A[], int N )
{ " 统一接口 "
Qsort( A, 0, N-1 );
}