查找中位数(分治策略)
问题描述
设计与实现查找数组的中项问题的算法;
解决思路
要找出一个数组的中位数,最简单的方法当然是将数组排序,但快速排序的时间复杂度也需要O(nlogn),我们可以寻找更快的算法来解决。首先对于一个长度为n的有序数组a[n],若n为偶数,则中位数为(a[n/2]+a[n/2-1])/2,若n为奇数,则中位数为a[n/2],那么问题的关键就是找到a[n/2]和a[n/2-1],然而这是在有序数组中的,那么换到无序的数组中,我们可以把问题转换为求数组中第n/2大的和第n/2+1的数,再一般点就是求一个无序数组中第k大的数。那么如何求第k大的数呢,我们可以先在数组中取一个值value,将数组划分为小于value的small,等于value的equal,大于value的big三个部分,分别记三个部分的元素个数为numS、numE、numB,若k<=numS,则说明我们要找的数就在small中,若numS<k<=numS+numE,则说明我们要找的值在equal中,而又因为equal中的值都相等,因此我们要找的值就等于equal中元素的值,若k>numS+numE,则我们要找的数就在big中;在一趟比较完成之后,若我们没有得到我们需要的值,只得到了我们需要的数所在的范围,那么我们可以再对得到的small或big再使用以上算法,直到得到需要的值。
算法描述
选择数组中第k大的数的算法流程图如下:
算法代码
int selectK(int a[], int length, int k)
{ int *small = new int[length]; int *equal = new int[length]; int *big = new int[length]; int value = a[0]; int numS = 0, numE = 0, numB = 0; for (int i = 0; i < length; i++) { if (a[i] < value) { small[numS] = a[i]; numS++; } else if (a[i] == value) { equal[numE] = a[i]; numE++; } else { big[numB] = a[i]; numB++; } } if (k <= numS)return selectK(small, numS, k); else if (k > numE + numS)return selectK(big, numB, k-numS-numE); else return value;
} int main()
{srand((int)time(0));int n;cin >> n;int *array = new int[n];for (int i = 0; i < n; i++){array[i] = rand()%10000;}cout << endl;cout << "中位数是:";if (n % 2 == 0) cout << (float)(selectK(array, n, n / 2) + selectK(array, n, n / 2 + 1)) / 2 << endl;elsecout << selectK(array, n, n / 2 + 1) << endl;delete[] array;system("pause");return 0;
}
算法分析
以下是本算法与快速排序的耗时对比:
数据规模n | 本算法 | 快速排序 |
1000 | 1ms | 1ms |
10000 | 2ms | 2ms |
100000 | 7ms | 28ms |
1000000 | 60ms | 1396ms |
10000000 | 4537ms | 14353ms |
查找中位数(分治策略)相关推荐
- 算法:分治策略和递归1 | 通过迭代来学习递归
文章目录 分治策略和递归 分治策略的步骤 示例1:阶乘问题 示例2:打印数组的值 示例3:在数组中查找目标值 分治策略和递归 分治策略: 是将规模比较大的问题可分割成规模较小的相同问题.问题不变,规模 ...
- 数据结构与算法笔记:分治策略之Greatest Slice,2-Way Merge,Counting Inversions,linearSelect,Diameter,Closest Pair
Divide and Conquer 分而治之概述 分而治之,就像是团队合作,将一项工作分解成不同的成员去处理 一般情况,我们面临的规模比较大,用n来表示,我们会把它分为若干个任务来同步进行处理 一般 ...
- 分治策略Divide and Conquer
在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",通常是递归算法,就是 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最 ...
- 递归与分治java策略实验报告_递归与分治策略–计算机算法设计与分析
递归概念:直接或者间接调用自身的算法,称为递归运算. 分治思想:把一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相等,递归解决子问题后再将结果合并 下方为一些应用函数.因为 ...
- 【算法设计与分析】13 分治策略的设计思想
算法中很多方法都是可以采用分治策略进行设计与优化,那么什么是分治策略?如何使用分治策略进行算法的设计与分析? 文章目录 1. 分治策略的基本思想 1.1 二分检索的设计思想 1.2 二分归并排序的设计 ...
- c语言分治法求众数重数_五大常见算法策略之——递归与分治策略
递归与分治策略 递归与分治策略是五大常见算法策略之一,分治策略的思想就是 分而治之 ,即先将一个规模较大的大问题分解成若干个规模较小的小问题,再对这些小问题进行解决,得到的解,在将其组合起来得到最终的 ...
- 分治策略时间复杂度计算
转发自:https://www.jianshu.com/p/7635e4babff2 文章说明了logN 怎么计算得到的. 维基百科-- 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范 ...
- 分治策略——输油管道问题
分治策略 1.分治策略是对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同. 2.递归地解这些子问题 ...
- 算法实验一 递归与分治策略
递推/递归与分治策略1 实验题目:王老师爬楼梯 题目描述: 王老师爬楼梯,他可以每次走1级或者2级或者3级楼梯,输入楼梯的级数,求不同的走法数.(要求递推求解)如果N很大,需要高精度计算. 输入要求: ...
- 算法设计与分析第2章 递归与分治策略
第2章 递归与分治策略 2.1 递归算法 递归算法:直接或间接地调用自身的算法. 递归函数:用函数自身给出定义的函数.两个要素:边界条件.递归方程 优点:结构清晰,可读性强,而且容易用数学归纳法来证明 ...
最新文章
- java Opencv 图片修复 Photo
- python主要用于后端开发还是前端,Django是用于前端还是后端?
- list-style-type:decimal在IE中显示全是1的解析
- 事务隔离级别神话与误解
- C#学习笔记——委托机制
- poj 1459 Power Network 多源多汇网络流
- Java与网络调试助手TCP通信
- ProtoBuf生成EmmyLua注解API提示文件(支持复杂的嵌套结构)
- 我的八年硕博士生涯——CMU王赟写在入职Facebook之前
- 上线啦,PP.io!
- Pytorch官方文档个人阅读总结
- 最强nba体验服显示服务器正在停机,最强NBA体验服
- 在电脑上安装android,在电脑上安装Android模拟器
- 解决Heroku“ name is already taken“问题
- 微信公众平台模板消息颜色错位bug以及修复
- Office2021官方镜像
- 华清远见嵌入式学习心得1
- Echarts地图实现闪动气泡,或者加载本地图片,改变颜色和symbolSize大小效果
- FPGA ISE PROMs下载程序问题
- Android 应用开发中国大学生挑战赛