求一无序数组中第n大的数字 - 快速选择算法
逛别人博客的时候,偶然看到这一算法题,顺便用C++实现了一下。
最朴素的解法就是先对数组进行排序,返回第n个数即可。。
下面代码中用的是快速选择算法(不晓得这名字对不对)
#include <vector>
#include <iostream>
#include <stdexcept>
#include <cstdio> const int QS_EERRMSG_LEN = ; /**
* 快速选择求无序数组中第n大的数字
* 因为select返回的是数组中对象的引用,
* 所以错误处理选择了异常
*/
template <typename T>
class QuickSelect
{
public:
typedef typename std::vector<T>::size_type size_type; /**
* 构造函数
* @brief QuickSelect
* @param array - vector类型的数组
*/
QuickSelect(std::vector<T>& array)
:m_array(array)
{} /**
* 选择第nth大的元素,
* 失败抛出std::out_of_range异常,
* 成功返回得到的元素
* @brief select
* @param nth
* @return
*/
const T&
select(size_type nth) throw(std::out_of_range)
{
//s_pos即第n大在排序之后数组中的下标
size_type s_pos = m_array.size() - nth; if(s_pos > m_array.size()){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "Array access violation:{access:%ld range_length:%ld begin:%ld}.", nth, m_array.size(), );
std::out_of_range oor(errmsg);
throw oor;
} return this->select_pos(s_pos, , m_array.size());
} /**
* @brief select
* @param nth
* @param begin
* @param end
* @return
*/
const T&
select(size_type nth, size_type begin, size_type end) throw(std::out_of_range)
{
size_type array_size = m_array.size(); if(begin > array_size || end > array_size || end < begin){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "The begin or end are not correct:{array_size:%ld begin:%ld end:%ld}.", array_size, begin, end);
std::out_of_range oor(errmsg);
throw oor;
} //要查找范围的长度
size_type range_length = end - begin + ; //要查找的第n大的元素在当前范围内的位置
size_type s_pos = range_length - nth; if(s_pos > range_length){
char errmsg[QS_EERRMSG_LEN]; std::snprintf(errmsg, QS_EERRMSG_LEN, "Array access violation:{access:%ld range_length:%ld begin:%ld}.", nth, range_length, begin);
std::out_of_range oor(errmsg);
throw oor;
}
else return this->select_pos(s_pos, begin, end);
}
private:
/**
* pos表示的是元素从begin开始的位置
* @brief select_pos
* @param pos
* @param begin
* @param end
* @return
*/
const T& select_pos(size_type pos, size_type begin, size_type end)
{
T& pivot = m_array[begin];
size_type swap_pos = begin; if(begin == end){
return m_array[pos];
} //进行一次快速排序
for(size_type i = begin + ;i < end;i ++){
if(m_array[i] < pivot){
std::swap(m_array[i], m_array[swap_pos ++]);
}
} //数组元素个数为奇数时多交换一次
if(m_array.size() % != ){
if(m_array[end - ] < pivot){
std::swap(m_array[end - ], m_array[swap_pos ++]);
}
} if(swap_pos - begin == pos){
return m_array[swap_pos];
}
else if(swap_pos - begin < pos){
return this->select_pos(pos, swap_pos + , end);
}
else{
return this->select_pos(pos, begin, swap_pos);
}
} /**
* @brief m_array
*/
std::vector<T>& m_array;
};
然后为了测试方便,实现vector输出,很简单的输出
 namespace std{
 template <typename T>
 std::ostream& operator <<(std::ostream& out, const std::vector<T>& array)
 {
     for(auto e:array){
         out << e <<" ";
     }
     out <<std::endl;
     return out;
 }
 }
下面是测试用例
int main()
{
std::vector<int> some{,,,,}; std::cout <<some; QuickSelect<int> qs(some); std::cout <<qs.select()<<std::endl; return ;
}
结果输出为
[root@localhost MYJOURNEY]# g++ quick_select.cpp -std=c++
[root@localhost MYJOURNEY]# ./a.out [root@localhost MYJOURNEY]#
求一无序数组中第n大的数字 - 快速选择算法的更多相关文章
- 无序数组中第Kth大的数
		
