【海量数据处理】寻找最大/小的k个数


/******************************************************
寻找k个最小的数

方法:堆排序

***************************************************/





#include "stdafx.h"
#include<iostream>
#include<assert.h>
using namespace std;

void MaxHeapAdjust(int a[],int i,int n)//对节点i进行调整,n是数组元素个数  
{   
    int largest = 0;  
    int left = i*2 + 1;//节点i的左节点  
    int right = i*2 + 2;//节点i的右节点  
      
    if(left< n && a[left]>a[i])//左节点和父节点比较  
        largest =left;  
    else  
        largest = i;  
    if(right<n && a[right]>a[largest])//如果有右节点,且左小于右  
        largest = right;  
          
    if(i != largest)//如果最大节点不是父节点  
    {  
        swap(a[i],a[largest]);  
        MaxHeapAdjust(a,largest,n);//下降父节点,跟子树最大堆比,其实经过创建最大堆时,子树都为最大堆了  
    }     
          
  
}  
  
  
//创建最大堆  
void BuildMaxHeap(int a[],int length)  
{  
    for(int i = length/2-1;i>=0;i--)//从非叶子节点开始进行最大堆调整  
    {  
        MaxHeapAdjust(a,i,length);  
    }  
  
}  
int main()
{
	//定义数组存储堆元素
	int k;
	cout << "请输入k:" << endl;  
    cin >> k;  
	int length = 0;  
    int i = 0; 
	int num = 0;
    int a[100] = {0};  
  
    cout << "请输入前k个数:" << endl;  
    for(;i<k;i++)  
        cin>>a[i]; 
    BuildMaxHeap(a,k);            //建堆
    cout << "请继续输入数字:" << endl;
	 while(cin >>num)                              //ctrl+z结束
		  {
		<span style="white-space:pre">	</span>if(num < a[0])
			{
			    a[0] = num;
			    MaxHeapAdjust(a,0,k);
			}
		 }
 

	
	 for(int i = 0;i<k;i++)  
    {  
        cout << a[i]<<" ";  
    }  
	 cout << endl;

	
	 system("pause");
	 return 0;

}





用STL的multiset来实现


typedef multiset<int,greater<int> > iSet;//set中的元素从大到小排列
typedef multiset<int,greater<int> >::iterator setIter;

void GetLeastKnum(const vector<int>& data,iSet & iset,int k)
{
	iset.clear();
	if(k<1 || data.size()<k)
		return;
	//遍历数组,不断更新堆

	vector<int>::iterator iter = data.begin();
	for(;iter!=ivec.size();iter++)
	{
		if(iset.size()<K)
			iset.insert(*iter);
		else
		{
			iSet siterGreatst = iset.begin();
			if(*iter < *siterGreatst)
				{
					iSet.erase(siterGreatst);
					iSet.insert(*iter);
				}
		}
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值