快速选择

来源:互联网 发布:安卓打开java闪退 编辑:程序博客网 时间:2024/06/06 07:50

查找集合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
原创粉丝点击