前言:
学习堆及堆排序,认识到堆的内部原理,这时候就应该运用在实体场景。
例如:全校有2000人,如何帅选出成绩最好的前10名。
帅选出全球前100所最具潜力的公司等等。
TOP-K问题:
如何创造出多个数据?
在32位机器上整型占4个字节,电脑一般自带内存是8GB或者16GB,也就是最多存储
2,147,483,648个整型数据。
如果一次性的数量比较大超过了21亿,此时就需要将数据存储在硬盘上面,通常硬盘的内存会比较大,当我们需要的时候在硬盘上去读取数据即可。
将数据写入文件中:
这里涉及到如何将数据写入文件中,也就是文件相关的操作:文件操作(1)(C语言版)-CSDN博客
可以根据以前写的文章进行复习。
在这里我们将数据写入文件中用fprintf,读取时用fscanf。(运用格式化读写会比较方便!)
将文件打开并将数据写入:
void CreatData()
{
srand((unsigned int)time(NULL));
char name[] = { "data.txt" };
int arr[100000];
int a = 0;
FILE* data = fopen(name, "w");
if (data == NULL)
{
perror("fopen ::error");
exit(-1);
}
for (int i = 0; i < 100000; i++)
{
a = (rand() + i) % 10000;
arr[i] = a;
}
for (int i = 0; i < 100000; i++)
{
fprintf(data,"%d\n",arr[i]);
}
fclose(data);
}
TOP-K思路:
因为小堆的最上层是最小的,如果没有比堆里面最小的大,那么就是最大的10个
主要思路还是“沉底思想”
代码:
void AdjustUp(HPDataType* a, int child)
{
int parent = (child - 1) / 2;
while (child > 0)
{
if (a[child] < a[parent])
{
swap(&a[child], &a[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
void AdjustDown(HPDataType* a, int size, int parent)
{
//假设最大的孩子的值是左孩子对应的数值
int childmax = (parent * 2) + 1;
while (childmax < size)
{
//如果右有孩子并且右孩子的值是大于左孩子将最大的孩子换成右孩子
if (childmax + 1 < size && a[childmax + 1] < a[childmax])
{
childmax = childmax + 1;
}
if (a[parent] > a[childmax])
{
swap(&a[parent], &a[childmax]);
parent = childmax;
childmax = (parent * 2) + 1;
}
else
{
break;
}
}
}
void swap(HPDataType* a, HPDataType* b)
{
HPDataType c = 0;
c = *a;
*a = *b;
*b = c;
}
void CreatData()
{
srand((unsigned int)time(NULL));
char name[] = { "data.txt" };
int arr[100000];
int a = 0;
FILE* data = fopen(name, "w");
if (data == NULL)
{
perror("fopen ::error");
exit(-1);
}
for (int i = 0; i < 100000; i++)
{
a = (rand() + i) % 10000;
arr[i] = a;
}
for (int i = 0; i < 100000; i++)
{
fprintf(data,"%d\n",arr[i]);
}
fclose(data);
}
void test3()
{
//创造数据
CreatData();
FILE* data = fopen("data.txt", "r");
if (data == NULL)
{
perror("fopen :error");
exit(-1);
}
int k = 10;
//创建堆
int* heap = (int*)malloc(sizeof(int) * k);
if (heap == NULL)
{
perror("heap::error");
exit(-1);
}
//建立k个数的小堆
for (int i = 0; i < k; i++)
{
fscanf(data,"%d",&heap[i]);
AdjustUp(heap,i);
}
//比较所有的数,如果有大于堆顶的将覆盖,并向下调整
int a = 0;
while (fscanf(data,"%d",&a) != EOF)
{
if (heap[0] < a)
{
heap[0] = a;
AdjustDown(heap, k, 0);
}
}
for (int i = 0; i < k; i++)
{
printf("%d ", heap[i]);
}
free(heap);
heap = NULL;
fclose(data);
}