序言

刚开始我认为,寻找第k小的元素:简单呀,先对所有元素排序,之后再找不就完事啦,这时时间复杂度在O(nlgn)。那有没有更好的排序的方法了呢?答案:当然是有的。

算法基本思路:

(1) 当规模小于某一阈值时,直接用排序算法返回结果。
(2) 当n大于阈值时,把n个元素划分为|_ n/5> _|,若n不是5的倍数,则排除剩余元素(不会有影响,这里只是为了求中项mm),分别排序,然后挑出每一组元素的中间值,再在所有的中间值中,递归调用本算法,挑出中间值mm,mm即为中项的中项。
(3) 将所有元素划分为A1、A2、A3三组,分别包含小于、等于、大于mm的元素。
(4)分三种情况,求出第k小元素在这三个数组中的哪一个:

  • a.若A1的元素数量大于等于K,即第K个元素在第一组内:在A1中递归查找第k小元素。

  • b.若A1、A2元素个数之和大于等于K,即中项mm为第K个元素:返回mm

  • c.否则,第K个元素在第三组:在A3中递归寻找第(k-|A1、A2元素数量之和|)小元素。

伪代码



code(已验证)

归并排序:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 100//归并排序
void Mergesort(int *A,int low,int high,int *temp)
{if(low < high){int mid = (high+low)/2;Mergesort(A,low,mid,temp);Mergesort(A,mid+1,high,temp);MERGE(A,low,mid,high,temp);}
}void MERGE(int *A,int low,int mid,int high,int *temp)
{int i=low;int j=mid;int m=mid+1;int n=high;int k=0;//开始合并两个数组;while(i <= j && m <= n){if(A[i] <= A[m]){temp[k++] = A[i++];}else{temp[k++] = A[m++];}}while(i <= j){temp[k++] = A[i++];}while(m <= n){temp[k++] = A[m++];}//把temp数组中的结果装回A数组for(i = 0; i < k; i++){A[i+low] = temp[i];}
}

寻找第k小元素:

//寻找第k小元素
int select_k(int *a,int low,int high,int k)
{int p,q,i,mm; //mm为中项集合的中项int *M = (int *)malloc(N*sizeof(int));int *temp = (int *)malloc(N*sizeof(int)); //辅助数组p = high-low +1; //元素总个数if(p<6)       //若p小于阈值44直接排序得到第k小元素{Mergesort(a,low,high,temp);return a[k];}q = p/5; //将所有元素分成的总组数for(i=1;i<=q;i++){Mergesort(a,low+5*(i-1),low+5*(i-1)+4,temp);M[i] = a[low+5*(i-1)+2];}if(q==1){mm = M[1];}elsemm = select_k(M,1,q,q/2);int count1=1,count2=1,count3=1;int *A1 = (int *)malloc(N*sizeof(int));int *A2 = (int *)malloc(N*sizeof(int));int *A3 = (int *)malloc(N*sizeof(int));for(i=low;i<=high;i++){if(a[i] < mm){A1[count1++] = a[i];}else if(a[i] == mm){A2[count2++] = a[i];}else{A3[count3++] = a[i];}}if(count1-1 >= k){return select_k(A1,1,count1-1,k);}else if(count1-1 + count2-1 >= k){return mm;}else if (count1-1 + count2-1 <k){return select_k(A3,1,count3-1,k-(count1-1)-(count2-1));}elsereturn 0;
}

主函数:

int main()
{int i,a,n;//int num[25] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24};int *num = (int *)malloc(N*sizeof(int));FILE* fp = fopen("2.txt","r");//读文件if(fp==NULL){printf("没找到文件");return 0;}for(i=1;i<12;i++){fscanf(fp,"%d",&num[i]);}fclose(fp);printf("请输入需要查询第k项的数:eg:1,2,3~~");scanf("%d",&n);a = select_k(num,1,11,n);printf("第%d小数为:",n);printf("%d",a);return 0;
}

注意:在寻找第k小元素代码中,一定要对q=1进行判断,mm=M[1].

