快速选择排序----减治法(找到数组中第k个元素)

【问题描述】设无序序列 T =(r1, r2, …, rn),T 的第k(1≤k≤n)小元素定义为T按升序排列后在第k个位置上的元
素。给定一个序列T和一个整数k,寻找 T 的第k小元素的问题
称为选择问题。
当k=1时,相当于找最小值。
当k=n时,相当于找最大值。
当k=n/2时,相当于找中值(中位数)。

#include <iostream>
using namespace std;
int QuickSelect(int a[],int left,int right,int k)
{
    if(left>right)
        return -1;
    int i,j,t,temp;
    temp=a[left];
    i=left;
    j=right;
    while(i!=j)
        //理解为i与j相碰时的空就是temp所在位置
    {
        while(a[j]>=temp&&i<j)
            j--;
        while(a[i]<=temp&&i<j)
            i++;
        if(i<j)
        {
            t=a[i];
            a[i]=a[j];
            a[j]=t;
        }
    }
    a[left]=a[i];
    a[i]=temp;
    if(i==k-1) return a[i];
    else if(i<k-1) return QuickSelect(a,i+1,right,k);
    else return QuickSelect(a,left,i-1,k);
}
int main()
{
    int a[10]={1,3,2,5,9,7,3,6,10,8};
    int k;
    cin>>k;
    cout<<QuickSelect(a,0,9,k)<<endl;
    return 0;
}

时间复杂度分析:
最好情况:每次划分的轴值恰好是序列的中值,则可以保证处理的区间比上一次减半,由于在一次划分(O(n))后,只需处理一个子序列在这里插入图片描述
最坏情况:每次划分的轴值恰好是序列中的最大值或最小值,则处理区间只能比上一次减少1个,所以:
T(n) = T(n-1) + O(n) =O(n2)

平均情况:假设每次划分的轴值是划分序列中的一个随机位置的元素,则处理区间按照一种随机的方式减少,可以证明,算法的平均时间是O(n) 。

发布了19 篇原创文章 · 获赞 2 · 访问量 741

猜你喜欢

转载自blog.csdn.net/qq_45639157/article/details/104929050