线性时间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 ...
随机推荐
- cocoaPods 的使用
打开 终端 1. 移除系统自带的 因为该rub已经被和谐了 使用ruby.taobao.org MCJ:~ MCJ$ sudo gem sources -l *** CURRENT SOURCES * ...
- springMVC 学习(一)
本文主要介绍springmvc的框架原理,并通过一个入门程序展示环境搭建,配置以及部署调试. springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合 ...
- (转)Tomcat7+Redis存储Session
原创http://blog.csdn.net/caiwenfeng_for_23/article/details/45666831 PS:截止到2015-05-12前是不支持Tomcat8的,详情见官 ...
- spring 的IoC的个人理解
1.ioc IoC的概念介绍 ( a).依赖注入, 分为依赖 和 注入 , 其实依赖是一种耦合方式, 通过spirng在运行时将这种依赖关系完成, 达到解耦目的, 同时达到代码重用, 方便测试,更加 ...
- js冒泡排序
今天面试了家公司,最后要写个js的简单数组排序,很久都写不出来,好尴尬,随着语言的发展,这些简单方法越来越不被重视了... <html> <head> <script t ...
- 我为什么喜欢用C#来做并发编程
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:就语言和运行时层面,C#做并发编程一点都不弱,缺的是生态和社区. 硅谷才女朱赟(我的家 ...
- HTTP错误500.19-定义了重复的节点
打开服务器的asp.net页面时出现这个错误: HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效. 解决办法: 打开II ...
- Word中一些问题解决
word图片不显示或显示不全怎么办? http://jingyan.baidu.com/article/0f5fb099c5cb7a6d8334ea06.html
- JAVA Day8
1. 引用数据类型需要new 2. 字符串使用的3种方式 String s = "hello world"; String s = new String(); String s = ...
- js 封装设计cookie
http://www.imooc.com/article/12700<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional/ ...