线性时间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 ...
随机推荐
- PHP 格中方法
1.__tostring()能够直接输出对象 class Ren { public $name; function Run() { echo "跑"; } function __t ...
- xcode 消除警告
项目中引用大量的第三方代码时,这些代码很复杂,不要轻易去改动它,如果编译产生很多警告,该如何消除呢? 1. 最直接.最一劳永逸.最安全的方式,直接找到警告的那段代码,改为不警告.这个方式最安全. 可是 ...
- datepicker使用
JqueryUI作为一个优秀的前端库,被广泛的应用在项目中.之前做的一个排班考勤系统,跟时间打交道较多,对时间控件做过一些对比,觉得jqueryUI里的这个datepicker更为实用,配置起来也简单 ...
- 终端下vim无法输入问题解决
最近回归vim时发现会偶尔出现vim无法输入,但光标在动的情况,一度怀疑是spf13的问题,后来经搜索,才发现是因为vim下,快捷键 Ctrl+s 的功能是停止输入,在IDE下编程时间长了,都有潜意识 ...
- iTextSharp简单生成pdf和操作pdf添加水印
遇到需要导出页面到pdf,并添加pdf水印的业务.稍微研究了下,借阅网友的前车之鉴,经过使用可行之后的代码贴出来,做个记录,也供需要的网友借阅. public class PDFSetWaterMar ...
- [原创]Mac系统下制作OS 10.11安装镜像
一.所需软件 1.从App Store下载OS X El Capitan 10.11.2 ------------------------------------------------------- ...
- iOS Runtime学习笔记
Associated Objects: @interface NSObject (AssociatedObject) @property (nonatomic, strong) id associat ...
- React使用jquery方式动态获取数据
好久没写react了,今天有空写一下来react实现实时请求数据,并刷新数据的小demo. 首先我还是选择了jquery方式中自带的ajax获取数据,首先要引用所需的js包 接下来要写一个自定义的js ...
- web Worker使js实现‘多线程’?
大家都知道js是单线程的,在上一段js执行结束之前,后面的js绝对不会执行,那么为什么标题说js实现‘多线程’,虽然说加了引号,可是标题也不能乱写不是,可恶的标题党? 姑且抛开标题不说,先说我们经常会 ...
- poj1236Network of Schools Tarjan裸题
其实就是手打了个Tarjan的模板 输出的时候注意是入度为0的点的个数和max(入度0的个数,出度0的个数),在n=1时特判为0即可 ——以后图论要渐渐模板化,方便使用 #include <cs ...