快速选择和快速排序类似,将数组分为S1和S2。当K值小于S1的的长度时,对S1进行递归。当k值刚好等于pivot时,那么已经找到了。当k值大于S1长度加一时,对S2进行递归。最后K始终在数组下标k-1的位置。
#include <iostream>
#include <vector>
using namespace std;
template <typename Comparable>
void insertionSort(vector<Comparable> &vec,int left ,int right)
{
for(int p=left+1;p<=right;p++)
{
Comparable tmp=std::move(vec[p]);
int j=p;
for(;j>left&&tmp<vec[j-1];j--)
vec[j]=std::move(vec[j-1]);
vec[j]=std::move(tmp);
}
}
//三位中值分割
template <typename Comparable>
const Comparable & median3(vector<Comparable> & a,int left,int right)
{
int center=(left+right)/2;
if(a[right]<a[left])
std::swap(a[center], a[left]);
if (a[right]<a[center])
std::swap(a[right], a[center]);
if(a[center]<a[left])
std::swap(a[center], a[left]);
std::swap(a[center], a[right-1]);
return a[right-1];
}
template <typename Comparable>
void quickSelect(vector<Comparable> & a,int left,int right,int k)
{
if(left+10<=right) //当数量比较少时,使用插入排序效果较好
{
const Comparable & pivot=median3(a, left, right);
int i=left;
int j=right-1;
for(;;)
{
while (a[++i]<pivot){}
while (pivot<a[--j]){}
if(i<j)
{
std::swap(a[i], a[j]);
}
else
{
break;
}
}
std::swap(a[i], a[right-1]);
if(k<=i)
{
quickSelect(a, left, i-1, k);
}
else if (k>i+1)
{
quickSelect(a, i+1,right,k);
}
}
else
{
insertionSort(a,left,right);
}
}
template <typename Comparable>
void quickSelect(vector<Comparable> & a,int k)
{
quickSelect(a,0,a.size()-1,k);
}
int main(int argc, const char * argv[]) {
// insert code here...
vector<int> a{1,6,3,5,4,6,7,10,2,37,38,12,2,32,5,36,73,224,7,8,2,4,7,2,7,9,0,4,45,34,67,23,
47,45,98,27,56};
int k;
cin>>k;
cout<<endl;
quickSelect(a, k);
std::cout <<a[k-1]<<endl;
return 0;
}