参考算法导论9.3节的内容和这位大神的博客:http://blog.csdn.net/v_JULY_v上对这一节内容代码的实现进行了学习

尝试实现了以查找中位数为前提的select算法。

算法功能:可以确定一个数组中第k大的元素。

算法思想描述如下:

1、将输入n个元素划分为(n/5:向下取整)个组,每组有5个元素。而只有最后一组为数组剩下的(n mod 5)个元素组成。

2、寻找这些组的中位数:通过对每一个小组进行插入排序,确定中位数。保存到数组mid_arr中。(下标:第i组中位数存在第i位上)

3、对2中查找的中位数数组继续递归调用select函数来查找中位数。

4、最后找到中位数的中位数,记为x。以x为枢纽,对数组进行1次划分,设y为比划分低区元素数目+1。划分以后有(n-y)个元素在高区,x为第y小元素。

5、当k==y时 函数结束,返回x值

k<y:对低区调用select函数来寻找第k小个数

k>y:对高区调用select函数来寻找第(k-y)小个元素。k-y是因为已知了y个元素比高区元素小。

具体实现与注释见代码

 #include<iostream>
#include<algorithm>
using namespace std;
const int num=;
const int numdev=num/+;//向上取整
int arr[num];
int mid_arr[numdev]; void insert_sort(int arr[],int left,int r)
{
for(int i=left; i<left+r; i++) //对于传入的数组arr中下标为left到left+r的元素进行插入排序
{
int key=arr[i];
int j=i-;
while(j>left&&arr[j]>key)
{
arr[j+]=arr[j];
j--;
}
arr[j+]=key;
}
}
int find_mid(int arr[],int left,int right)
{
if(left==right) return arr[left]; int index;
for(index=left; index<right-; index+=)
{
insert_sort(arr,index,);
int number=index-left;//中位数的计算与寻找
mid_arr[number/]=arr[index+];//把插入排序后的这一组数字中5组数的中位数放到mid_arr对应下标的位置中 } //对剩余元素的处理
int remain_num=right-index+;//注意这个下标细节,计算最后一组元素的个数
if(remain_num>)
{
insert_sort(arr,index,remain_num-);
int number=index-left;
mid_arr[number/]=arr[index+remain_num/];
} int num_group=(right-left)/-;
if((right-left)%!=) num_group++; if(num_group==) return mid_arr[];
else return find_mid(mid_arr,,num_group);
} int find_mid_index(int arr[],int left,int right,int mid)//寻找中位数的位置
{
for(int i=left; i<=right; i++)
{
if(arr[i]==mid) return i;
}
return -;
}
int quick_select(int arr[],int left,int right,int k)
{
int mid=find_mid(arr,left,right); int index=find_mid_index(arr,left,right,mid);
swap(arr[index],arr[right]);
int pivot=arr[right]; int i=left;
int j=right-;
//按中位数的中位数对数组进行1次划分。
while()
{
while(arr[i]<pivot) i++;
while(arr[j]>pivot) j--;
if(i<j)
swap(arr[i],arr[j]);
else break;
}
swap(arr[i],arr[right]);
/*对于下一次划分的处理*/
int m=i-left+;
if(m==k) return arr[i];
else if(m>k) return quick_select(arr,left,i-,k);
else return quick_select(arr,i+,right,k-m); }
int main()
{
int arr[num]= {,,,,,,,,,,,,,,,,,,,,};
int k=;
int ans=quick_select(arr,,num-,k);
cout<<ans<<endl;
return ;
}

快速选择算法/Select 寻找第k大的数的更多相关文章

  1. 寻找第K大的数

    在一堆数据中查找到第k个大的值. 名称是:设计一组N个数,确定其中第k个最大值,这是一个选择问题,解决这个问题的方法很多. 所谓“第(前)k大数问题”指的是在长度为n(n>=k)的乱序数组中S找 ...

  2. 寻找第K大的数(快速排序的应用)

    有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数.给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在.测试样例:[1,3,5,2,2],5, ...

  3. 数组,寻找第K大的数

    时间复杂度 O(n) def partition(data,left,right): if (len(data)<=0 or left<0 or right>=len(data)): ...

  4. 分治法寻找第k大的数

    利用快速排序的思想·去做 #include<iostream>using namespace std;int FindKthMax(int*list, int left, int righ ...

  5. 算法——得到数据流中前K大的数

    用优先队列 public PriorityQueue<Integer> kthLargest(int k, int[]a) { PriorityQueue<Integer> q ...

  6. [经典算法题]寻找数组中第K大的数的方法总结

    [经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26   字体:[大 中 小] 打印复制链接我要评论   今天看算法分析是,看到一个这样的问题,就是在一堆数据 ...

  7. [SOJ]寻找第k大数字(numberk)

    Description 经过长时间的筹备工作,在Jourk,Ronny,Plipala,阿长,阿沈等人的努力下,DM实验室建立起自己的系列网站,其中包括三个大板块:DMOJ首页.DMOJ论坛.DMOJ ...

  8. Coursera Algorithms week3 快速排序 练习测验: Selection in two sorted arrays(从两个有序数组中寻找第K大元素)

    题目原文 Selection in two sorted arrays. Given two sorted arrays a[] and b[], of sizes n1 and n2, respec ...

  9. 【算法与数据结构】在n个数中取第k大的数(基础篇)

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍            在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些 ...

随机推荐

  1. 后台开发 - DPDK引发的图谱

    关系图谱(点击看完整大图): 部分名词: 名词 全写 解释 备注 DPDK Data Plane Development Kit 数据平面开发套件或叫数据平面开发工具集 Intel开源的快速数据包处理 ...

  2. Linux上的TIME_WAIT和tcp_fin_timeout

    当Linux服务器的TIME_WAIT过多时,通常会想到去修改参数降低TIME_WAIT时长,以减少TIME_WAIT数量,但Linux并没有提供这样的接口,除非重新编译内核. Linux默认的TIM ...

  3. 【笔记】CSS选择器整理(IE低版本支持性测试)

    时间:2015.05.11 参考附件:css选择器.xmind(网友共享) 查看链接:http://www.w3school.com.cn/cssref/css_selectors.asp   htt ...

  4. android-基础编程-democoderjoy-架构篇

    设计这个demo很简单,针对每个控件放到一个listitem中去,主activity继承之listActivity,这样再override其单击效果进入到每个控件. 主界面流程 1.继承 MainAc ...

  5. 堆操作,malloc

    PS:堆空间缺省值都是cd,栈空间缺省值都是cc 内存有四区:栈.全局(静态).常量.除此以外的空间暂时不能随意使用,但是通过malloc函数申请就可以使用了. 利用malloc申请一个int变量,注 ...

  6. 【repost】一探前端开发中的JS调试技巧

    有请提示:文中涉及较多Gif演示动画,移动端请尽量在Wifi环境中阅读 前言:调试技巧,在任何一项技术研发中都可谓是必不可少的技能.掌握各种调试技巧,必定能在工作中起到事半功倍的效果.譬如,快速定位问 ...

  7. poj 2192 Zipper

    题目 刚开始本来觉得可以用队列来写,但是 例如 ta te teta,ta的t先出队列那就不行了,所以还得用dp dp[i][j] 表示A前i个字符与B前j个字符是否能构成C前i+j个字符 要使 dp ...

  8. 一篇谈Flink不错的文章

    精华 : 在执行引擎这一层,流处理系统与批处理系统最大不同在于节点间的数据传输方式.对于一个流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一 ...

  9. nutch相关目录说明

    Nutch数据包含3个目录结构,分别是: 1.Crawldb:用于存储Nutch将要检索的url信息,以及检索状态(是否检索.何时检索) 2.Linkdb:用于存储每一个url所包含的超链接信息(包括 ...

  10. Swift简单实现一个常规条款、免责声明文字+带有链接的展示形式

    效果:   IMG_F08DABE063A6-1.jpeg class DisclamerView: UIView { //@objc weak var vc:UIViewController? // ...