//最小的k个数
//输入n个整数,输出其中最小的k个数
//解答:虽然利用快排的思想很好的解决了问题,但是也有限制,首先我们需要一次性读入所以的数据,其次,需要修改输入的数组
//利用堆排序来解决此问题,此种方法适合处理海量数据
//首先我们先读入k个元素创建一个大小为k的大根堆,然后我们依次读入剩下的数据,如果当前数据比大根堆的堆顶小,则用这个数代替当前
//堆顶,并调整堆使其保持大根堆的性质;如果当前数据比堆顶大,那么这个数不可能是最小的k个整数之一,故可以抛弃此数,此种方法的复杂度为O(nlogk)
#include<iostream>
using namespace std;
void AdjustDown(int *data,int i,int len)
{
if(data==NULL||i<=0||len<=0||i>len)
return;
int nchild;
for(;2*i+1<len;i=nchild)
{
nchild=2*i+1;
if(nchild<len-1&&data[nchild+1]>data[nchild])
nchild++;
if(data[i]<data[nchild])
swap(data[i],data[nchild]);
else
break;
}
}
void BuildMax(int *a,int n)
{
if(a==NULL||n<=0)
return;
for(int i=n/2-1;i>=0;i--)
AdjustDown(a,i,n);
}
void main()
{
int data[]={1,3,5,6,2,4,8,7};
int len=sizeof(data)/sizeof(int);
int k;
cin>>k;
if(k>len||k<=0)
return;
int *b=new int[k];
for(int i=0;i<k;i++)
{
b[i]=data[i];
}
BuildMax(b,k);
for(int i=k;i<len;i++)
{
if(data[i]>b[0])
continue;
else
{
b[0]=data[i];
AdjustDown(b,0,k);
}
}
for(int i=0;i<k;i++)
cout<<b[i]<<" ";
delete []b;
}