用一个大根堆只保存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
---------------------------------------