寻找第k元
要求:给定一个数组array[n],寻找大小排在第k的元素
思路一:最直接的思路就是先排序,这样可以直接通过数组下标找到第k大的元素,最好的快速排序时间复杂度为O(nlogn)。
思路二:我们可以在快速排序的基础上进行改进,即运用快速排序框架,不过快速排序中的基准元素,我们采用随机划分而不是快速排序那样指定为一个固定的值。此方法时间复杂度为O(n)
- #include<iostream>
- #include<stdlib.h>
- #include<math.h>
- #include<time.h>
- using namespace std;
- int random(int p,int r)
- {
- return (rand()%(r-p+1)+p);
- }
- int partion(float a[],int p,int r)
- {
- int x = a[r];
- int i=p-1;
- for(int j = p;j<r;++j){
- if(a[j]<=x){
- ++i;
- swap(a[i],a[j]);
- }
- }
- swap(a[i+1],a[r]);
- return i+1;
- }
- int part(float a[],int p,int r)
- {
- int i=random(p,r);
- swap(a[i],a[p]);
- return partion(a,p,r);
- }//该算法的主体框架为快速排序的框架,但与快速排序不同的是,快速排序是通过递归框架
- //对数组进行排序,但此算法通过递归框架只对数组中的第k元进行筛选,所以递归的出口不同
- //快速排序中的递归出口为if(high>low),但该函数的递归出口为if(k-1==i-p)
- //与快速排序相同的是都存在一个划分过程
- //如果单是求第k元的话,该函数的参数可以简化,即p=0,这样j==i
- float select(float a[],int p,int r,int k)
- {//在数组a中从下标p到r中求第k小的元素
- if(p==r)
- {
- return a[p];
- }
- int i=part(a,p,r);//对数组a随机划分
- int j=i-p;//+1;//此处之所以要i-p因为该函数从数组p下标开始,而不一定从0开始
- if(k-1==j)//因为数组下标从0开始,所以第k小元素下标为k-1
- return a[i];//递归出口,返回该元素
- else if(k-1<j)
- return select(a,p,i-1,k);
- else
- return select(a,i+1,r,k-j-1);
- }
- void bubble(float a[], int n)
- {
- int i,flag=1;
- for(i=1;i<=n-1&&flag;i++)
- {
- flag=0;
- for(int j=0;j<n-i;j++)
- {
- if(a[j+1]<a[j])
- {
- int temp=a[j];
- a[j]=a[j+1];
- a[j+1]=temp;
- flag=1;
- }
- }
- }
- }
- int main()
- {
- int n,t,i,j=0;
- cout<<"请输入元素的个数n"<<endl;
- cin>>n;
- // float *p=(float *)malloc(n*sizeof(float));
- float *p=new float[n];
- cout<<"请输入每个元素的值"<<endl;
- for(i=0;i<n;i++)
- {
- cin>>p[i];
- }
- cout<<"请输入要寻找第k元的k值"<<endl;
- int k;
- cin>>k;
- cout<<select(p,0,n-1,k)<<endl;
- return 1;
- }
寻找第k元的更多相关文章
- 寻找第K大的数
在一堆数据中查找到第k个大的值. 名称是:设计一组N个数,确定其中第k个最大值,这是一个选择问题,解决这个问题的方法很多. 所谓“第(前)k大数问题”指的是在长度为n(n>=k)的乱序数组中S找 ...
- [SOJ]寻找第k大数字(numberk)
Description 经过长时间的筹备工作,在Jourk,Ronny,Plipala,阿长,阿沈等人的努力下,DM实验室建立起自己的系列网站,其中包括三个大板块:DMOJ首页.DMOJ论坛.DMOJ ...
- 快速选择算法/Select 寻找第k大的数
参考算法导论9.3节的内容和这位大神的博客:http://blog.csdn.net/v_JULY_v上对这一节内容代码的实现进行了学习 尝试实现了以查找中位数为前提的select算法. 算法功能:可 ...
- 分治算法--寻找第k大数
问题描述:给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k大的元素,(这里给定的线性集是无序的). 其实这个问题很简单,直接对线性序列集qsort,再找出第k个即可.但是这样的 ...
- 寻找第K大的数(快速排序的应用)
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数.给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在.测试样例:[1,3,5,2,2],5, ...
- XJTUOJ wmq的队伍(树状数组求 K 元逆序对)
题目链接:http://oj.xjtuacm.com/problem/14/[分析]二元的逆序对应该都会求,可以用树状数组.这个题要求K元,我们可以看成二元的.我们先从后往前求二元逆序对数, 然后对于 ...
- P3290 寻找第K大数
描述 寻找第K大数 N个小朋友在一起做游戏.每个小朋友在自己的硬纸板上写一个数,然后同时举起来.接着,小y老师提一个问题,看哪个小朋友先抢答出来.问题是:在这N个数中,第K大的是哪个数?请你编程完成. ...
- 数组,寻找第K大的数
时间复杂度 O(n) def partition(data,left,right): if (len(data)<=0 or left<0 or right>=len(data)): ...
- (寻找第K小的数&&寻找第K小的数的和)
这一篇博客以一些OJ上的题目为载体,讲一下寻找第K小的数的方法 方法一: 先将数据排列好,然后,然后return a[k]或者将前K个数加起来 方法二: 基于高速排序.如,一次高速排序将某一个数放到了 ...
随机推荐
- javac编译原理
javac编译器的作用就是将符合java语言规范的源代码转化成符合java虚拟机规范的java字节码 经历:词法分析器->语法分析器->语义分析器->编译字节码 四个过程生成字节码文 ...
- JAVA学习总结-多线程基础:
参考书籍:疯狂JAVA讲义 1.进程和线程; 进程是处于运行过程中的程序;并且具有一定的独立功能;进程是系统进行系统资源分配和调度的一个独立单位. 一般而言,进程包括以下三个特征: 独立性:进程是系统 ...
- Linux下常用的配置
本文主要给出的都是一些常用的Linux配置,系统版本是基于CentOs6.3,供自己复习和新人学习,不当之处还请指正. vmware tools安装 虚拟机--->安装vmware tools ...
- 03_OGNL
1.值栈: 解答Struts能够直接获取属性值: 原因:Struts并不是直接通过request隐式对象中获取,而是将整个对象封装到了ValueStack值栈中,直接匹配是否存在这个属性,找到了就取出 ...
- 负载均衡LVS(DR模式)安装实战
1.编译安装ipvsadm 首先从LVS官网下载tarball,解压后make && make install即可. 要注意的是LVS的依赖有:popt-static.libnl.ke ...
- Redis源码学习:字符串
Redis源码学习:字符串 1.初识SDS 1.1 SDS定义 Redis定义了一个叫做sdshdr(SDS or simple dynamic string)的数据结构.SDS不仅用于 保存字符串, ...
- Ruby 连接MySQL数据库
使用Ruby连接数据库的过程还真的是坎坷,于是写点文字记录一下. 简介 Ruby简介 RubyGems简介 包管理之道 比较著名的包管理举例 细说gem 常用的命令 准备 驱动下载 dbi mysql ...
- 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 ...
- #pragma pack(x) CPU对齐
编译器会尽量把成员对齐以提高内存的命中率.对齐是可以更改的,使用"#pragma pack(x)" 可以改变编译器的对齐方式. C++固有类型的对界取编译器对齐方式与自身大小中较小 ...
- HTML简单使用
HTML简单使用 标签 : 前端技术 HTML HTML(Hypertext Marked Language), 即超文本标记语言,能够独立于各种操作系统平台(如UNIX/Linux/Windows等 ...