在一个数组中查找最大的K个元素或者最小的K个元素

面试中经常会遇到查找最大的K个元素或者最小的K个元素的问题。如果是查找最大的K个元素,就用小根堆,如果当前元素比堆的根都元素大,那么一定要放到堆里来,用当前元素替换根元素(因为根的元素是最小的),然后调整堆。查找最小的K个元素用大根堆同理。


上代码:

#include <iostream>
using namespace std;

//在数组arr[1..size]中,使得以i为根的子堆保持大根堆的性质
void siftUp(int* arr, int i, int size)
{
	if(i>=size)
		return;
	int lchild = 2*i,rchild = 2*i+1;
	int largest = i;
	if(lchild <= size && arr[lchild] > arr[largest])
		largest = lchild;
	if(rchild <= size && arr[rchild] > arr[largest])
		largest = rchild;
	if(largest != i)
	{
		int tmp = arr[i];
		arr[i] = arr[largest];
		arr[largest] = tmp;
		siftUp(arr, largest, size);
	}
	return;
}


//find the least k elements, using max-root-heap
void findKLeastElements(int* arr, int k, int arrlength)
{
	if(k >= arrlength)
	{
		cout<<"The original array length is less than "<<k<<","<<endl;
		cout<<"so the original array is the least "<<arrlength<<" elements."<<endl;
		return;
	}
	int* heaparr = new int[k+1];
	for(int i = 0; i< k; ++i)
		heaparr[i+1] = arr[i];
	
	//build heap
	for(int i = k/2; i >= 1; --i)//heaparr[k/2] is the last root
		siftUp(heaparr,i,k);

	//find the least k elements
	for(int i = k; i < arrlength; ++i)
	{
		if(arr[i] < heaparr[1])
		{
			heaparr[1] = arr[i];
			siftUp(heaparr, 1, k);
		}
	}

	for(int i = 1; i <= k; ++i)
		cout<<heaparr[i]<<" ";
	cout<<endl;
	delete []heaparr;
}

//在数组arr[1..size]中,使得以i为根的子堆保持小根堆的性质
void siftDown(int* arr, int i, int size)
{
	if(i>=size)
		return;
	int lchild = 2*i,rchild = 2*i+1;
	int least = i;
	if(lchild <= size && arr[lchild] < arr[least])
		least = lchild;
	if(rchild <= size && arr[rchild] < arr[least])
		least = rchild;
	if(least != i)
	{
		int tmp = arr[i];
		arr[i] = arr[least];
		arr[least] = tmp;
		siftDown(arr, least, size);
	}
	return;
}

//find the biggest k elements, using min-root-heap
void findKBiggestElements(int* arr, int k, int arrlength)
{
	if(k >= arrlength)
		return;

	int* heaparr = new int[k+1];
	for(int i = 0; i< k; ++i)
		heaparr[i+1] = arr[i];
	
	//build heap
	for(int i = k/2; i >= 1; --i)//heaparr[k/2] is the last root
		siftDown(heaparr,i,k);

	//find the least k elements
	for(int i = k; i < arrlength; ++i)
	{
		if(arr[i] > heaparr[1])
		{
			heaparr[1] = arr[i];
			siftDown(heaparr, 1, k);
		}
	}

	for(int i = 1; i <= k; ++i)
		cout<<heaparr[i]<<" ";
	cout<<endl;
	delete []heaparr;
}

int main(int argc, char* argv[])
{
	int x1[12]={30,22,45,34,67,100,-1,564,981,3,51,-33};
	findKLeastElements(x1,1, 12);
	findKBiggestElements(x1,3,12);

	return 0;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值