用快速排序的思想输出数组第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. 【转】Mysql行转换为列

    From : http://www.cnblogs.com/lhj588/archive/2012/06/15/2550392.html# 今晚需要统计数据生成简易报表,由原表格数据是单行的形式,最好 ...

  2. 【手机网络游戏 编程】C#异步socketAPI调用 处理数据的流程

    之前客户端在网络条件好的时候,运行没问题.但是有时候手机的网络不稳定,接受数据可能不稳定,导致接受数据错误,一直都不知道,原来是接受数据处理的不够好! 现在更改过后的接受数据的逻辑如下: //接收 p ...

  3. 一种多线程写日志文件的解决方案 c#源代码演示

    using System;using System.Collections.Generic;using System.Collections;using System.Text;using Syste ...

  4. iOS:通过Self-Sizing Cells新特性自动计算cell的高度

    iOS8 新特性Self-Sizing Cells,自动计算cell的高度 一.简单介绍 UITableView是iOS开发最常用的一个控件,通过代理和数据源方法,几乎能实现各种各样的列表功能.在这里 ...

  5. RxJava RxPermissions 动态权限 简介 原理 案例 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. windows下mysql忘记root密码的解决办法

    今天早上 一朋友说自己的mysql 忘记root密码了 让我帮忙给看看,因为没有接触过mysql 所以从网上找了一下信息经我亲身实践  已经成功!mysql版本是5.1以下是从网上找的信息: 1. 首 ...

  7. spark0.8.0安装与学习

    spark0.8.0安装与学习       原文地址:http://www.yanjiuyanjiu.com/blog/20131017/ 环境:CentOS 6.4, Hadoop 1.1.2, J ...

  8. Linux系统中查找、删除重复文件,释放磁盘空间。

    在Linux系操作系统中查找并删除重复文件的方法的确有很多,不过这里介绍的是一款非常简单实用的软件FSlint.FSlint是一个重复文件查找工具,可以使用它来清除不必要的重复文件,笔者经常使用它来释 ...

  9. Mongoose Connection best practice

    There is often quite a lot of confusion about how best to set up a database connection with Mongoose ...

  10. maven 打包可执行jar的方法

    转自:http://blog.csdn.net/johnnywww/article/details/7964326 1.修改pom.xml增加如下内容 <plugin> <group ...