【排序】快速排序(复习)

快速排序模板

题目

活动 - AcWing 

解释

  • 模板类型的题目,一些细节点如下
  • 基准数mid一定要是一个数字a[mid]不能是下标
  • i,j先移动后判断
  • 进入更小的区间继续排序时,区间分界为后起步的j

代码段

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
int n, a[N];
void quick_sort(int l, int r)
{
    if (l == r) return;
    int i = l - 1;
    int j = r + 1;
    int mid = a[(l + r) / 2];
    //这里必须确定一个基准数,不能是下标,因为下标的话可能在交换过程中a[mid]被交换
    while (i < j)
    {
        do i++; while (a[i] < mid);
        do j--; while (a[j] > mid);//先移动后判断
        if (i < j) swap(a[i], a[j]);
    }
    quick_sort(l, j);
    quick_sort(j + 1, r);
    //这里以j为区间分界,记住!!
}
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    quick_sort(0, n - 1);
    for (int i = 0; i < n; i++)
        cout << a[i] << ' ';
    return 0;
}

第k小的数

题目

活动 - AcWing

解释

  • 边排序边确定k所在的区间
  • 涉及到排序的模板题,有几个注意点
  • 依旧以j为分界点下标,需要算出j到区间起点的距离,即e=j-l+1
  • 方便与距离k进行比较
  • 然后选择k所在的区间,参考代码内注释(边界问题)

代码段

#include<iostream>
using namespace std;
const int N=1e5+10;
int n,k;
int a[N];
int quick_sort(int l,int r,int k)
{
    if(l==r)return a[l];
    int mid=a[l+r>>1],i=l-1,j=r+1;
    while(i<j)
    {
        do i++;while(a[i]<mid);
        do j--;while(a[j]>mid);
        if(i<j)
        swap(a[i],a[j]);
    }
    int e=j-l+1;
    //这里的e表示在当前区间,j到区间起点的距离长度,k也是距离长度
    if(k<=e)
    //这里防止边界问题,需要记忆一下必须是k<=e,并且将j算入左区间的end
    //j+1算入右区间的begin
       return quick_sort(l,j,k);
    else
        return quick_sort(j+1,r,k-e);
    
  
}
int main()
{
    cin>>n>>k;
    for(int i=0;i<n;i++)
    cin>>a[i];
    cout<<quick_sort(0,n-1,k)<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nathan Qian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值