快速排序

顾名思义,快速排序(quicksort)是在实践中最快的一致排序算法,它的平均运行时间是O(NlogN)。该算法之所以特别快,主要是由于非常精炼和高度优化的内部循环。它的最坏情形的性能为O(N^2),但稍加努力就可以改变这种情形。
像归并排序一样,快速排序也是一种分治的递归算法。将数组S排序的基本算法由下列简单的四步组成:
(1)如果S中元素个数是0或1,则返回。
(2)取S中任一元素v,称之为枢纽元(pivot)。
(3)将S-{v}(S中其余元素)划分成两个不相交的集合:S1={x属于S-{v} ,x<=v}和S2={x属于S-{v}|x>=v}。
(4)返回{quicksort(S1),后跟v,继而{quciksort(S2)}.
选取枢纽元的方法
三数中值分割法:
一组N个数的中值是第N/2个最大的数。枢纽元的最好的选择是数组的中值。可是,这很难算出,并且会明显减慢快速排序的速度。这样的中值并没有多大的帮助,因此一般的做法是使用左端,右端和中心位置上的三个元素的中值作为枢纽元。例如,输入为8,1,4,9,6,3,5,2,7,0,它的左边元素是8,右边元素是0,中心位置上的元素是6。于是枢纽元则是v=6。显然使用三数中值分割法消除了预排序输入的不好情形。
小数组
对于很小的数组(N<=20),快速排序不如插入排序好。而且,因为快速排序是递归的,所以这样的情形经常发生。通常的解决方法是,对于小的数组不递归地使用快速排序,而代之以诸如插入排序这样的对小数组有效的排序算法。使用这种策略大约可以节省15%的时间。一种好的截止范围是N=10,虽然在5~20之间任一截止范围都有可能产生类似的结果。

快速排序的驱动程序
/**
* Quicksort algorithm (driver).
* /
template <typename Comparable> 
void quicksort( vector<Comparable> & a)
{
     quicksort(a,0,a.size() -1 );
}
执行三数中值分割方法的程序
/**
* Return median of left, center, and right.
* Order these and hide the pivot.
* /
template <typename Comparable>
const Comparable & median3( vector<Comparable> & a, int left,int right)
{
   int center=(left+right) /2 ;
   if(a[center] <a[left] )
      swap( a[left],a[center]);
   if(a[right] <a[left] )
       swap(a[left],a[right] );
   if(a[right] <a[center] )
       swap( a[center],a[right]);

      //Place pivot at position right -1, because a[right] > a[center]
   swap(a[center],a[right-1]);
   return a[right-1];
}
快速排序的主程序
/**
* Internal quicksort method that makes recursive calls.
* Uses median-of-three partitioning and c cutoff of 10.
* a is an array of Comparable items.
* left is the left-most index of the subarray.
* right is the right-most index of the subarray.
* /

template <typename Comparable>
void quicksort(vector<Comparable> & a, int left, int right)
{
    if( left + 10 <= right )
    {
        Comparable pivot=median3(a,left,right);
             //Begin partitioning
         int i=left,j=right-1;
         for( ; ; )
         {
             while(a[++i] < pivot ) {}
             while(pivot < a[--j] ) {}
             if(i<j)
                 swap(a[i],a[j]);
             else
                  break;
         } 
         swap(a[i],a[right-1] ); //Restore pivot
         quicksort(a,left,i-1);  //Sort small elements
         quicksort(a,i+1,right);  // Sort large elements
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值