找出数组中第i小元素(时间复杂度Θ(n)--最坏情况为线性的选择算法
找出数组中第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)--最坏情况为线性的选择算法相关推荐
- python判断数组中是否有重复元素_python经典面试算法题4.1:如何找出数组中唯一的重复元素...
本题目摘自<Python程序员面试算法宝典>,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中. [百度面试题] 难度系数:⭐⭐⭐ 考察频率:⭐⭐⭐⭐ 题目描述 ...
- java数组出现次数最多的数_找出数组中出现次数最多的那个数——主元素问题...
方法一:以空间换时间,可以定义一个计数数组int count[101],用来对数组中数字出现的次数进行计数(只能针对数组中数字的范围1~100),count数组中最大的元素对应的下标,即为出现次数最多 ...
- 9.11排序与查找(三)——给定一个排序后的数组,包括n个整数,但这个数组已被旋转过多次,找出数组中的某个元素...
/** * 功能:给定一个排序后的数组.包括n个整数.但这个数组已被旋转过多次,次数不详.找出数组中的某个元素. * 能够假定数组元素原先是按从小到大的顺序排列的. */ /*** 思路:数组被 ...
- 找出数组中被其他元素整除的元素_「每日一题」数组中重复的数字
题目描述 在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次.请找出数组中任意一个重复的数字. Input ...
- 给定一个排序后的数组,包含n个整数,但这个数组已被旋转过多次,找出数组中的某个元素...
2019独角兽企业重金招聘Python工程师标准>>> /** * 功能:给定一个排序后的数组,包含n个整数,但这个数组已被旋转过多次,次数不详.找出数组中的某个元素. * 可以假定 ...
- c语言实现在数组中找一个数字显示,C语言找出数组中的特定元素的算法解析
问题描述:一个int数组,里面数据无任何限制,要求求出所有这样的数a[i],其左边的数都小于等于它,右边的数都大于等于它.能否只用一个额外数组和少量其它空间实现. 思路:如果能用两个辅助数组,那么相对 ...
- c语言找出一个数组中出现次数最多的那个元素,c语言找出数组中出现次数最多地那个元素...
matlab中如何找出不同维度矩阵出现次数最多的数组并记录其个数 首先是胞矩阵中的序列问题,不妨假设AA{1}是一个多行两列的数据,AA{2}同例.程序如下clcclearallAA{1}=[12;2 ...
- 利用HashMap找出数组中出现次数最多的元素及其次数
我在牛客网上刷题时遇到了这道题目,因为初学Java不久,对Java的应用还不熟悉,刚开始用C语言做没做出来(我太菜了...),接着百度发现竟然可以用HashMap做,仔细一想发现这真是一个好办法(为什 ...
- 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)
1.8*8的棋盘上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下 ...
最新文章
- 工信部:今年将发放5G临时牌照,预计下半年5G手机投放市场
- leetcode 刷题之路 64 Construct Binary Tree from Inorder and Postorder Traversal
- 大学生学python到底有没有有-为什么我会想建议每个大学生都学一点编程?
- 架构设计-业务逻辑层简述
- 数据仓库如何实现湖仓一体数据分析?
- python-模拟property
- 云计算(Cloud Computing)
- ME525+刷机2.3.6版本过程分享
- javascript继承的6种方法
- cents OS 重装yum,配置阿里yum源
- 小迪-65-内网安全
- JAVA8之 日期时间时区之 ZoneId[ZoneOffset, ZoneRegion] 笔记
- 图像形状上下文特征ShapeContexts
- TEWA-700G、TEWA-1000E/G等TEWA系列光猫获取超级密码
- 红帽 -EX200-RHCSA 试题讲解-2
- HTML5 Canvas编写五彩连珠(4):动画
- 询盘获客系统为什么会这么火,你知道吗?
- 离散世界模型,带你轻松玩转 Atari 游戏
- AI视觉识别让无人机巡航拥有智慧之眼
- Linux设备与驱动学习之----什么是驱动