目录
1.堆排序
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
typedef int HPDataType;
//交换两个节点
void Swap(HPDataType* p1, HPDataType* p2)
{
assert(p1 && p2);
HPDataType tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//向下调整算法
void AdjustDown(HPDataType* a, int n, int parent)
{
assert(a);
int maxchild = parent * 2 + 1;
while (maxchild < n)
{
//找到左右孩子中的较大者
if (maxchild + 1 < n && a[maxchild] < a[maxchild + 1])
{
maxchild = maxchild + 1;//更新最大孩子
}
if (a[parent] < a[maxchild])
{
Swap(&a[parent], &a[maxchild]);
//更新父子节点
parent = maxchild;
maxchild = parent * 2 + 1;
}
//当父子满足大堆关系时,不进行交换
else
{
break;
}
}
}
//向上调整算法
void AdjustUp(HPDataType* a, int child)
{
assert(a);
int parent = (child - 1) / 2;
while (child > 0)
{
//大堆
if (a[parent] < a[child])
{
Swap(&a[parent], &a[child]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
void HeapSort(HPDataType* a, HPDataType n)
{
//向上调整建大堆
int i = 0;
for (i = n - 1; i >= 0; i--)
{
AdjustUp(a, i);
}
//选数
i = 1;
while (i < n)
{
Swap(&a[0], &a[n - i]);
AdjustDown(a, n - i, 0);
i++;
}
}
int main()
{
HPDataType a[] = { 4,1,7,8,15,34,19,27,25,65 };
int len = sizeof(a) / sizeof(a[0]);
HeapSort(&a, len);
//打印
for (int i = 0; i < len; i++)
{
printf("%d ", a[i]);
}
return 0;
}
2.top-k问题
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <time.h>
#include<assert.h>
#include<stdlib.h>
typedef int HPDataType;
//交换两个节点
void Swap(HPDataType* p1, HPDataType* p2)
{
assert(p1 && p2);
HPDataType tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//向下调整算法
void AdjustDown(HPDataType* a, int n, int parent)
{
assert(a);
int maxchild = parent * 2 + 1;
while (maxchild < n)
{
//找到左右孩子中的较大者
if (maxchild + 1 < n && a[maxchild] < a[maxchild + 1])
{
maxchild = maxchild + 1;//更新最大孩子
}
if (a[parent] < a[maxchild])
{
Swap(&a[parent], &a[maxchild]);
//更新父子节点
parent = maxchild;
maxchild = parent * 2 + 1;
}
//当父子满足大堆关系时,不进行交换
else
{
break;
}
}
}
//向上调整算法
void AdjustUp(HPDataType* a, int child)
{
assert(a);
int parent = (child - 1) / 2;
while (child > 0)
{
//大堆
if (a[parent] < a[child])
{
Swap(&a[parent], &a[child]);
child = parent;
parent = (child - 1) / 2;
}
else
{
break;
}
}
}
//创建数据文件
void CreateDataFile(const char* filename, int N)
{
FILE* fin = fopen(filename, "w");
if (fin == NULL)
{
perror("fopen fail");
return;
}
srand(time);
for (int i = 0; i < N; i++)
{
fprintf(fin, "%d\n", rand()%100);//产生100以内的随机数
}
fclose(fin);
}
void PrintTopK(const char* filename, int k)
{
assert(filename);
FILE* fout = fopen(filename, "r");
if (fout == NULL)
{
perror("fopen fail");
return;
}
//文件读取成功
//为堆开辟空间
int* minHeap = (int*)malloc(sizeof(int) * k);
if (minHeap == NULL)
{
perror("malloc fail");
return;
}
//读取前k个数到为堆开辟的空间中
for (int i = 0; i < k; i++)
{
fscanf(fout, "%d", &minHeap[i]);
}
//前k个数建小堆.向上调整算法
for (int i = k - 1; i >= 0; --i)
{
AdjustUp(minHeap, i);
}
//依次访问后N-k个数
int val = 0;
while (fscanf(fout, "%d", &val) != EOF)
{
//出现比k个数中最小数大的数,替换并向下调整
if (val > minHeap[0])
{
minHeap[0] = val;
AdjustDown(minHeap, k, 0);
}
}
//打印前k个数
for (int i = 0; i < k; i++)
{
printf("%d ", minHeap[i]);
}
free(minHeap);
fclose(fout);
}
int main()
{
const char* filename = "Data.text";
int N = 100;
int k = 10;
//CreateDataFile(filename, N);
PrintTopK(filename, k);
return 0;
}