问题描述

设计与实现查找数组的中项问题的算法;

解决思路

要找出一个数组的中位数,最简单的方法当然是将数组排序,但快速排序的时间复杂度也需要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 | 通过迭代来学习递归

    文章目录 分治策略和递归 分治策略的步骤 示例1:阶乘问题 示例2:打印数组的值 示例3:在数组中查找目标值 分治策略和递归 分治策略: 是将规模比较大的问题可分割成规模较小的相同问题.问题不变,规模 ...

  2. 数据结构与算法笔记:分治策略之Greatest Slice,2-Way Merge,Counting Inversions,linearSelect,Diameter,Closest Pair

    Divide and Conquer 分而治之概述 分而治之,就像是团队合作,将一项工作分解成不同的成员去处理 一般情况,我们面临的规模比较大,用n来表示,我们会把它分为若干个任务来同步进行处理 一般 ...

  3. 分治策略Divide and Conquer

    在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",通常是递归算法,就是 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最 ...

  4. 递归与分治java策略实验报告_递归与分治策略–计算机算法设计与分析

    递归概念:直接或者间接调用自身的算法,称为递归运算. 分治思想:把一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相等,递归解决子问题后再将结果合并 下方为一些应用函数.因为 ...

  5. 【算法设计与分析】13 分治策略的设计思想

    算法中很多方法都是可以采用分治策略进行设计与优化,那么什么是分治策略?如何使用分治策略进行算法的设计与分析? 文章目录 1. 分治策略的基本思想 1.1 二分检索的设计思想 1.2 二分归并排序的设计 ...

  6. c语言分治法求众数重数_五大常见算法策略之——递归与分治策略

    递归与分治策略 递归与分治策略是五大常见算法策略之一,分治策略的思想就是 分而治之 ,即先将一个规模较大的大问题分解成若干个规模较小的小问题,再对这些小问题进行解决,得到的解,在将其组合起来得到最终的 ...

  7. 分治策略时间复杂度计算

    转发自:https://www.jianshu.com/p/7635e4babff2 文章说明了logN 怎么计算得到的. 维基百科-- 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范 ...

  8. 分治策略——输油管道问题

    分治策略 1.分治策略是对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同. 2.递归地解这些子问题 ...

  9. 算法实验一 递归与分治策略

    递推/递归与分治策略1 实验题目:王老师爬楼梯 题目描述: 王老师爬楼梯,他可以每次走1级或者2级或者3级楼梯,输入楼梯的级数,求不同的走法数.(要求递推求解)如果N很大,需要高精度计算. 输入要求: ...

  10. 算法设计与分析第2章 递归与分治策略

    第2章 递归与分治策略 2.1 递归算法 递归算法:直接或间接地调用自身的算法. 递归函数:用函数自身给出定义的函数.两个要素:边界条件.递归方程 优点:结构清晰,可读性强,而且容易用数学归纳法来证明 ...

最新文章

  1. java Opencv 图片修复 Photo
  2. python主要用于后端开发还是前端,Django是用于前端还是后端?
  3. list-style-type:decimal在IE中显示全是1的解析
  4. 事务隔离级别神话与误解
  5. C#学习笔记——委托机制
  6. poj 1459 Power Network 多源多汇网络流
  7. Java与网络调试助手TCP通信
  8. ProtoBuf生成EmmyLua注解API提示文件(支持复杂的嵌套结构)
  9. 我的八年硕博士生涯——CMU王赟写在入职Facebook之前
  10. 上线啦,PP.io!
  11. Pytorch官方文档个人阅读总结
  12. 最强nba体验服显示服务器正在停机,最强NBA体验服
  13. 在电脑上安装android,在电脑上安装Android模拟器
  14. 解决Heroku“ name is already taken“问题
  15. 微信公众平台模板消息颜色错位bug以及修复
  16. Office2021官方镜像
  17. 华清远见嵌入式学习心得1
  18. Echarts地图实现闪动气泡,或者加载本地图片,改变颜色和symbolSize大小效果
  19. FPGA ISE PROMs下载程序问题
  20. Android 应用开发中国大学生挑战赛

热门文章

  1. 去除IE浏览器弹出窗口
  2. XiaoWei的战斗力
  3. ffmpeg视频中提取语音
  4. 【Unity基础知识之一】 Unity支持 IOS 64-BIT
  5. Python有哪些优势?
  6. 中科院自动化所 模式识别国家重点实验室(NLPR)
  7. 修改Mac 共享Wifi默认的桥接IP
  8. Ctone T01双卡双待Android 2.2的3.5英寸电容式多点触摸的GSM智能手机带GPS无线上网
  9. git rebase使用简介
  10. 雷神笔记本关闭触摸板