标签:快速排序
查找集合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