用快速排序的思想输出数组第k大的元素:

 #include<iostream>
#include<algorithm>
using namespace std; //递归实现:返回数组第k大的值.数组下标区间是[begin,end].其中数组假定n个元素,则k的值在区间[1,n].
//能够使用这种方法的前提条件是:n个数不能重复。如果n个数中有重复,那么区间的大小不能保证就是第K大。
int findkth(int* arr, int begin, int end, int k)
{
int key=arr[begin];
int i=begin,j=end;
while(i<j)
{
while(i<j && arr[j]<=key) j--;
arr[i]=arr[j];
while(i<j && arr[i]>=key) i++;
arr[j]=arr[i];
}
arr[i]=key; //递归的结束条件为某一记录刚好划分到第k个位置
//由于数组从0开始,所以需要加1了
if (i == k-)return arr[i];
else if (i < k-) return findkth(arr, i+, end, k);
else return findkth(arr, begin, i-, k);
} //只做了一轮划分,没有递归完成快速排序.返回的是划分的下标。数组a[]下标区间[low,high]
template <class T>
int partition(T a[],int low,int high)
{
T key=a[low];
int i=low,j=high;
while(i<j)
{
while(i<j && a[j]>=key) j--;
a[i]=a[j];
while(i<j && a[i]<=key) i++;
a[j]=a[i];
}
a[i]=key;
return i;
} //利用快速排序的思想查找第K大的数值
//第一个参数代表要查找的数组
//第二个参数代表数组的长度
//第三个参数代表要查找第几大的元素
//非递归
template <class T>
T findkth2(T a[],int n,int k)
{
int low=,high=n-;
while()
{
int pos=partition(a,low,high);
if(pos==n-k) return a[pos];
else if(pos<n-k)
{
low=pos+;
high=n-;
}
else if(pos>n-k)
{
high=pos-;
low=;
}
}
} int main()
{
int a[]={,,,,,,,,,,};
int b[]={,,,,,,,,,,};
int c[]={,,,,,,,,,,}; for(int i=;i<;i++) cout<<a[i]<<" ";
cout<<endl;
sort(a,a+);
for(int i=;i<;i++) cout<<a[i]<<" ";
cout<<endl; for(int i=;i>=;i--)
cout<<findkth(b,,,i)<<" ";
cout<<endl; for(int i=;i>=;i--)
cout<<findkth2(c,,i)<<" ";
cout<<endl; cout<<endl<<endl;
for(int i=;i<;i++) cout<<b[i]<<" ";
cout<<endl;
for(int i=;i<;i++) cout<<c[i]<<" ";
cout<<endl;
return ;
}

参考:http://blog.csdn.net/guangwen_lv/article/details/39674241

利用快速排序的特点:第一遍排序会确定一个数的位置,这个数左边都比它大,右边都比他小(降序),当左边区间大于K时,说明我们求的第K大数在左边区间,这时我们可以舍弃右边区间,将范围缩小到左边区间从而重复上述过程,直到确定一个数的位置时,左边区间的小是K-1那么这个数字就是我们所求。右边同理。

能够使用这种方法的前提条件是:n个数不能重复。如果n个数中有重复,那么区间的大小不能保证就是第K大。可以用HASH判重来将重复的数据去掉。然后再使用上述方法。

