要求:给定一个数组array[n],寻找大小排在第k的元素

思路一:最直接的思路就是先排序,这样可以直接通过数组下标找到第k大的元素,最好的快速排序时间复杂度为O(nlogn)。

思路二:我们可以在快速排序的基础上进行改进,即运用快速排序框架,不过快速排序中的基准元素,我们采用随机划分而不是快速排序那样指定为一个固定的值。此方法时间复杂度为O(n)

此思路的代码如下:
  1. #include<iostream>
  2. #include<stdlib.h>
  3. #include<math.h>
  4. #include<time.h>
  5. using namespace std;
  6. int random(int p,int r)
  7. {
  8. return (rand()%(r-p+1)+p);
  9.  
  10. }
  11. int partion(float a[],int p,int r)
  12. {
  13. int x = a[r];
  14. int i=p-1;
  15. for(int j = p;j<r;++j){
  16. if(a[j]<=x){
  17. ++i;
  18. swap(a[i],a[j]);
  19. }
  20. }
  21. swap(a[i+1],a[r]);
  22. return i+1;
  23. }
  24. int part(float a[],int p,int r)
  25. {
  26. int i=random(p,r);
  27. swap(a[i],a[p]);
  28. return partion(a,p,r);
  29. }//该算法的主体框架为快速排序的框架,但与快速排序不同的是,快速排序是通过递归框架
  30. //对数组进行排序,但此算法通过递归框架只对数组中的第k元进行筛选,所以递归的出口不同
  31. //快速排序中的递归出口为if(high>low),但该函数的递归出口为if(k-1==i-p)
  32. //与快速排序相同的是都存在一个划分过程
  33. //如果单是求第k元的话,该函数的参数可以简化,即p=0,这样j==i
  34. float select(float a[],int p,int r,int k)
  35. {//在数组a中从下标p到r中求第k小的元素
  36. if(p==r)
  37. {
  38. return a[p];
  39. }
  40. int i=part(a,p,r);//对数组a随机划分
  41. int j=i-p;//+1;//此处之所以要i-p因为该函数从数组p下标开始,而不一定从0开始
  42. if(k-1==j)//因为数组下标从0开始,所以第k小元素下标为k-1
  43. return a[i];//递归出口,返回该元素
  44. else if(k-1<j)
  45. return select(a,p,i-1,k);
  46. else
  47. return select(a,i+1,r,k-j-1);
  48.  
  49. }
  50. void bubble(float a[], int n)
  51. {
  52. int i,flag=1;
  53. for(i=1;i<=n-1&&flag;i++)
  54. {
  55. flag=0;
  56. for(int j=0;j<n-i;j++)
  57. {
  58. if(a[j+1]<a[j])
  59. {
  60. int temp=a[j];
  61. a[j]=a[j+1];
  62. a[j+1]=temp;
  63. flag=1;
  64.  
  65. }
  66.  
  67. }
  68. }
  69. }
  70. int main()
  71. {
  72. int n,t,i,j=0;
  73. cout<<"请输入元素的个数n"<<endl;
  74. cin>>n;
  75. // float *p=(float *)malloc(n*sizeof(float));
  76. float *p=new float[n];
  77. cout<<"请输入每个元素的值"<<endl;
  78. for(i=0;i<n;i++)
  79. {
  80. cin>>p[i];
  81. }
  82. cout<<"请输入要寻找第k元的k值"<<endl;
  83. int k;
  84. cin>>k;
  85. cout<<select(p,0,n-1,k)<<endl;
  86. return 1;
  87. }
程序运行结果如下:

寻找第k元的更多相关文章

  1. 寻找第K大的数

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

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

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

  3. 快速选择算法/Select 寻找第k大的数

    参考算法导论9.3节的内容和这位大神的博客:http://blog.csdn.net/v_JULY_v上对这一节内容代码的实现进行了学习 尝试实现了以查找中位数为前提的select算法. 算法功能:可 ...

  4. 分治算法--寻找第k大数

    问题描述:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k大的元素,(这里给定的线性集是无序的). 其实这个问题很简单,直接对线性序列集qsort,再找出第k个即可.但是这样的 ...

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

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

  6. XJTUOJ wmq的队伍(树状数组求 K 元逆序对)

    题目链接:http://oj.xjtuacm.com/problem/14/[分析]二元的逆序对应该都会求,可以用树状数组.这个题要求K元,我们可以看成二元的.我们先从后往前求二元逆序对数, 然后对于 ...

  7. P3290 寻找第K大数

    描述 寻找第K大数 N个小朋友在一起做游戏.每个小朋友在自己的硬纸板上写一个数,然后同时举起来.接着,小y老师提一个问题,看哪个小朋友先抢答出来.问题是:在这N个数中,第K大的是哪个数?请你编程完成. ...

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

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

  9. (寻找第K小的数&amp;&amp;寻找第K小的数的和)

    这一篇博客以一些OJ上的题目为载体,讲一下寻找第K小的数的方法 方法一: 先将数据排列好,然后,然后return a[k]或者将前K个数加起来 方法二: 基于高速排序.如,一次高速排序将某一个数放到了 ...

随机推荐

  1. javac编译原理

    javac编译器的作用就是将符合java语言规范的源代码转化成符合java虚拟机规范的java字节码 经历:词法分析器->语法分析器->语义分析器->编译字节码 四个过程生成字节码文 ...

  2. JAVA学习总结-多线程基础:

    参考书籍:疯狂JAVA讲义 1.进程和线程; 进程是处于运行过程中的程序;并且具有一定的独立功能;进程是系统进行系统资源分配和调度的一个独立单位. 一般而言,进程包括以下三个特征: 独立性:进程是系统 ...

  3. Linux下常用的配置

    本文主要给出的都是一些常用的Linux配置,系统版本是基于CentOs6.3,供自己复习和新人学习,不当之处还请指正. vmware tools安装 虚拟机--->安装vmware tools ...

  4. 03_OGNL

    1.值栈: 解答Struts能够直接获取属性值: 原因:Struts并不是直接通过request隐式对象中获取,而是将整个对象封装到了ValueStack值栈中,直接匹配是否存在这个属性,找到了就取出 ...

  5. 负载均衡LVS(DR模式)安装实战

    1.编译安装ipvsadm 首先从LVS官网下载tarball,解压后make && make install即可. 要注意的是LVS的依赖有:popt-static.libnl.ke ...

  6. Redis源码学习:字符串

    Redis源码学习:字符串 1.初识SDS 1.1 SDS定义 Redis定义了一个叫做sdshdr(SDS or simple dynamic string)的数据结构.SDS不仅用于 保存字符串, ...

  7. Ruby 连接MySQL数据库

    使用Ruby连接数据库的过程还真的是坎坷,于是写点文字记录一下. 简介 Ruby简介 RubyGems简介 包管理之道 比较著名的包管理举例 细说gem 常用的命令 准备 驱动下载 dbi mysql ...

  8. Leetcode解题-链表(2.2.2)ReverseLinkedList

    题目:2.2.2 Reverse Linked List II Reverse a linked list from position m to n. Do it in-place and in on ...

  9. #pragma pack(x) CPU对齐

    编译器会尽量把成员对齐以提高内存的命中率.对齐是可以更改的,使用"#pragma pack(x)" 可以改变编译器的对齐方式. C++固有类型的对界取编译器对齐方式与自身大小中较小 ...

  10. HTML简单使用

    HTML简单使用 标签 : 前端技术 HTML HTML(Hypertext Marked Language), 即超文本标记语言,能够独立于各种操作系统平台(如UNIX/Linux/Windows等 ...