参考算法导论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个元素比高区元素小。

具体实现与注释见代码

  1. #include<iostream>
  2. #include<algorithm>
  3. using namespace std;
  4. const int num=;
  5. const int numdev=num/+;//向上取整
  6. int arr[num];
  7. int mid_arr[numdev];
  8.  
  9. void insert_sort(int arr[],int left,int r)
  10. {
  11. for(int i=left; i<left+r; i++) //对于传入的数组arr中下标为left到left+r的元素进行插入排序
  12. {
  13. int key=arr[i];
  14. int j=i-;
  15. while(j>left&&arr[j]>key)
  16. {
  17. arr[j+]=arr[j];
  18. j--;
  19. }
  20. arr[j+]=key;
  21. }
  22. }
  23. int find_mid(int arr[],int left,int right)
  24. {
  25. if(left==right) return arr[left];
  26.  
  27. int index;
  28. for(index=left; index<right-; index+=)
  29. {
  30. insert_sort(arr,index,);
  31. int number=index-left;//中位数的计算与寻找
  32. mid_arr[number/]=arr[index+];//把插入排序后的这一组数字中5组数的中位数放到mid_arr对应下标的位置中
  33.  
  34. }
  35.  
  36. //对剩余元素的处理
  37. int remain_num=right-index+;//注意这个下标细节,计算最后一组元素的个数
  38. if(remain_num>)
  39. {
  40. insert_sort(arr,index,remain_num-);
  41. int number=index-left;
  42. mid_arr[number/]=arr[index+remain_num/];
  43. }
  44.  
  45. int num_group=(right-left)/-;
  46. if((right-left)%!=) num_group++;
  47.  
  48. if(num_group==) return mid_arr[];
  49. else return find_mid(mid_arr,,num_group);
  50. }
  51.  
  52. int find_mid_index(int arr[],int left,int right,int mid)//寻找中位数的位置
  53. {
  54. for(int i=left; i<=right; i++)
  55. {
  56. if(arr[i]==mid) return i;
  57. }
  58. return -;
  59. }
  60. int quick_select(int arr[],int left,int right,int k)
  61. {
  62. int mid=find_mid(arr,left,right);
  63.  
  64. int index=find_mid_index(arr,left,right,mid);
  65. swap(arr[index],arr[right]);
  66. int pivot=arr[right];
  67.  
  68. int i=left;
  69. int j=right-;
  70. //按中位数的中位数对数组进行1次划分。
  71. while()
  72. {
  73. while(arr[i]<pivot) i++;
  74. while(arr[j]>pivot) j--;
  75. if(i<j)
  76. swap(arr[i],arr[j]);
  77. else break;
  78. }
  79. swap(arr[i],arr[right]);
  80. /*对于下一次划分的处理*/
  81. int m=i-left+;
  82. if(m==k) return arr[i];
  83. else if(m>k) return quick_select(arr,left,i-,k);
  84. else return quick_select(arr,i+,right,k-m);
  85.  
  86. }
  87. int main()
  88. {
  89. int arr[num]= {,,,,,,,,,,,,,,,,,,,,};
  90. int k=;
  91. int ans=quick_select(arr,,num-,k);
  92. cout<<ans<<endl;
  93. return ;
  94. }

快速选择算法/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. java基础-day32

    第09天 JDBC连接池&DBUtils工具类 今日内容介绍 u c3p0连接池 u dbcp连接池 u DBUtils工具类 第1章   c3p0连接池 1.1  连接池概述 实际开发中“获 ...

  2. java基础-day30

    第07天 MySQL数据库 今日内容介绍 u 多表关系实战练习 u 多表查询 u SQL语句的练习 第1章   多表关系实战练习 1.1  多表关系--实战1--省和市 1.1.1 需求分析 在数据库 ...

  3. noip第3课作业

    1.    求最大值 [问题描述] 输入三个数a,b,c,输出三个整数中的最大值 [样例输入] 10 20 30 [样例输出] 30 #include <iostream> using n ...

  4. 基类的析构函数写成virtual虚析构函数

    虚函数作用:动态绑定,实现多态效果. 场景问题: 派生类中有资源需要回收,而在编程中采用多态,由基类的指针指向派生类,则在释放的时候,如果基类的析构函数不是virtual,则派生类的析构函数得不到释放 ...

  5. linux 查看、关闭 ssh pts/n登录的用户

    1.查看登录用户: [root@TiaoBan- bin]# w :: up days, :, users, load average: 1.90, 1.75, 1.84 USER TTY FROM ...

  6. 8.正则表达式和XPath

    1.使用正则表达式爬取内涵段子 import requests import re def loadPage(page): url = "http://www.neihan8.com/art ...

  7. 微信WeixinJSBridge API使用实例

    http://www.jb51.net/article/66642.htm 这篇文章主要介绍了微信WeixinJSBridge API使用实例,本文直接给出HTML代码,代码中包含了很多实用功能,如图 ...

  8. 有关VS报错Files的值XXX

    从网上下载了一个实例来学习,但是运行的时候报错:Files的值(后面跟一堆符号,看不懂), 环境:安装了易赛通加密软件(估计可能跟这个加密软件有关系了) 解决方案:找到程序根目录的obj/Debug/ ...

  9. Python 学习第二章

    本章内容 数据类型 数据运算 表达式 if ...else 语句 表达式 for 循环 表达式 while 循环 一.数据类型 在内存中存储的数据可以有多种类型. 在 Python 有五个标准的数据类 ...

  10. JAVA学习笔记1——环境配置

    ·JDK 发展史 1995 java语言诞生 1996 JDK1.0发布 1997 JDK1.1发布 1998 JDK1.2发布(Java2),JFC/Swing技术发布 1999 Java被分成了J ...