找出数组中第i小元素

期望时间复杂度:Θ(n)
最坏情况的时间复杂度Θ(n^2)

int randomized_select(int *array,int start,int end,int index){if(start == end)return array[start];int middle = randomized_partition(array,start,end);int position = middle - start + 1;if(index  == position)return array[middle];else if(index < position)return randomized_select(array,start,middle-1,index);elsereturn randomized_select(array,middle + 1,end,index - position);
}

快速排序的随机划分函数:randomized_partition
>>链接地址

本版本为错误版本,中间的中位数求中位数排序用了插入排序,用插入算法,在最坏的情况下,时间复杂度Ω(n^2)

int select(int *array,int start,int end,int index)
{//if(start == end) return array[start];const int constant_num = 5;int remainder = (end - start + 1) % constant_num;int zero = remainder == 0 ? 0 : 1;int num = (end - start + 1) / constant_num + zero;int *median = new int[num];if(remainder){insertion_sort(array,start + (num - 1 ) * constant_num,start + (num - 1 ) * constant_num + remainder-1);median[num-1] = array[start + (num - 1 ) * constant_num + (remainder - 1)/2];}for (int i = 0; i < num - zero; ++i) {insertion_sort(array,start + i * constant_num,start + (i+1) * constant_num - 1);median[i] = array[start + i * constant_num + constant_num / 2];}insertion_sort(median,0,num-1);int key = median[(num-1) / 2];delete[] median;//划分int middle = partition(array,start,end,key);//递归求解int position = middle - start + 1;if(index == position){return  array[middle];}else if(index < position){return select(array,start,middle-1,index);}else{return select(array,middle + 1,end,index - position);}
}

下面是最坏情况的(当n>70时)时间复杂度Θ(n)
以下是正确版本

int select(int *array,int start,int end,int index)
{if(start == end) return array[start];const int constant_num = 5;int remainder = (end - start + 1) % constant_num;int zero = remainder == 0 ? 0 : 1;int num = (end - start + 1) / constant_num + zero;int *median = new int[num];if(remainder){insertion_sort(array,start + (num - 1 ) * constant_num,start + (num - 1 ) * constant_num + remainder-1);median[num-1] = array[start + (num - 1 ) * constant_num + (remainder-1)/2];}for (int i = 0; i < num - zero; ++i) {insertion_sort(array,start + i * constant_num,start + (i+1) * constant_num - 1);median[i] = array[start + i * constant_num + constant_num / 2];}int key = select(median,0,num-1,num/2 + (num % 2 == 0 ? 0 : 1));delete[] median;//划分int middle = partition(array,start,end,key);//递归求解int position = middle - start + 1;if(index == position){return  array[middle];}else if(index < position){return select(array,start,middle-1,index);}else{return select(array,middle + 1,end,index - position);}
}

辅助函数partition

int partition(int *array,int start,int end,int key)
{for (int i = start; i < end + 1; ++i) {if(array[i] == key){int temp = array[i];array[i] = array[end];array[end] = temp;break;}}int middle = start - 1;for (int i = start; i < end; ++i) {if(array[i] <= key){middle++;int temp = array[i];array[i] = array[middle];array[middle] = temp;}}array[end] = array[middle+1];array[middle+1] = key;return middle + 1;
}

