快速排序
demo
#include <iostream>
using namespace std;
const int N=1e6+10;
int num[N];
void quick_sort(int *q,int low ,int high)
{
if(low >= high)
return ;
int i=low-1,j=high+1,x=q[i+j>>1];
while(i<j)
{
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j) swap(q[i],q[j]);
}
quick_sort(q,low,j);
quick_sort(q,j+1,high);
}
int main()
{
int n,k;
cin>>n;
for(int i=0;i<n;i++)
cin>>num[i];
for(int i=0;i<n;i++)
printf("%d ",num[i]);
return 0;
}
注意点
这里就提一个边界问题,详情可以看我以前发的快速排序模板。
快速排序模板题(第k个数)
demo
#include <iostream>
using namespace std;
const int N=1e6+10;
int num[N];
int quick_sort(int *q,int low ,int high,int k)
{
if(low >= high)
return q[low];
int i=low-1,j=high+1,x=q[i+j>>1];
while(i<j)
{
do i++;while(q[i]<x);
do j--;while(q[j]>x);
if(i<j) swap(q[i],q[j]);
}
if(j-low+1>=k) quick_sort(q,low,j,k);
else quick_sort(q,j+1,high,k-(j-low+1));
}
int main()
{
int n,k;
cin>>n;
cin>>k;
for(int i=0;i<n;i++)
cin>>num[i];
cout<<quick_sort(num,0,n-1,k)<<endl;
return 0;
}
思路解析
(1)当第 k 个数在前段的时候
我们注意这里是要寻找第k个数,所以我们每次排序的时候,只要把含有第k个数的那一段区间进行排序
所以这里我们需要判断第k个数的位置。
这里解释一下 ( j - low + 1 > = k ) 的意思。我们先要知道 j 的位置是我们的分解点,但是我们需要知道 j 包含了第几个数,所以 j - low就是这段区间包含的数,但是这里因为 j 是下标,所以加 1.
例子:0 , 1 当 j 指向了1,low的位置在 0,j - low = 1.
但是这里其实有两个数,我们想要得到正确的数的数量,所以 j - low + 1
回到上面,如果k在前面的区间,那么就是 ( j - low +1) 是包含 k的,所以就是 ( j - low + 1)> = k,所以我们只需要对前面的一段进行排序,反之就对后面那个区间排序。
(2)当第 k 个数在后面一段的时候
这个时候我们需要个更新 k 的值,因为在新的一组数据中,它已经不是第 k 个数了。那么由(1)的推导,我们知道,他是第 k - ( j - low +1)个数了。
(3)第三个问题就是,结束的时候,我们第k个数会在哪个位置,当然因为我们的排序会一直针对它,所以最后递归调用结束的时候 low 或者 high 的位置就是它的位置了。