题目:找出无序数组中第Kth大的数,如{63,45,33,21},第2大的数45. 输入: 第一行输入无序数组,第二行输入K值. 该是内推滴滴打车时(2017.8.26)的第二题,也是<剑指of ...
 - [LeetCode] 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 ...
 - [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 ...
 - 前端算法题:找出数组中第k大的数字出现多少次
		
题目:给定一个一维数组,如[1,2,4,4,3,5],找出数组中第k大的数字出现多少次. 例如:第2大的数是4,出现2次,最后输出 4,2 function getNum(arr, k){ // 数组 ...
 - 无序数组中第K大的数
		
1. 排序法 时间复杂度 O(nlogn) 2. 使用一个大小为K的数组arr保存前K个最大的元素 遍历原数组,遇到大于arr最小值的元素时候,使用插入排序方法,插入这个元素 时间复杂度,遍历是 O( ...
 - 查找无序数组中第K大的数
		
思路: 利用快速排序的划分思想 可以找出前k大数,然后不断划分 直到找到第K大元素 代码: #include <iostream> #include <algorithm> # ...
 - 如何寻找无序数组中的第K大元素?
		
如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...
 - SQL Server 2008 R2——查找最小nIndex,nIndex存在而nIndex+1不存在 求最小连续数组中的最大值
		
=================================版权声明================================= 版权声明:原创文章 谢绝转载 请通过右侧公告中的“联系邮 ...
 - 快速查找无序数组中的第K大数?
		
1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN).在此,我们想探索是否存在时间复杂度 < O(NlgN),而且近似等于O(N)的高 ...
 
随机推荐
- Reverse digits of an integer.
			
class Solution { public: int reverse(int x) { ;//long 是怕中间过程溢出 <<,max=-min-){ ans=ans*+x%; x=x ...
 - mysql   超时 问题处理
			
当数据库出现10055和10048错误时,处理办法: 第一 链接超时设置(1)打开注册表:regedit 找到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ ...
 - mysql 8小时空闲后连接失效的解决
			
查了一下发现应用程序和mysql数据库建立连接,如果超过8小时应用程序不去访问数据库,数据库就断掉连接 .这时再次访问就会抛出异常. 关于mysql自动断开的问题研究结果如下, 1.c3p0.Hika ...
 - Kendo Web UI  Grid里时间格式转换
			
我和大家分享一下我的kendo的学习心得.如果不好的地方多多包含或者给我留言请看图 kendo里时间格式如图Oder Date列里的格式.但是我们想把时间转换成中国人习惯的格式.如Shipped Da ...
 - jquery实现当前页面编辑
			
实现效果 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
 - 开心菜鸟系列学习笔记--------初探Nodejs(了解篇)
			
一Node.js开始学习了! 1) 输出hellow worlds a.建一个js文件 hello.js 写 console.info('hellow world !!!'); 进入终 ...
 - mysql下怎样运行脚本
			
假设要运行脚本: F:\hello world\niuzi.sql 第一种方法: 在命令行下(未连接数据库),输入 mysql -h localhost -u root -p < ...
 - OpenSceneGraph是一个开源的三维引擎
			
http://www.osgchina.org/OpenSceneGraph是一个开源的三维引擎,被广泛的应用在可视化仿真.游戏.虚拟现实.科学计算.三维重建.地理信息.太空探索.石油矿产等领域.OS ...
 - DLNA架构在机顶盒上播放云存储文件的实现
			
DLNA 架构在机顶盒上播放云存储文件的实现 摘要: 随着越来越多的数码设备,音像设备等对 UPNP 协议的支持和普及,业界对多媒体内容提供服务的需求越越来越强烈,为了实现遵循 UPNP 协议和 ...
 - 【转】Android出现“Read-only file system”解决办法
			
原文网址:http://www.111cn.net/sj/android/44496.htm 下面介绍一篇Android出现“Read-only file system”解决办法 有碰到这类问题的朋友 ...