线性时间O(n)内求数组中第k大小的数
——本文为博主原创,转载请注明出处
因为最近做的WSN(wireless sensor network)实验要求用3个传感器节点接受2000个包的数据并算出一些统计量,其中就有算出中位数这么一个要求,且其按算出数据的时间长短排名给分,所以就在考虑一个线性时间的求第k大小的数的算法。
鉴于传感器只有10k的内存,以及考虑到快排的过程利于简化,所以采用快速排序(以及由之前课程中做的排序算法的测试得知,快排在相同时间复杂度的排序中有较大的优越性,最重要的就是快排好写)。
算法基本思想
快速排序的思想就不做过多的描述了,我们对之进行的改进是,每一趟划分过后,把我们要找的第k位与作为基准数的下标进行比较,如果k大,就在基准数右边的子数组中找,反之就在左边的子数组中找。这样就相当于每次快排过后对左右子数组的双递归被优化成了单侧的递归。
时间复杂度
考虑极端情况,假设数组大小n足够大,在查找的最后一趟(记为第m趟)才找到,第一趟没找到为O(n),第二趟没找到为O(n/2),第m趟没找到为O(n/2m-1),时间复杂度为O(n(1+1/2+....+1/2m-1)),其中1,1/2,....,1/2m-1为q小于1的等比数列,求和的值是个常数设为C(由∑1/2k的收敛性知),则O(n(1+1/2+....+1/2m-1))=O(nC)=O(n)
代码
因为传感器的代码需要用nesC写,所以程序采用C语言实现
- #include <stdio.h>
- int partition(int *a, int low, int high)
- {
- int pivot = a[low];
- while (low < high)
- {
- while (a[high] >= pivot && low < high)
- high--;
- a[low] = a[high];
- while (a[low] <= pivot && low <high)
- low++;
- a[high] = a[low];
- }
- a[low] = pivot;
- return low;
- }
- int quickSortKth(int *a, int low, int high, int k)
- {
- if (low >= high)
- return a[low];
- else
- {
- int mid = partition(a, low, high);
- if (mid > k)
- quickSortKth(a, low, mid - , k);
- else if (mid < k)
- quickSortKth(a, mid + , high, k);
- else
- return a[mid];
- }
- }
- int getKthMax(int *a, int k, int len) {
- , len - , len-k);
- }
- int getKthMin(int *a, int k, int len) {
- , len - , k-);
- }
- int main()
- {
- ] = { ,,,,,,,,,,,,,, };
- int k;
- ]);//获取数组a的大小
- scanf("%d", &k);
- //printf("%d", len);
- printf("result: %d\n", getKthMin(a, k, len));
- ;
- }
结果
三花
2016-12-25
线性时间O(n)内求数组中第k大小的数的更多相关文章
- [经典算法题]寻找数组中第K大的数的方法总结
[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...
- 查找数组中第k大的数
问题: 查找出一给定数组中第k大的数.例如[3,2,7,1,8,9,6,5,4],第1大的数是9,第2大的数是8-- 思考:1. 直接从大到小排序,排好序后,第k大的数就是arr[k-1]. 2. ...
- #7 找出数组中第k小的数
「HW面试题」 [题目] 给定一个整数数组,如何快速地求出该数组中第k小的数.假如数组为[4,0,1,0,2,3],那么第三小的元素是1 [题目分析] 这道题涉及整数列表排序问题,直接使用sort方法 ...
- 选择问题(选择数组中第K小的数)
由排序问题可以引申出选择问题,选择问题就是选择并返回数组中第k小的数,如果把数组全部排好序,在返回第k小的数,也能正确返回,但是这无疑做了很多无用功,由上篇博客中提到的快速排序,稍稍修改下就可以以较小 ...
- 寻找数组中第K大的数
给定一个数组A,要求找到数组A中第K大的数字.对于这个问题,解决方案有不少,此处我只给出三种: 方法1: 对数组A进行排序,然后遍历一遍就可以找到第K大的数字.该方法的时间复杂度为O(N*logN) ...
- 找轮转后的有序数组中第K小的数
我们可以通过二分查找法,在log(n)的时间内找到最小数的在数组中的位置,然后通过偏移来快速定位任意第K个数. 此处假设数组中没有相同的数,原排列顺序是递增排列. 在轮转后的有序数组中查找最小数的算法 ...
- 无序数组中第K大的数
1. 排序法 时间复杂度 O(nlogn) 2. 使用一个大小为K的数组arr保存前K个最大的元素 遍历原数组,遇到大于arr最小值的元素时候,使用插入排序方法,插入这个元素 时间复杂度,遍历是 O( ...
- 求一个数组中第K小的数
面试南大夏令营的同学说被问到了这个问题,我的第一反应是建小顶堆,但是据他说用的是快排的方法说是O(n)的时间复杂度, 但是后来经过我的考证,这个算法在最坏的情况下是O(n^2)的,但是使用堆在一般情况 ...
- 每天一道算法题(32)——输出数组中第k小的数
1.题目 快速输出第K小的数 2.思路 使用快速排序的思想,递归求解.若键值位置i与k相等,返回.若大于k,则在[start,i-1]中寻找第k大的数.若小于k.则在[i+1,end]中寻找第k+st ...
随机推荐
- Spring+SpringMvc+Mybatis框架集成搭建教程五(项目源码发布到GitHub)
一.背景 我们做完了上面的四步操作以后,来把我们写好的项目提交到自己的GitHub仓库进行版本管理,具体步骤如下. 二.提交步骤 1.首先你要保证你已经有GitHub的账号和密码(没有可以去githu ...
- sql单表中某一字段重复,取最近3条或几条数据
order by a.uid,a.id; sql查询语句,针对需求:一个表中某一字段是有重复的数据,针对该字段相同的值只取最近的3条或要求的几条: --记录铭心!
- eclipse 搭建python环境
1.安装eclipse + jdk windows下面就直接下载,双击安装就完了. Linux下: 安装eclipse: 安装完之后,可直接运行eclipse: 快捷方式在: 安装jidk: 2. ...
- Loadrunner监控Linux系统资源
一.安装rsh和rpcbind 1.查看是否安装:rpm -qa |grep rsh 2.安装rsh:yum -y install rsh* 3.yum -y install nfs-utils r ...
- HTML开源框架
swiper http://www.swiper.com.cn/ frawework7 http://framework7.cn/
- python环境变量自动配置脚本(setx使用)
前言 setx不是windows系统自带的工具,需要到微软官网下载,但是有的系统也会自带.(是官方提供的,可放心食用) set和setx都可以用来配置环境变量.他们的不同点在于,set只是临时的修改环 ...
- JS截字符串处理数字,汉字,英文问题
<script> function suolve( str,sub_length ){ var temp1 = str.replace(/[^\x00-\xff]/g,"**&q ...
- HDU 2545 树上战争 (并查集+YY)
题意:给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,lxh和pfz初始时分别站在两个节点上,lxh总是先移动 ,谁当前所在的点被另一个人占据,他就输了比赛,问谁能获胜 比较有意思的 ...
- iOS通知的使用
注册:[[NSNotificationCenter defaultCenter] postNotificationName:@"changeColor" object:self]; ...
- dedecms在首页或列表调取文章内容body的三个方法
有时需要在网站首页或栏目封面上显示几篇文章的内页作为导语或其他什么的,但acrlist标签是不能直接调取body的,这时我们就需要使用以下方法来调取body. 方法一:arcticle 标签 加上ch ...