【排序进阶】快速选择算法

一.定义

快速选择算法(Quickselect)是一种在未排序的数组中查找第k小/大元素的算法,时间复杂度为O(n)。它的基本思想是选择一个基准值(pivot),将数组分为两部分,一部分小于等于基准值,一部分大于基准值。然后根据k与基准值的大小关系,选择其中一部分进行递归搜索,直到找到第k小/大元素为止。

快速选择算法和快速排序算法的思路类似,但是快速选择算法只需要对一部分数组进行快速排序,而不需要对整个数组进行排序。因此,快速选择算法的平均时间复杂度为O(n),最坏时间复杂度为O(n^2),但是最坏情况出现的概率很小。

快速选择算法的时间复杂度为O(n),空间复杂度为O(1)

二.基本步骤 

  1. 选择一个基准值pivot,可以选择数组中的任意一个元素。

  2. 将数组分为两部分,一部分小于等于pivot,一部分大于pivot。

  3. 如果k小于等于左边部分的元素个数,那么继续在左边部分中查找第k小元素;否则,在右边部分中查找第k-left个小元素。

  4. 重复步骤2和3,直到找到第k小元素为止。

三.核心代码(注释讲解)  

void search(int left,int right) //递归函数,left和right表示当前搜索的区间
{
    int i=left,j=right,pivot=arr[(left+right)/2]; //取中间值作为基准值
    while(i<=j) //当i<=j时进行循环
    {
        while(arr[j]>pivot) //从右往左找到第一个小于等于基准值的数
            j--;
        while(arr[i]

四.具体题目 

P1923 【深基9.例4】求第 k 小的数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

五.【AC】答案  

#include
#include
using namespace std;

int arr[5000005],k; //定义全局变量,存储输入的数组和要查找的第k小数

inline long long read(){ //快速读入函数
    char cc=getchar();
    long long f=1,ans=0;
    while(cc<'0' ||cc>'9'){
        if(cc=='-')
            f=-1;
        cc=getchar();
    }
    while(cc>='0' && cc<='9'){
        ans=ans*10+ (cc-'0'); //注意这里是ans*10+...
        cc=getchar();
    }
    return f*ans;
}

void search(int left,int right) //递归函数,left和right表示当前搜索的区间
{
    int i=left,j=right,pivot=arr[(left+right)/2]; //取中间值作为基准值
    while(i<=j) //当i<=j时进行循环
    {
        while(arr[j]>pivot) //从右往左找到第一个小于等于基准值的数
            j--;
        while(arr[i]

你可能感兴趣的:(排序专栏,数据结构,排序算法,算法)