求n个无序数的前k个小的数

时间:2022-12-30 18:33:14

用一个大根堆只保存k个数,每次读一个数与大根堆的堆顶比较,若大直接抛弃,若小,则替换堆顶,然后调整堆

最后遍历一遍最后求出的就是最小的k个数。

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;

const int maxn = 20;
int array[maxn], k;

inline int randint(int low, int high);

void heapAdjust(int *arr, int index, int len);
void random();

int main()
{
	
	while(scanf("%d", &k) != EOF)
	{
		if(k > maxn)
			continue;
		random();
		int *result = new int[k];
		int cnt = 0;
		for(int i = 0; i < maxn; i++)
		{
			if(cnt < k)
			{
				result[cnt++] = array[i];
				if(cnt == k)
				{
					for(int h = (k - 2) / 2; h >= 0; h--)
						heapAdjust(result, h, k);
				}
			}
			else if(array[i] < result[0])
			{
				result[0] = array[i];
				heapAdjust(result, 0, k);
			}
		}
		for(int i = 0; i < k; i++)
			printf("%d ", result[i]);
		printf("\n");
		printf("---------------------------------------\n");
		delete []result;
	}
	
	return 0;
}

inline int randint(int low, int high)
{
	return (rand() % (high - low + 1)) + low; 
}

void random()
{
	srand(time(NULL));
	for(int i = 0; i < maxn; i++)
		array[i] = rand() % maxn;
	
	for(int i = 0; i < maxn; i++)
		printf("%d ", array[i]);
	printf("\n\n\n");
}

void heapAdjust(int *arr, int index, int len)
{
	int tmp = arr[index];
	for(int i = index * 2 + 1; i < len; i = 2 * i + 1)
	{
		if(i + 1 < len && arr[i] < arr[i + 1])
			i++;
		if(tmp > arr[i])
			break;
		arr[index] = arr[i];
		index = i;
	}
	arr[index] = tmp;
}

测试数据:

6 1 6 15 18 16 10 4 7 8 12 12 16 15 16 0 6 0 2 18 




8 7 6 6 1 0 6 4 2 0 
---------------------------------------