我们只能利用10kb的运行空间去取一个有上万个数据甚至上亿个数据的文件时
如果使用冒泡排序和堆排序会很难实现
这时我们可以开辟一个大小为k的数组 将文件开头的数据放入数组中 将数据转化成小堆 所以数组第一个数据就是它所有数据中最小的数据 再将文件后面的数据 和数据比较 如果比数据第一个数据大 那么将这个数据移到数组第一个位置中 再变成小堆 再进行比较 再变小堆 一直持续到 文件数据被遍历完 这时 数组中的数据就是 文件中最大的k个数
整体代码如下
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void heapdown(int* hp, int site ,int num)
{
int parent = site;
int child = parent * 2 + 1;
while (child < num)
{
if (hp[child+1]>0 && hp[child]>hp[child + 1])
{
child++;
}
if (hp[parent]>hp[child])
{
int tmp = hp[parent];
hp[parent] = hp[child];
hp[child] = tmp;
}
else
{
break;
}
parent = child;
child = parent * 2 + 1;
}
}
//void heapsort(int* hp, int total)
//{
// for (int i = (total - 1 - 1) / 2; i >= 0; i--)
// {
// heapdown(hp, i ,total);
// }
//}
void Topk(int k)
{
const char* file = "text.txt";
FILE* fin = fopen(file, "r");
int* arr = (int*)malloc(sizeof(int) * k);
if (arr==NULL)
{
perror("malloc");
return;
}
for (int i = 0; i < k; i++)
{
fscanf(fin, "%d", &arr[i]);
}
for (int i = (k - 1 - 1) / 2; i >= 0; i--)
{
heapdown(arr, i ,k);
}
int x = 0;
while (fscanf(fin, "%d", &x)>0)
{
if (x>arr[0])
{
arr[0] = x;
}
for (int i = (k - 1 - 1) / 2; i >= 0; i--)
{
heapdown(arr, i, k);
}
}
for (int i = 0; i < k; i++)
{
printf("%d ", arr[i]);
}
fclose(fin);
}
void createdate()
{
int n = 100000;
const char* file = "text.txt";
FILE* fin = fopen(file, "w");
if (fin == NULL)
{
perror("fopen");
return;
}
for (int i = 0; i < n; i++)
{
int x = (rand()+i) % 10000000;
fprintf(fin, "%d\n", x);
}
fclose(fin);
}
int main()
{
srand((unsigned int)time(NULL));
int num=10;
scanf("%d", &num);
//createdate();
Topk(num);
}