快速选择

查找集合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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值