找出数组中第i小元素(时间复杂度Θ(n)--最坏情况为线性的选择算法相关推荐

  1. python判断数组中是否有重复元素_python经典面试算法题4.1:如何找出数组中唯一的重复元素...

    本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. [百度面试题] 难度系数:⭐⭐⭐ 考察频率:⭐⭐⭐⭐ 题目描述 ...

  2. java数组出现次数最多的数_找出数组中出现次数最多的那个数——主元素问题...

    方法一:以空间换时间,可以定义一个计数数组int count[101],用来对数组中数字出现的次数进行计数(只能针对数组中数字的范围1~100),count数组中最大的元素对应的下标,即为出现次数最多 ...

  3. 9.11排序与查找(三)——给定一个排序后的数组,包括n个整数,但这个数组已被旋转过多次,找出数组中的某个元素...

    /**  * 功能:给定一个排序后的数组.包括n个整数.但这个数组已被旋转过多次,次数不详.找出数组中的某个元素.  * 能够假定数组元素原先是按从小到大的顺序排列的.  */ /*** 思路:数组被 ...

  4. 找出数组中被其他元素整除的元素_「每日一题」数组中重复的数字

    题目描述 在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次.请找出数组中任意一个重复的数字. Input ...

  5. 给定一个排序后的数组,包含n个整数,但这个数组已被旋转过多次,找出数组中的某个元素...

    2019独角兽企业重金招聘Python工程师标准>>> /** * 功能:给定一个排序后的数组,包含n个整数,但这个数组已被旋转过多次,次数不详.找出数组中的某个元素. * 可以假定 ...

  6. c语言实现在数组中找一个数字显示,C语言找出数组中的特定元素的算法解析

    问题描述:一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它.能否只用一个额外数组和少量其它空间实现. 思路:如果能用两个辅助数组,那么相对 ...

  7. c语言找出一个数组中出现次数最多的那个元素,c语言找出数组中出现次数最多地那个元素...

    matlab中如何找出不同维度矩阵出现次数最多的数组并记录其个数 首先是胞矩阵中的序列问题,不妨假设AA{1}是一个多行两列的数据,AA{2}同例.程序如下clcclearallAA{1}=[12;2 ...

  8. 利用HashMap找出数组中出现次数最多的元素及其次数

    我在牛客网上刷题时遇到了这道题目,因为初学Java不久,对Java的应用还不熟悉,刚开始用C语言做没做出来(我太菜了...),接着百度发现竟然可以用HashMap做,仔细一想发现这真是一个好办法(为什 ...

  9. 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)

    1.8*8的棋盘上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下 ...

最新文章

  1. 工信部:今年将发放5G临时牌照,预计下半年5G手机投放市场
  2. leetcode 刷题之路 64 Construct Binary Tree from Inorder and Postorder Traversal
  3. 大学生学python到底有没有有-为什么我会想建议每个大学生都学一点编程?
  4. 架构设计-业务逻辑层简述
  5. 数据仓库如何实现湖仓一体数据分析?
  6. python-模拟property
  7. 云计算(Cloud Computing)
  8. ME525+刷机2.3.6版本过程分享
  9. javascript继承的6种方法
  10. cents OS 重装yum,配置阿里yum源
  11. 小迪-65-内网安全
  12. JAVA8之 日期时间时区之 ZoneId[ZoneOffset, ZoneRegion] 笔记
  13. 图像形状上下文特征ShapeContexts
  14. TEWA-700G、TEWA-1000E/G等TEWA系列光猫获取超级密码
  15. 红帽 -EX200-RHCSA 试题讲解-2
  16. HTML5 Canvas编写五彩连珠(4):动画
  17. 询盘获客系统为什么会这么火,你知道吗?
  18. 离散世界模型,带你轻松玩转 Atari 游戏
  19. AI视觉识别让无人机巡航拥有智慧之眼
  20. Linux设备与驱动学习之----什么是驱动

热门文章

  1. linux c之管道的介绍、创建关闭和简单读写(父进程向子进程写入数据)
  2. Android之放大镜实现的两种方式
  3. 字符串之字符数组种是否所有的字符都只出现过一次
  4. Android之如何成为Android高手
  5. oracle使用max提升效率,Oracle调优之利用max与leftjoin来进行不同表之间匹配
  6. 结构体数组排列_学习RTOS(3)数据结构
  7. 年度迷惑新闻:美女其实是个男生?
  8. 堪称经典!这部由苏联最杰出数学家编写的数学教材,为何能大受推崇?
  9. 一分钟教你用Excel从统计局抓数据!
  10. python怎么使用time模块_PYTHON的TIME模块使用