快排


前言

快速排序与归并排序都是两个很重要的排序算法。其平均时间复杂度都是nlogn。在数字很大的情况下,sort可能要超时。比如第k个数,逆序对问题。2333,这里必卡sort。


一、快排是什么?

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

二、快排的思想步骤:

1.确定分界点,x= q【l+r>>1】;
2.交换调整区间,使前一个区间的数小于等于x,后一个区间是大于等于x;
3.用步骤1,2递归处理左右两个区间。

三、模板及其应用:

1.快排模板

代码如下(示例):

#include <iostream>
using namespace std;
const int N = 1000010;
int q[N];
void qsort(int q[], int l, int r)
{
    if (l >= r) return;
    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]);
    }
    qsort(q, l, j);   //这里或者改为qsort(q, l, i-1);和qsort(q, l, i);
    qsort(q, j + 1, r);
}
int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]);
    qsort(q, 0, n - 1);
    for (int i = 0; i < n; i ++ ) printf("%d ", q[i]);
    return 0;
}

代码参考

2.第k个数

注意:其实第k个数就是考察会不会用快排来进行优化
题目链接
题目描述:给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数。
输入样例
5 3
2 4 1 5 3
输出样例:
3

AC代码

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
const int N =1e6+9;
int q[N];
void qsort(int l,int r,int k ){
    if(l>=r) return;
    int i = l-1,j= r+1,x=q[(r+l)>>1]; //注意指针在两边
    while(i<j){
        do i++ ;while(q[i]<x);   //一旦相等就不用交换了
        do j-- ;while(q[j]>x);
        if(i < j) swap(q[i],q[j]);
    }//两个指针不可穿过,也可以理解为相遇即停止,x就只是循环时用来作判断的 
    int n = j-l+1;  //记录当层前面半函数作用的数组,一定要用j,避免出错!
    if(k<=n) qsort(l,j,k); //优化; k是指第几个数
    else qsort(j+1,r,k-n);
}
int main(){
    int n ,k;
    scanf("%d%d",&n,&k);
    for(int i = 0;i <n;i++) scanf("%d",&q[i]);
    qsort(0,n-1,k);
    printf("%d",q[k-1]);
}

用j的原因是:划分区间,i左边的都是小于等于x的,右边都是大于等于x的


3.总结

附上各个排序的时间复杂度图
注:稳定性是指排序后,原本相等的两个数排序后会不会改变原来的顺序。
以后有必要的话,再把其他排序算法补全吧,(●’◡’●)。

图片:在这里插入图片描述

但是sort 确实最快的!
STL sort,因为它是经过特殊设置的,在任何情况下都要比快速排序快。sort不是单纯的O(nlog n),而是无限接近于O(n)的。归并排序是比较接近于O(nlog n)的,会比下界为O(n^2)的快速排序稳定。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值