找出一堆数据中最大或者最小的K个数

原创 2012年03月27日 19:05:35

 用容量为K的最小堆来存储最大的K个数,最小堆的堆顶元素就是最大K个数中最小的一个。每次考虑一个新的元素时,将其与堆顶的元素进行比较,只有当它大于堆顶元素时,才用其替换堆顶元素,并更新最小堆。时间复杂度为O(N*logK)。


找出最大的K个数方法是建立一个有K个数的最小堆。

#include <iostream>
#include <vector>
#include <set>

using namespace std;

typedef multiset< int,less<int> >  INTHEAP;

void FindGreatestNum(vector<int>& iArray, const unsigned int num, INTHEAP& pRes)
{
	pRes.clear();
	if(iArray.empty() || num <= 0)
	{
		return;
	}

	vector<int>::iterator iter = iArray.begin();
	while(iter != iArray.end())
	{
		if(pRes.size() < num)
		{
			pRes.insert(*iter);
		}
		else
		{
			INTHEAP::iterator pIter = pRes.begin();
			if(*iter > *pIter)
			{
				pRes.erase(pIter);
				pRes.insert(*iter); 
			}
		}
		iter ++;
	}
}
int main()
{
	int iArray[] = {1,6,9,0,2,8,12,77,90,54,78,92,23,34,56,76,91};
	int len =  sizeof( iArray ) / sizeof( int );
	const unsigned int num = 7;
	vector<int> nArray(iArray, iArray + len);

	INTHEAP pRes;
	FindGreatestNum(nArray, num, pRes);
	INTHEAP::iterator iter = pRes.begin();
	while(iter != pRes.end())
	{
		cout<<*iter<<" ";
		iter ++;
	}
	cout<<endl;
	return 0;
}

同理:找出最小的K个数方法是建立一个有K个数的最大堆。

#include <iostream>
#include <set>
#include <vector>

using namespace std;
typedef multiset<int, greater < int > >  intHeap;

void FindKLeastNumbers(vector< int >& iArray,const unsigned int num,intHeap& pResult)
{
	pResult.clear();
	if(iArray.empty() || num <= 0)
	{
		return;
	}
	for(vector<int>::iterator iter = iArray.begin(); iter != iArray.end(); iter ++)
	{
		if(pResult.size() < num)
		{
			pResult.insert(*iter);
		}
		else
		{
			multiset<int, greater<int> >::iterator pIter = pResult.begin();

			if(*iter < *(pResult.begin()))
			{
				pResult.erase(pIter);
				pResult.insert(*iter);
			}
		}
	}
}

int main()
{
	int iArray[]  = {1,9,7,8,5,3,9,4,2};
	int len = sizeof( iArray ) / sizeof( int );
	vector< int >  nArray(iArray, iArray + len);

	const unsigned int num = 4;
	intHeap pResult;

	FindKLeastNumbers(nArray, num, pResult);
	multiset<int, greater<int> >::iterator iter = pResult.begin();

	while(iter != pResult.end())
	{
		cout<<*iter<<" ";
		iter ++;
	}
	cout<<endl;
	return 0;

}

小结:通过学习STL相关的知识,它其实是一个非常好的库,具有良好的数据结构,而且运行效率也比较的高,是里说应当掌握的重要技术。



相关文章推荐

Top K问题

Top K问题在数据分析中非常普遍的一个问题(在面试中也经常被问到),比如: 从20亿个数字的文本中,找出最大的前100个。 解决Top K问题有两种思路, 最直观:小顶堆(大顶堆 -> 最小1...

bfprt算法----找出数组中最小的k个数(Java)

无序数组中最小的k个数 对于一个无序数组,数组中元素为互不相同的整数,请返回其中最小的k个数。 给定一个整数数组A及它的大小n,同时给定k,请返回其中最小的k个数。 测试样例: [1,2,4,3]...

找出N个数中最小的k个数问题(复杂度O(N*logk))

找出N个数中最小的k个数问题(复杂度O(N*logk))

二.用最小堆方法找出海量数据中最小的k个数

思路:用数组b模拟海量数据的数组,数组a存放最小的k个数,首先将数组b的前k个数赋值给a,对a建最大堆,则此时a[0]存放a的最大元素,然后遍历b中k 以后的数据和a[0]比较,如果比a[0]小,则...

【海量数据处理】N个数中找出最大的前K个数

N个数中找出最大的前K个数,需要用小堆实现。分析:由于小堆的堆顶存放堆中最小的数据,可以通过与堆顶数据进行比较,将大数据存放在堆中,注意在每次改变堆顶数据后,进行调堆,使堆顶一直存放整个堆中最小元素。...
  • Scenlyf
  • Scenlyf
  • 2016年06月11日 18:53
  • 172

【数据结构】找出N个数据中最大的前k个数据(利用堆排序)

我们举例,假若从10000万个数里选出前100个最大的数据。首先我们先分析:既然要选出前100个最大的数据,我们就建立一个大小为100的堆(建堆时就按找最大堆的规则建立,即每一个根节点都大于它的子女节...

【数据结构】找出N个数据中最大的前k个数据(利用堆排序)

我们举例,假若从10000万个数里选出前100个最大的数据。首先我们先分析:既然要选出前100个最大的数据,我们就建立一个大小为100的堆(建堆时就按找最大堆的规则建立,即每一个根节点都大于它的子女节...

海量数据处理 - 10亿个数中找出最大的10000个数(top K问题)

前两天面试3面学长问我的这个问题(想说TEG的3个面试学长都是好和蔼,希望能完成最后一面,各方面原因造成我无比想去鹅场的心已经按捺不住了),这个问题还是建立最小堆比较好一些。         先拿1...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:找出一堆数据中最大或者最小的K个数
举报原因:
原因补充:

(最多只允许输入30个字)