码迷,mamicode.com
首页 > 其他好文 > 详细

快速选择

时间:2015-08-29 18:52:37      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:快速排序

查找集合S中第k个最小元的算法几乎与快速排序相同。事实上,其前三步是一样的。 令|Si|为Si中元素的个数,快速选择的步骤如下:
(1) 如果|S|=1,那么k=1并将S中的元素作为答案返回。如果正在使用小数组的截止方法且|S|<=CUTOFF,则将S排序并返回第k个最小元.
(2)选取一个枢纽元v属于S。
(3)将集合S-{v}分割成S1和S2,就像快速排序中所做的那样。
(4)如果k<=|S1|,那么第k个最小元必然在S1中。在这种情况下,返回quickselect(S1,k)。如果k=1+|S1|,那么枢纽元就是第k个最小元,将它作为答案返回。否则,第k个最小元就在S2中,它是S2中的第(k-|S2|-1)个最小元。我们进行一次递归调用并返回quicksort(S2,k-|S1|-1)。

/**
*Internal selection method that makes recursive calls.
*Uses median-of-three partitioning and a cutoff of 10.
*Place the kth smallest item in a[k-1];
*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.
*k is the desired rank ub the entire array.
*/
template <typename Comparable>
void quickSelect( vector<Comparable> & a,int left, int right,int k)
{
    if(left+110<=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
          //Recurse; pnly this part changes
      if( k<i)
           quickSelet(a,left,i-1,k);
      else if (k == i)
          return pivot;
      else if( k> i+1)
          quickSelect(a,i+1,right,k);
    }
    else //Do an insertion sort on the subarray
        insertionSort(a,left,right);
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

快速选择

标签:快速排序

原文地址:http://blog.csdn.net/hacker_no_1/article/details/48089047

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!