算法-寻找第k小元素(C)相关推荐

  1. Hoare选择算法 寻找第k小元素C实现 算法的“AWK脚手架和grap运行过程分析”

    现实生活中常有找"最大"."最小"及"中位数"等需求,解决这样的问题不用将整个序列排序.寻找"最大"."最小& ...

  2. 解决寻找第K小元素问题——三种不同的算法实现

    个人原创,禁止转载--Zetrue_Li 问题描述:在一个序列里找出第K小元素 以下程序基于函数 int select_kth_smallest(list q, int k) 实现 :返回向量q中第k ...

  3. 分治法实验-寻找第k小元素

    问题描述 随机生成含有n个不同元素的数组L(n≥10000),要求找出第k小的元素(k≤n),完成下面的任务: (1)设计一个基于排序选择算法程序,编程调试正确(排序算法自己确定). (2)设计一个时 ...

  4. [LeetCode题解]从两个有序数组的并集中寻找第k小元素

    Given two sorted arrays A, B of size m and n respectively. Find the k-th smallest element in the uni ...

  5. 分治算法 求第k小元素 O(n) O(nlog2^n)

    BFPRT算法:时间复杂度O(n)求第k小的数字(分治算法+快排) 各位小伙伴,由于本篇文章代码太过杂乱.我于 2018年12月25日 对文中介绍的算法进行了重写.点击上面的蓝色字体,可以阅读重写后的 ...

  6. C语言寻找第k小元素,小技巧——查找第k小的元素

    今天分享一个小技巧,虽然是小技巧但是还是很有价值的,曾经是微软的面试题.题目是这样的,一个无序的数组让你找出第k小的元素,我当时看到这道题的时候也像很多人一样都是按普通的思维,先排序在去第K个,但是当 ...

  7. 寻找中项和第k小元素c语言,分治法第k小元素poj2104.ppt

    分治法第k小元素poj2104 第六章 分 治 6.1 引言 分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 战略 算法设计技术 划分--治理- ...

  8. 寻找第K大元素的八大算法、源码及拓展

    寻找第K大元素的八大算法.源码及拓展 http://www.cnblogs.com/bethunebtj/p/4861378.html 一.问题描述 所谓"第(前)k大数问题"指的 ...

  9. 快速排序_查找第k小元素

    快速排序_查找第k小元素 以下代码可以从数组a[]中找出第k小的元素. 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的. 请仔细阅读分析源码,填写划线部分缺失的内容. 一个问题,快排你的 ...

最新文章

  1. php 安全基础 第一章简介 原则
  2. idea 设置光标回到上一次位置的快捷键
  3. 图像识别工程师 VS The application has requested the Runtime to terminate it in an unusual way.
  4. 【MORE协议】基于MORE的改进协议设计的MATLAB仿真
  5. maven 版本号插件_测试Maven版本插件自动递增版本号
  6. 【机器学习】 - 使用dlib进行人脸定位,人脸检测,给人脸图片戴口罩
  7. 深度人脸表情识别研究进展
  8. python基础学习笔记(九)
  9. Tomcat启动乱码及IDEA中tomcat信息乱码解决方法
  10. tensorflow精进之路(二十五)——Object Detection API目标检测(下)(VOC数据集训练自己的模型进行目标检测)
  11. php ajax 返回字符串而不是对象
  12. 【光学】基于matlab夫琅禾费圆孔衍射【含Matlab源码 062期】
  13. Unity设置为中文
  14. Windows科研工具
  15. linux启动exe程序命令行参数,Linux可执行文件的启动及命令行参数和环境变量的传递...
  16. WinSnap 截图工具绿色中文特别版
  17. win10应用商店无法打开重新 加载
  18. subplot函数介绍
  19. 粉笔公考——常识专项课——民法典
  20. 编程小白须知,阿里、百度、华为这些大厂都用什么编程语言?别说不知道!

热门文章

  1. 多渠道推广场景下,如何实现 App 用户增长的精准归因?
  2. python中指定最后一个字符_如何从Python字符串中删除最后一个字符?
  3. Android车载嵌入式操作系统(Android Automotive)
  4. C语言地址传递和引用传递
  5. 什么是线下门店陈列洞察?百度AI人工智能
  6. 游戏:致那个曾经热血的青春
  7. 用户研究专题:定量研究
  8. Cookie的理解含义
  9. Windows搭建NTP服务器——搭建时间同步服务器
  10. python神经网络编程 豆瓣,python神经网络图像分类