100w个数中找出最大的前K个数

Posted wanglelelihuanhuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了100w个数中找出最大的前K个数相关的知识,希望对你有一定的参考价值。

100w个数中找出最大的前K个数这个题是堆应用

首先100万个数大约占4M内存,可以加载到内存中。我们可以采用排序解决这个问题,比如堆排序、快排等,但排序不是最优解。我们可以利用最小堆来解决这个问题。

堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。 堆结构的二叉树存储是 最大堆:每个父节点的都大于孩子节点。 最小堆:每个父节点的都小于孩子节点。 思路:1、开辟大小为k的空间,把数组中前k个数建小堆            2、把剩下的数依次和堆顶元素进行比较,如果后面的数大于堆顶,替换掉堆顶,重新调整为最小堆,直到把剩下的数与堆顶比较完,此时堆里的k个数就是最大的前k个数
#include<iostream>
using namespace std;

void _Adjustdown(int* arr, int size, int parent)

	int child = parent * 2 + 1;
	while (child < size)
	
		//比较左右节点,选择较小的
		if (child + 1 < size && arr[child] > arr[child + 1])
		
			child++;
		
		if (arr[parent] > arr[child])
		
			swap(arr[parent],arr[child]);
			parent = child;
			child = parent * 2 + 1;
		
		else
		
			break;
		
	

//建小堆
void BuildHeap(int *arr,int size)

	//从第一个非叶子节点开始向下调整
	for (int i = (size-2)/ 2; i >= 0; --i)
	
		_Adjustdown(arr, size, i);
	

void GetKTop(int* arr,int size,int k)

	if (size<k || k<=0)
	
		return;
	 
	//开辟大小为k的空间,把数组中前k个数建小堆
	int *heap = new int[k];
	for (int i = 0; i < k; ++i)
	
		heap[i] = arr[i];
	
	BuildHeap(heap,k);

	//把后面的数依次和堆顶比较
	for (int i = k; i<size; ++i)
	
		//如果后面的数大于堆顶,替换掉堆顶,重新调整为最小堆
		if (arr[i]>heap[0])
		
			heap[0] = arr[i];
			_Adjustdown(heap, k, 0);
		
	

	for (int i = 0; i < k; ++i)
	
		cout << heap[i] << " ";
	
	
	delete[] heap;

int main()

	int arr[] = 1,2,5,6,7,9,2,5,10,22,40,35;
	int size = sizeof(arr) / sizeof(arr[0]);
	GetKTop(arr,size,3);
	return 0;


 

如果用堆排序解决问题,需要把所有数进行建堆,建堆的时间复杂度O(lgN),如果只把前k个数建堆,时间复杂度O(lgk),k远小于N,效率比堆排序高。


 

 

 

以上是关于100w个数中找出最大的前K个数的主要内容,如果未能解决你的问题,请参考以下文章

C++100w个数中找出最大的前K个数

海量数据处理 大量数据中找出最大的前10个数 (Top K 问题)

找出一堆数中最小的前K个数

Top k 问题

top K问题

海量数据问题