快速排序
算法概述
void Quicksort( ElementType A[], int N )
{
if( N<2 ) return;
pivot = 从A[]中选一个主元;
将S = { A[]\pivot } 分成2个独立子集:
A1={ a∈S | a<=pivot } 和
A2={ a∈S | a<=pivot };
A[] = Quicksort(A1,N1)∪
{pivot}∪
Quicksort{A2,N2};
}
选主元
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] ) ;
Swap ( & A[ Center] , & A[ Right- 1 ] ) ;
return A[ Right- 1 ] ;
}
子集划分
如果有元素正好等于pivot怎么办?
停下来交换√ 不理它,继续移动指针->会导致主元一直停在一侧,时间复杂度为nlogn
小规模数据的处理
快速排序的问题
解决方案
当递归的数据规模充分小,则停止递归,直接调用简单排序(如插入排序) 在程序中定义一个Cutoff的阈值
算法实现
void Quicksort( ElementType A[], int Left, int Right )
{
if( Cutoff <= Right-Left ) {
Pivot = Median3( A, Left, Right );
i = Left; j = Right-1;
for(;;) {
while( A[++1] < Pivot );
while( A[--j] < Pivot );
if( i<j )
Swap( &A[i],&A[j]);
else
break;
}
Swap( &A[i], &A[Right-1]);
Quicksort(A, Left, i-1);
Quicksort(A, i+1, Right);
}
else
Insertion_Sort( A+Left, Right-Left+1 );
}
void Quick_sort ( ElementType A[ ] , int N)
{
Quicksort ( A, 0 , N- 1 ) ;
}
#include <stdlib.h>
int compare ( const void * a, const void * b)
{
return ( * ( int * ) a - * ( int * ) b) ;
}
qsort ( A, N, sizeof ( int ) , compare) ;
struct Node {
int key1, key2;
} A[ MAXN] ;
int compare2keys ( const void * a, const void * b)
{
int k;
if ( ( ( const struct Node* ) a) -> key1 < ( ( const struct Node* ) b) -> key1 )
k = 1 ;
else if ( ( ( const struct Node* ) a) -> key1 > ( ( const struct Node* ) b) -> key1 )
k = - 1 ;
else {
if ( ( ( const struct Node* ) a) -> key2 < ( ( const struct Node* ) b) -> key2 )
k = - 1 ;
else
k = 1 ;
}
return k;
}
qsort ( A, N, sizeof ( struct Node) , compare2keys) ;
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] ) ;
Swap ( & A[ Center] , & A[ Right- 1 ] ) ;
return A[ Right- 1 ] ;
}
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 ) ;
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 ) ;
}