本文为原创,如需转载,请注明作者和出处,谢谢!

第一种算法是最容易想到的,就是利用快速排序的思想,将一个数组分成以某一个数X为轴,左边的所有的数都比X小,而右边的数都比X大。但我快速排序不同的是,在这个算法中只考虑X的一边,而不是两边都考虑。

如果X的位置是i,那么要得到第k个数,如果k<=i, 那么这个数一定在i的左边,否则在i的右边。

源码如下:

#include <stdio.h>
#include <stdlib.h>
int new_random(int min, int max)
{
    return (min + (int)(((float)rand()/RAND_MAX)*(max - min)));
}
void swap(int *a, int *b)
{
    int c = *a;
    *a = *b;
    *b = c;
}

int partition(int A[], int p, int r)
{
    int i = p - 1, j;
    for(j = p; j < r; j++)
    {
        if(A[j] <= A[r])
        {
            i++;
            swap(&A[i], &A[j]);
        }
    }
    swap(&A[i + 1], &A[r]);
    return i + 1;
}

int randomize_partition(int A[], int p, int r)
{
    int i = new_random(p, r);
    swap(&A[i], &A[r]);
    return partition(A, p, r);
}

//第一种算法
int randomized_select(int data[], int p, int r, int k)
{
    if(k > (r - p + 1)) return 0;
    if(p == r) return data[p];
    int i = randomize_partition(data, p, r);
    //int i = partition(data, p, r); //不好使,死循环, 必须用随机数,在第二步时总是在最大数处划分

int count = i - p + 1;
    if(k <= count)
        return randomized_select(data, p, i, k);
    else
        return randomized_select(data, i + 1, r, k - count);
}

另外一种对这种算法做了一下改进,即将数组每5个数一组进行排序,然后取得它的中位数,再对这些中位数进行排序。然后先出的轴X最比较好的,因此X的左边和右边的数总是很平均,所以平均查找速度更快。算法如下:

void quicksort(int data[], int b, int e)
{
    if(b < e)
    {
        int k = partition(data, b, e);
        quicksort(data, b, k - 1);
        quicksort(data, k + 1, e);
    }
}

int partition1(int A[], int p, int r, int x)
{
    int i = p - 1, j;
    for(j = p; j <= r; j++)
    {
        if(A[j] <= x)
        {
            i++;
            swap(&A[i], &A[j]);
        }
    }
    A[i + 1] = x;
    return i + 1;
}
//第二种算法
int select_new(int data[], int p, int r, int k)
{
    if(r - p < 75)
    {
        quicksort(data, p, r);
        return data[p + k - 1];
    }   
    int i;
    for(i = 0; i <= (r - p - 4) / 5; i++)
    {
        quicksort(data, p + 5 * i, p + 5 * i + 4);
        swap(&data[p + 5 * i + 2], &data[p + i]);
    }
    int x = select_new(data, p, p + (r - p - 4) / 5, (r - p - 4)/10); // 得到更好的轴X
    i = partition1(data, p, r, x);
    int count = i - p + 1; 
    if(k <= count)
        return select_new(data, p, i, k);
    else
        return select_new(data, i + 1, r, k - count);
}

int main()
{
    int data[] = {3, 1, 7, 34, 8, 11, 678, 12, -1, 100};
    printf("%d\n", randomized_select(data, 0, 9, 2));
    int data1[] = {3, 1, 7, 34, 8, 11, 678, 12, -1, 100};
    printf("%d\n", select_new(data1, 0, 9, 2));
   
     return 0;
}

本文转自银河使者博客园博客,原文链接http://www.cnblogs.com/nokiaguy/archive/2008/05/12/1193986.html如需转载请自行联系原作者
银河使者

