快速排序是实践中已知的最快的排序算法,他的平均运行时间为O(n logn), 最坏情形的性能为O(n^2)。
一:选取枢纽元的几种方法
1:糟糕的方法:通常的做法是选择数组中第一个元素作为枢纽元,如果输入是随机的,那么这是可以接受的。但是,如果输入序列是预排序的或者是反序的,那么依据这样的枢纽元进行划分则会出现相当糟糕的情况,因为可能所有的元素不是被划入S1,就是都被划入S2中。
2:较好的方法:一个比较好的做法是随机选取枢纽元,一般来说,这种策略是比较妥当的。
3:三数取中值方法,例如,输入序列为 8, 1, 4, 9, 6, 3, 5, 2, 7, 0 ,它的左边元素为8,右边元素为0,中间位置|_left+right)/2_|上的元素为6,于是枢纽元为6.显然,使用三数中值分割法消除了预排序输入的坏情形。
二:细节
1、我们要考虑一下,就是如何处理那些等于枢纽元的元素,问题在于当i遇到第一个等于枢纽元的关键字时,是否应该停止移动i,或者当j遇到一个等于枢纽元的元素时是否应该停止移动j。
答案是:如果i,j遇到等于枢纽元的元素,那么我们就让i和j都停止移动。
2、对于很小的数组,如数组的大小N<=20时,快速排序不如插入排序好。
三:代码:
//三数取中分割法
input_type median3( input_type a[], int left, int right)
{
int center;
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] );
/* invariant: a[left] <= a[center]<= a[right] */
swap( &a[center], &a[right-1]); /* hide pivot */
return a[right-1]; /* return pivot */
}
http://blog.csdn.net/v_JULY_v/article/details/6431001