浏览器标题切换
浏览器标题切换end

计蒜客T1746 - 快速排序 - 快排模板题 - 递归写法

时间复杂度

平均情况: Ο(nlogn)

最坏状况下则需要 Ο(n2) 次比较

AC代码(以左边为基准)

#include<iostream>
#include<string>
#include<cmath>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;

int a[100010],n;

void quicksort(int L, int R)
{
    if(L>=R) return;
    int i=L,j=R; // a[L]中存的就是基准数
    while(i!=j)
    {
        //要先从右边开始找(不能交换顺序)
        // (最后交换基准时换过去的数要保证比基准小,因为基准选取数组第一个数,在小数堆中)
        while(a[j]>=a[L]&&i<j) j--;   // 大的放右
        while(a[i]<=a[L]&&i<j) i++; //再找右边的  // 小的放左
        if(i<j) swap(a[i],a[j]);
    }
    swap(a[L],a[i]); // 将基准数归位
    quicksort(L,i-1); // 递归继续处理左边的
    quicksort(i+1,R); // 递归继续处理右边的
}

int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    quicksort(0,n-1);
    for(int i=0;i<n;i++)
        printf("%d ",a[i]);
    cout<<endl;
    return 0;
}

优化过的快排AC代码

这个是以最右边为基准点。

优化:基准点随机选择。

#include<iostream>
#include<string>
#include<cmath>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;

int a[100010],n;

void quicksort(int L,int R)
{
    if(L>=R) return;

    int p=rand()%(R-L+1)+L;  //p就是[L,R)范围内随机生成的基准数下标 (随机下标)
    // 也可以p=L+(R-L)/2; // 或p=(L+R)/2(中间元素下标)

    swap(a[p],a[R]);// 把最后一个数a[R]变成基准数
    int i=L,j=R,x=a[R]; // x是基准数  最右边那个元素定为基准数
    while(i<j)
    {
        while(a[i]<=x&&i<j) i++; // 小的放左
        while(a[j]>=x&&i<j) j--;   // 大的放右
        if(i<j) swap(a[i],a[j]);
    }
    //结束while会出一个新的基准数a[j],j是基准数下标
    //***这个时候i肯定>=j 所以if(i>j)这个条件写不写都ok
    swap(a[j],a[R]); // 将基准数归位
    quicksort(L,i-1); // 递归继续处理左边的
    quicksort(i+1,R); // 递归继续处理右边的
}

int main()
{
    srand(time(0)); //srand(time(NULL));
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    quicksort(0,n-1);
    for(int i=0;i<n;i++)
        printf("%d ",a[i]);
    cout<<endl;
    return 0;
}

优化过的快排代码注意问题

  1. 为什么j不等于R-1,要等于R?

    • 把这两组数据分别代进去走一遍:1 2 或 2 1
  2. 进入while的时候为什么要先让i往右走再让j往左走,而不是先让j先往左i再往右?

    • 把这组数据代入 1 7 8 5 我们会发现,如果先让j先走的话,j和i之后会同时走到数字1这个位置,当while出去的时候,会把1和5进行交换,这样子小的数字就跑到基准数的位置上去了,从而造成错误。
posted @   抓水母的派大星  阅读(80)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2020-03-10 寒假Day47:Power Calculus-IDA*(dfs+剪枝)
点击右上角即可分享
微信分享提示