得到第K个大的数算法研究相关推荐

  1. 【215】第K个大的数,K相关题目-分治、堆应用

    1.从大到小第K个数  在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 ...

  2. 第k个数, (第k个大的数)

    第k个数 给定一个长度为 n 的整数数列,以及一个整数 k,请用快速选择算法求出数列从小到大排序后的第 k 个数. 输入格式 第一行包含两个整数 n 和 k. 第二行包含 n 个整数(所有整数均在 1 ...

  3. 利用快排查询无序数组第k位大的数

    由于快速排序的partion函数返回值是基准值最终的位置,由此可以启发得出当这个位置刚好是第k位时,直接输出它下标对应的值,如果这个位置大于第k位时,则向该基准位置的左边递归:如果这个位置小于第k位时 ...

  4. c语言判断数组里的数据先递增后递减,查找两个有序序数组(一个递增、一个递减)中第K大的数...

    题目不难,关键是边界条件要想清楚.先写一个时间复杂度为O(K) 的解法. #include using namespace std; //a[] increase //b[] decrease //u ...

  5. [leetcode]堆排序 求前k大的数

    前一篇博客中写到了排序算法,其中包含一个堆排序,因此本篇博客讲解堆这个数据结构及其应用. 关于最大堆最小堆以及初始建堆和整理堆在上篇博客中有提及,此处不再赘述.下面讲解一个堆的重要应用,求n个数中前k ...

  6. 大数据新算法在个人信用风险评估模型中使用效果的评估

    风控系统资料 https://www.jianshu.com/p/db2aece905a7 基于大数据和机器学习的Web异常参数检测系统Demo实现 https://www.freebuf.com/a ...

  7. 上海内推 | 上海人工智能实验室招聘大语言模型算法研究实习生

    合适的工作难找?最新的招聘信息也不知道? AI 求职为大家精选人工智能领域最新鲜的招聘信息,助你先人一步投递,快人一步入职! 上海人工智能实验室 上海人工智能实验室(https://www.shlab ...

  8. 【算法与数据结构】在n个数中取第k大的数(基础篇)

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍           在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些以 ...

  9. 【算法】寻找第k大的数

    目录: 1.引子 2.排序解决法 3.类快排解法 4.最小堆解法 1.引子 日常编码中,常见遇到这样的问题,"寻找最大的数",此问题非常容易,可暴力直接遍历找出,也可使用分冶策略找 ...

最新文章

  1. mysql布隆过滤器源码_通过实例解析布隆过滤器工作原理及实例
  2. 比特币现金价格周分析看点:仍维持在1000美元以上的正面区间
  3. python 线程指南
  4. 数据结构源码笔记(C语言):快速排序
  5. 【数据结构与算法】5. C++中 list、deque、vector对比
  6. 18-chown命令
  7. 简单scrapy爬虫实例
  8. matlab fspecial
  9. JavaScript字符转Unicode,顺便说句:GitHub的Oh no页面很亮
  10. 命名问题导致的一个bug
  11. Omni Converter全能转换器安装教程
  12. 嵌入式大神:教你如何从零开始学习路线解析
  13. Channel Splitting Network for Single MR Image Super-Resolution医学图像超分阅读笔记
  14. u盘怎么安装计算机系统,教您如何用u盘装系统
  15. 易建联惨遭雄鹿霸王硬上弓!!!
  16. vue 屏幕自适应及全屏放大缩小
  17. noip2014 总结
  18. 用群晖筑建音乐之「家」
  19. SAP:常用的T-code 收藏
  20. 实用的60个CSS代码片段[下]

热门文章

  1. HDU 3951 (博弈) Coin Game
  2. 在wp7中读取XML的配置文件,Content与Resource的区别
  3. Team Foundation Server (TFS) 2015 安装指导
  4. mysql clickhouse_通过mysql操作clickhouse
  5. 多媒体微型计算机必不可少的硬件,第1章计算机基础知识习题材料.doc
  6. imgaug批量椒盐噪声 python_python手写给图像加椒盐噪声和高斯噪声
  7. css中标签显示模式、块元素、行内元素、行内块元素、显示模式转换
  8. 异常是catch还是throws的简单原则
  9. 如何实现一个简单的RPC
  10. 2021年上半年移动广告流量观察白皮书