也可阅读如下另一位网友的java代码:

 /** * Created with IntelliJ IDEA.
* User: hqtc
* Date: 16-3-22
* Time: 下午9:52
* To change this template use File | Settings | File Templates.
*/
public class QuickSort{ private int getSeparatorIndex(int[] nums, int low, int high) {
int k = nums[low];
while (low < high) {
while (k < nums[high] && low < high) {
high--;
}
if (low < high)
nums[low++] = nums[high];
while (k > nums[low] && low < high) {
low++;
}
if (low < high)
nums[high--] = nums[low];
}
nums[low] = k;
return low;
} public void sort(int num[], int low, int high) {
if (low < high) {
int sepIndex = getSeparatorIndex(num, low, high);
sort(num, low, sepIndex - 1);
sort(num, sepIndex + 1, high);
}
} public int findKthMax(int arr[], int k, int left, int right) {
int sepIndex = getSeparatorIndex(arr, left, right);
if (k == arr.length - sepIndex) {
return arr[sepIndex];
} else {
if (k > arr.length - sepIndex) {
return findKthMax(arr, k, left, sepIndex - 1);
} else {
return findKthMax(arr, k, sepIndex + 1, right);
}
}
}
} /*作者:环球探测
链接:http://www.jianshu.com/p/9f887dfc374a
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/

输出数组第k大的元素的更多相关文章

  1. 力扣:丑数II和数组中前K大的元素

    数组中的第K个元素 在未排序的数组中找到第 k 个最大的元素.请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素. 示例 1: 输入: [3,2,1,5,6,4] 和 k ...

  2. 寻找数组中的第K大的元素,多种解法以及分析

    遇到了一个很简单而有意思的问题,可以看出不同的算法策略对这个问题求解的优化过程.问题:寻找数组中的第K大的元素. 最简单的想法是直接进行排序,算法复杂度是O(N*logN).这么做很明显比较低效率,因 ...

  3. 获取一个数组里面第K大的元素

    如何在O(n)内获取一个数组比如{9, 1, 2, 8, 7, 3, 6, 4, 3, 5, 0, 9, 19, 39, 25, 34, 17, 24, 23, 34, 20}里面第K大的元素呢? 我 ...

  4. [LeetCode] Kth Largest Element in a Stream 数据流中的第K大的元素

    Design a class to find the kth largest element in a stream. Note that it is the kth largest element ...

  5. LeetCode703 流中第k大的元素

    前言: 我们已经介绍了二叉搜索树的相关特性,以及如何在二叉搜索树中实现一些基本操作,比如搜索.插入和删除.熟悉了这些基本概念之后,相信你已经能够成功运用它们来解决二叉搜索树问题. 二叉搜索树的有优点是 ...

  6. POJ 2985 Treap平衡树(求第k大的元素)

    这题也能够用树状数组做,并且树状数组姿势更加优美.代码更加少,只是这个Treap树就是求第K大元素的专家--所以速度比較快. 这个也是从那本红书上拿的模板--自己找了资料百度了好久,才理解这个Trea ...

  7. 2.4 选择第k大的元素 selection

    1.目标:找到N个元素中,第k大的数. 例如:max是k=N--1:min是k=0:median是k=N/2 2.Quick-select 借鉴了快速排序的思想 (1)利用partition保证: ① ...

  8. [leetcode]215. Kth Largest Element in an Array 数组中第k大的元素

    Find the kth largest element in an unsorted array. Note that it is the kth largest element in the so ...

  9. hrbust 1840 (树状数组第k大) 删点使用

    小橙子 Time Limit: 2000 MS Memory Limit: 32768 K Total Submit: 2(2 users) Total Accepted: 1(1 users) Ra ...

随机推荐

  1. 使用ASP.NET读取word2003文档

    直接使用.NET 读取doc文档. http://www.codeproject.com/Articles/22738/Read-Document-Text-Directly-from-Microso ...

  2. 用java打暴雪星际争霸(2)——执行測试机器人

    原创内容.转载请注明. 在上一节安装完成后.或者您直接打开我分享的虚拟机后,我如今将解说怎样启动測试机器人. 第一步,打开Eclipse,导入机器人演示样例项目,如图所看到的. 第二步,我们能够看到就 ...

  3. RV32A指令集

    RV32A指令包括两类:AMO(atomic memory operation)指令,Load-Reserved/Store-Conditional指令 Category Fmt RV32I base ...

  4. DevExpress的安装方法与破解教程【转】

    DevExpress是一个界面控件套件,提供了一系列的界面控件套件的DotNet界面控件.DevExpress开发的控件有很强的实力,不仅功能丰富,应用简单,而且界面华丽,更可方便订制,对于编程人员来 ...

  5. jQuery中的编程范式

    浏览器前端编程的面貌自2005年以来已经发生了深刻的变化,这并不简单的意味着出现了大量功能丰富的基础库,使得我们可以更加方便的编写业务代码,更重要的是我们看待前端技术的观念发生了重大转变,明确意识到了 ...

  6. Hadoop:开发机运行spark程序,抛出异常:ERROR Shell: Failed to locate the winutils binary in the hadoop binary path

    问题: windows开发机运行spark程序,抛出异常:ERROR Shell: Failed to locate the winutils binary in the hadoop binary ...

  7. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(八)安装zookeeper-3.4.12

    如何搭建配置centos虚拟机请参考<Kafka:ZK+Kafka+Spark Streaming集群环境搭建(一)VMW安装四台CentOS,并实现本机与它们能交互,虚拟机内部实现可以上网.& ...

  8. 如何给USB移动硬盘格式化分区

    硬盘盒装好后,插在电脑USB接口上,电脑正常识别到移动硬盘后,但因为全新硬盘没有分区,在"我的电脑"里是看不到盘符的.下面以40G移动硬盘分区讲一下硬盘如何分区.1.操作系统最好是 ...

  9. (转)溶解shader

    游戏中物体腐化消失,燃烧消失时,会有从局部慢慢消失的效果,然后配合一些粒子特效,就能达到非常好的美术效果.类似效果如下: 注:_DissColor为溶解主色,_AddColor为叠加色,按照溶解的移动 ...

  10. [Spring Boot] @Component, @AutoWired and @Primary

    Spring boot is really good for Dependencies injection by using Autowiring. Each class instancse in s ...