问题描述:
输入n个整数,输出其中最小的k个。
例如:输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。
解决方案:
用数组来存储这n个数,遍历前k个树,对前k个数建立大顶堆,继续遍历数组剩余元素,
每遍历一个,都与堆顶元素相比较,若其值小于堆顶元素,则它们相互交换,并更新堆,使其仍然保持大顶堆特性。
代码实现:
#include <cstdio>
#include <cstdlib>
//采用堆实现
void buildHead(int a[], int k);
void adjustHead(int a[], int i, int k);
void swapXY(int *x, int *y);
int main(int, char**)
{
int array[] = {3, 5, 9, 0, 1, 2, 8, 4, 6, 7};
int len = 10;
int k = 5;
buildHead(array, k);
for (int i = k; i < len; i++)
{
if (array[i] < array[0])
{
swapXY(&array[0], &array[i]);
adjustHead(array, 0, k);
}
}
//输出最小的K个数
printf("最小的%d个数:\n", k);
for (int s = 0; s < k; s++)
printf("%d\t", array[s]);
printf("\n");
system("pause");
return 0;
}
void buildHead(int a[], int k)
{
for (int i = k/2-1; i >=0; i--)
adjustHead(a, i, k);
}
void adjustHead(int a[], int i, int k)
{
if (i > k/2-1)
return;
int leftNo = 2*i+1;
int maxNo = a[i] > a[leftNo]? i:leftNo;
if (leftNo+1 < k && a[maxNo] < a[leftNo+1])
maxNo = leftNo+1;
if (maxNo != i)
{
swapXY(&a[i], &a[maxNo]);
adjustHead(a, maxNo, k);
}
}
void swapXY(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
//参考:http://blog.csdn.net/v_JULY_v/article/details/6370650