算法-寻找第k小元素(C)
序言
刚开始我认为,寻找第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)相关推荐
- Hoare选择算法 寻找第k小元素C实现 算法的“AWK脚手架和grap运行过程分析”
现实生活中常有找"最大"."最小"及"中位数"等需求,解决这样的问题不用将整个序列排序.寻找"最大"."最小& ...
- 解决寻找第K小元素问题——三种不同的算法实现
个人原创,禁止转载--Zetrue_Li 问题描述:在一个序列里找出第K小元素 以下程序基于函数 int select_kth_smallest(list q, int k) 实现 :返回向量q中第k ...
- 分治法实验-寻找第k小元素
问题描述 随机生成含有n个不同元素的数组L(n≥10000),要求找出第k小的元素(k≤n),完成下面的任务: (1)设计一个基于排序选择算法程序,编程调试正确(排序算法自己确定). (2)设计一个时 ...
- [LeetCode题解]从两个有序数组的并集中寻找第k小元素
Given two sorted arrays A, B of size m and n respectively. Find the k-th smallest element in the uni ...
- 分治算法 求第k小元素 O(n) O(nlog2^n)
BFPRT算法:时间复杂度O(n)求第k小的数字(分治算法+快排) 各位小伙伴,由于本篇文章代码太过杂乱.我于 2018年12月25日 对文中介绍的算法进行了重写.点击上面的蓝色字体,可以阅读重写后的 ...
- C语言寻找第k小元素,小技巧——查找第k小的元素
今天分享一个小技巧,虽然是小技巧但是还是很有价值的,曾经是微软的面试题.题目是这样的,一个无序的数组让你找出第k小的元素,我当时看到这道题的时候也像很多人一样都是按普通的思维,先排序在去第K个,但是当 ...
- 寻找中项和第k小元素c语言,分治法第k小元素poj2104.ppt
分治法第k小元素poj2104 第六章 分 治 6.1 引言 分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 战略 算法设计技术 划分--治理- ...
- 寻找第K大元素的八大算法、源码及拓展
寻找第K大元素的八大算法.源码及拓展 http://www.cnblogs.com/bethunebtj/p/4861378.html 一.问题描述 所谓"第(前)k大数问题"指的 ...
- 快速排序_查找第k小元素
快速排序_查找第k小元素 以下代码可以从数组a[]中找出第k小的元素. 它使用了类似快速排序中的分治算法,期望时间复杂度是O(N)的. 请仔细阅读分析源码,填写划线部分缺失的内容. 一个问题,快排你的 ...
最新文章
- php 安全基础 第一章简介 原则
- idea 设置光标回到上一次位置的快捷键
- 图像识别工程师 VS The application has requested the Runtime to terminate it in an unusual way.
- 【MORE协议】基于MORE的改进协议设计的MATLAB仿真
- maven 版本号插件_测试Maven版本插件自动递增版本号
- 【机器学习】 - 使用dlib进行人脸定位,人脸检测,给人脸图片戴口罩
- 深度人脸表情识别研究进展
- python基础学习笔记(九)
- Tomcat启动乱码及IDEA中tomcat信息乱码解决方法
- tensorflow精进之路(二十五)——Object Detection API目标检测(下)(VOC数据集训练自己的模型进行目标检测)
- php ajax 返回字符串而不是对象
- 【光学】基于matlab夫琅禾费圆孔衍射【含Matlab源码 062期】
- Unity设置为中文
- Windows科研工具
- linux启动exe程序命令行参数,Linux可执行文件的启动及命令行参数和环境变量的传递...
- WinSnap 截图工具绿色中文特别版
- win10应用商店无法打开重新 加载
- subplot函数介绍
- 粉笔公考——常识专项课——民法典
- 编程小白须知,阿里、百度、华为这些大厂都用什么编程语言?别说不知道!