快速排序,变形题目

目录

题目一

题目二 


不多说我们先看快排是怎么写的

题目一

其实说白了这个排序直接调用内置函数sort()就可以做排序了,但我们还是分析以下快排的代码

帮助理解下一道题目

代码逻辑

 难点就是理解做递归的这个过程

以  3 2 1 4 5 为例子
我是这样理解递归的
递归在我看来就是将原来的一个大的集合,拆分成小的集合,然后先对小集合操作,再对每个小集合进行合并
所以在看的时候是从小往大看的,即先对一个元素操作,再加入一个元素,每次操作完再加入一个元素

就像这里 我们是随便取一个序列中间的值x然后把比这个x小的数字放在x左边,比它大的放在右边
那么我们随便取一个元素
例如2 2就不需要操作 我们添加一个元素 
(因为我对于一串数字而言 2 1 下标同时减去一个数字 相对顺序是不变的 不影响结果)
2 1 那么选组中间的那个数值x=q[0+1>>1]=2     0+1>>1 等价于0+1 除2
1比x小放到 进行操作完后的结果就是 1 2

那么我们再加入一个元素3
现在就是3 1 2
同样x=q[0+2>>1]=1
所以进行操作 1 3 2 此时x=3 继续操作 得到1 2 3 
这样去想就会好理解很多

#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int n;      //表示数量
int q[N];   //存储数字序列

void quick_sort(int q[],int l,int r)    //l表示左边界 r表示右边界
{
    if(l>=r) return;                    //如果左边界大于等于右边界结束退出
    
    int i=l-1,j=r+1,x=q[l+r>>1];        //i记录左边界 做移动 r记录有边界 做移动
    while(i<j)                          // x表示中间的数值 
    {
        do i++;while(q[i]<x);           //如果左边的数小于x进行移动
        do j--;while(q[j]>x);           //如果右边的数大于x进行移动
        if(i<j) swap(q[i],q[j]);        //如果现在的左边界还小于右边界 进行交换
    }
    
    quick_sort(q,l,j);                  //递归求解
    quick_sort(q,j+1,r);
}
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",&q[i]);
    
    quick_sort(q,0,n-1);
    
    for(int i=0;i<n;i++) printf("%d ",q[i]);
    return 0;
}

题目二 

原理就是k是个下标

如果以新区间的左端点为起始位置, 形成一个新的k,区间内做个排序,指向的依然是我要找的q[k]

#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int q[N];
int n,k;

int  quick_sort(int l,int r,int k)
{
    if(l>=r) return q[l]; //返回第一个大于等于x的数字
    int i=l-1,j=r+1,x=q[l+r>>1];
    while(i<j)
    {
        do i++;while(q[i]<x);
        do j--;while(q[j]>x);
        if(i<j) swap(q[i],q[j]);
    }
    
    int s=j-l+1;  //这里用来判断k在那一部分里 用来减少计算
    if(k<=s) return quick_sort(l,j,k);
    else return quick_sort(j+1,r,k-s);
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++) scanf("%d",&q[i]);
    
    cout<<quick_sort(0,n-1,k);
    
    
}

题目来源acwing 

模板来源:闫学灿
链接:https://www.acwing.com/activity/content/code/content/57785/
来源:AcWing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值