面试杂题(一)数组中最小的k个数

要找到数组中最小的k个数,只需要建立一个k大小的数组,或者在原数组中开辟一个大小为k的区间,用来保留k个数;

遍历原数组,如果有比k个数小的,就用该数去替换k数组中最大的,所以问题就转化成在k数组中找最大的数,最差效率为o((n-k)*k)

如果利用最大堆的特性,就能快速在k大小数组中找到最大的数,效率变成o((n-k)*logn)

代码如下:

void minKinArray(int *p,int nlen,int *result,int k)
{
	if (p==NULL||nlen<k)
	{
		return;
	}
		
	for (int i=0;i<k;i++)
	{
		result[i]=p[i];
	}
		int max;
		creatMaxHeap(result,k);
		
		
	for (int i=k;i<nlen;i++)
	{
		max=result[0];
		if (p[i]<max)
		{
			result[0]=p[i];
		}
		adjustHeap(result,k,0);
	}
}


	

void printArray(int *p,int nlen)
{
	if (p==NULL||nlen<=0)
	{
		return;
	}
	for (int i=0;i<nlen;i++)
	{
		cout<<p[i]<<'\t';
	}
	cout<<endl;
}

 void creatMaxHeap(int *p,int nlen)
{
	if (nlen<=1)
	{
		return;
	}
	int index=((nlen-1)-1)/2;
	for (int i=index;i>=0;i--)
	{
		if (2*i+2>=nlen)
		{
			//只有左儿子
			if(p[i]<p[2*i+1])
			{
				swap(&p[i],&p[2*i+1]);
			}

		}
		else
		{
			if (p[2*i+1]>=p[2*i+2])
			{
				if (p[i]<p[2*i+1])
				{
					swap(&p[i],&p[2*i+1]);
				}
			}
			else
			{
				if (p[i]<p[2*i+2])
				{
					swap(&p[i],&p[2*i+2]);
				}
			}
		}
	}
}

 void adjustHeap(int *p,int nlen,int index)
 {
	if (nlen<=0||p==NULL)
	{
		return;
	}
	if (index*2+1>=nlen)  //这是叶子节点
	{
		return;
	}
	if (index*2+2>=nlen)//只有左叶子节点
	{
		if(p[index]<p[2*index+1])
		{
			swap(&p[index],&p[2*index+1]);
		}

	}
	else
	{
		if (p[2*index+1]>p[2*index+2])
		{
			if (p[index]<p[2*index+1])
			{
				swap(&p[index],&p[2*index+1]);
				adjustHeap(p,nlen,2*index+1);
			}

		}
		else
		{
			if (p[index]<p[2*index+2])
			{
				swap(&p[index],&p[2*index+2]);
				adjustHeap(p,nlen,2*index+2);
			}
		}
	}
 }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值