找第k小数和中位数算法——快速排序思想,复杂度O(n) C++实现

news/2024/5/19 22:17:19 标签: 算法, 数据结构, 快速排序, 中位数, 第k小

第k小数,可等价于找到一个位置为k的元素,前面的都比它小,后面的都比它大。

采用类似于快速排序的划分方法,但根据情况每次只需处理其中一边。

划分的工作量是O(n),最坏情况下为n;每次都将子问题规模缩小一半,递推方程是:

W(n) = W(n/2) + n
W(1) = 0

迭代法可得W(n) = O(n)

通过计算其平均复杂度也为O(n)(《算法导论》第2版p109)。

代码

#include <iostream>
using namespace std;

void P(int a[],int n); //打印数组
int SelectK(int *S, int l, int r, int k);//找第k小
int Median(int *S, int l, int r);//找中位数

int main()
{
    int n = 10;
    int S[]= {1,3,5,7,9,2,4,6,8,10};
    P(S, 10);
    int k;
    cout << "input k:";
    cin >> k;
    cout << "the " << k << "th min number is: " << SelectK(S, 0, n-1, k-1) << endl;
    //Median(S, 0, n-1);
    cout << "Median is: " << Median(S, 0, n-1) << endl;
    return 0;
}
void P(int a[],int n)
{
    for(int i=0; i<n; i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;
}
int Partition(int *S, int l, int r){
    int i = l;
    int j = r;
    int x = S[l];
    while (i<j){
        while (i<j && S[j]>=x){
            j--;
        }
        if (i<j){
            S[i++] = S[j];
        }
        while (i<j && S[i]<=x){
            i++;
        }
        if (i<j){
            S[j--] = S[i];
        }
    }
    S[i] = x;
    return i;
}
//找第k小数,等价于找到一个位置为k的元素,前面的都比它小,后面的都比它大
int SelectK(int *S, int l, int r, int k){
    int pivot = Partition(S, l, r);
    if (pivot==k){ //找到了位置k,前面的都比它小,后面的都比它大
       return S[pivot];
    }
    else if(pivot>k){ //pivot后面的都比它大,可以忽略了
        return SelectK(S, l, pivot-1, k); //划分前半部分
    }
    else{ //pivot前面的都比它小,也可以忽略了
        return SelectK(S, pivot+1, r, k); //划分后半部分,k是位置,不是第k,所以参数仍然是k
    }
}

//找中位数,如果数组的个数是偶数个,则返回排序后数组的第N/2个数
int Median(int *S, int l, int r){
    return SelectK(S, l, r, (r-l)/2);
}



http://www.niftyadmin.cn/n/905864.html

相关文章

vue--配置多入口程序

1 module.exports { 2 entry: { 3 app:.src/main.js, 4 admin:./src/admin-main.js 5 } 6 } 在多数情况下&#xff0c;程序入口只有一个&#xff0c;就是main.js。但是如果用户使用的是.../index这个网址&#xff0c;而后台提供给登录用户…

求数组出现次数前n个数JAVA_找出数组中出现次数超过数组长度一半的数字java实现...

接下来要给大家带来的是找出数组中出现的次数超过数组长度的一半的一个数字的java实现和思路&#xff0c;一起来看看吧。题目&#xff1a;数组当中有一个数字出现的次数超过了数组长度的一半&#xff0c;请摸找出这个数字。例&#xff1a;输入一个长度为9的数组{1,2,3,2,2,2,5,…

PAT甲级真题 1044 Shopping in Mars (25分) C++实现 (双指针,简单模拟)

题目 Shopping in Mars is quite a different experience. The Mars people pay by chained diamonds. Each diamond has a value (in Mars dollars M$). When making the payment, the chain can be cut at any position for only once and some of the diamonds are taken o…

java hash数据类型_Java数据类型转换那些事儿

1. 自动类型提升当容量小的数据类型的变量与容量大的数据类型的变量做运算时&#xff0c;结果自动提升为容量大的数据类型。大概顺序&#xff1a;byte、char、short —> int —> long —> float —> double特别是当byte、char、short三种类型的变量做运算时&#x…

19-字符切割函数c++模板

https://www.cnblogs.com/stonebloom-yu/p/6542756.html #include <cstring> #include <cstdio> #include <iostream> #include <vector> using namespace std;vector<string> split(const string &str,const string &pattern){//本函数…

PAT甲级真题 1045 Favorite Color Stripe (30分) C++实现 (动态规划,最长不下降子序列(LIS))

题目 Eva is trying to make her own color stripe out of a given one. She would like to keep only her favorite colors in her favorite order by cutting off those unwanted pieces and sewing the remaining parts together to form her favorite color stripe. It i…

php基本的流程控制语句,PHP基础之流程控制语句

PHP 有三大流程控制&#xff1a;顺序控制&#xff0c;分支控制&#xff0c;循环控制。1、顺序控制&#xff1a;就是程序按顺序从上往下一步一步的执行。2、分支控制&#xff1a;程序有选择的执行。又分单分支&#xff0c;多分支&#xff0c;多重分支。a、单分支&#xff1a;基本…

PAT甲级真题 1046 Shortest Distance (20分) C++实现 (环形两点间最小距离,找基准点)

题目 The task is really simple: given N exits on a highway which forms a simple cycle, you are supposed to tell the shortest distance between any pair of exits. Input Specification: Each input file contains one test case. For each case, the first line c…