class QuickSort
{
private:
int *arr;//待排序数组
int length;//数组长度
public:
//构造函数
QuickSort(int length)
{
arr=new int[length+1];
this->length=length;
}
//交换函数
void swap(int i,int j)
{
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//输入数据
void input()
{
int i=1;
while(i<=length)
{
cin>>arr[i];
++i;
}
}
//输出函数
void display()
{
int i=1;
while(i<=length)
{
cout<<arr[i]<<" ";
++i;
}
cout<<endl;
}
//随机化划分函数
int randomizedPartition(int start,int end)
{
int i=start+rand()%(end-start+1);//产生随机数start~end
swap(i,start);//交换元素
return partition(start,end);//返回划分位置
}
//划分函数
int partition(int start,int end)
{
int key=arr[start];//arr[start]作为划分关键字
int i=start;
int j=end;
//交换元素
while(true)
{
while(arr[i]<key)
{
++i;
}
while(arr[j]>key)
{
--j;
}
//寻找两个可以交换的元素
//如果j<=i,说明arr[j]在左半域,arr[i]在右半域,划分完成,在j,j+1之间划分
if(i<j)
{
swap(i,j);
++i;
--j;
}
else
{
return j;
}
}
}
//快速排序
void quickSort(int start,int end)
{
if(start<end)//起码有2个元素
{
int middle;
middle=randomizedPartition(start,end);
quickSort(start,middle);
quickSort(middle+1,end);
}
}
//线性时间选择第k小元素
int randomizedSelect(int start,int end,int k)
{
if(start==end)//如果有两个元素的段被随机化划分之后,则应该有此等式成立,即找到了第K小元素
{
return arr[start];
}
else
{
int middle=randomizedPartition(start,end);
int left=middle-start+1;
if(k<=left)
{
return randomizedSelect(start,middle,k);//在划分后的左侧寻找第k小元素
}
else
{
return randomizedSelect(middle+1,end,k-left);//在划分后的右侧寻找第k-左段长度小的元素
}
}
}
};
void main()
{
QuickSort test(10);
test.input();
test.display();
cout<<test.randomizedSelect(1,10,3)<<endl;//寻找第3小元素
test.quickSort(1,10);//随机化快速排序
test.display();//打印结果
}