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