在开始之前有兴趣的hxd可以去看看下面这篇博客,这样可以更好理解以下内容
堆的特殊实现(向下调整算法)及排序_darling-02的博客-CSDN博客
目录
堆的定义
用一个结构体定义:一个数组(可动态增长),数组的大小,数组的数据
//大堆
typedef int TypeHeapDate;
typedef struct Heap
{
TypeHeapDate* a;(动态可增长的数组)
int size;//堆的数据个数
int capacity;//容量(数组的大小)
}Heap;
堆的创建(初始化)
注意开辟空间后里面的数组,不一定是堆,所以需要建堆churu
void HeapCreate(Heap* php, TypeHeapDate* a, int sn)
{
assert(php);
php->a = (TypeHeapDate*)malloc(sizeof(TypeHeapDate)*sn);
if (php->a == NULL)
{
printf("file of malloc");
exit(-1);
}
//拷贝过去 方便后面删除插入(需要开辟空间)
memcpy(php->a,a,sizeof(TypeHeapDate)*sn);
php->capacity = php->size = sn;
//建堆 -》大堆
for (int i = (sn - 1 - 1) / 2; i >= 0; i--)
{
AdjustDownward(php->a,php->size,i);
}
}
堆的销毁
void HeapDestroy(Heap* php)
{
assert(php);
free(php->a);
php->a = NULL;
php->capacity = php->size = 0;
}
堆的插入
插入的数插入后(此时它是数组最后一个数),需要和它的父节点比较
大堆:比父节点小不用向上调整,比父节点大向上调整
例如·在下面数组中插入8 和 88
void AdjustUp(int*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 HeapPush(Heap* php, TypeHeapDate x)
{
assert(php);
//满了需要增容
if (php->capacity == php->size)
{
TypeHeapDate* newspace = (TypeHeapDate*)realloc(php->a,sizeof(TypeHeapDate)*php->capacity*2);
if (newspace == NULL)
{
printf("file of relloc");
exit(-1);
}
php->a = newspace;
php->capacity *= 2;
}
//int push = php->size - 1;
php->a[php->size] = x;
php->size++;
//插入后需要考虑插入数的大小 需要向上调正
AdjustUp(php->a,php->size-1);
}
堆的删除
堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整
void HeapPop(Heap* php)
{
assert(php);
//保证有数可删
assert(php->size > 0);
//删除先把第一个和最后一个数交换 重新向下调整
Swap(&php->a[0], &php->a[php->size - 1]);
php->size--;
AdjustDownward(php->a, php->size, 0);
}
获取堆顶元素
TypeHeapDate HeapTop(Heap* php)
{
assert(php);
assert(php->size > 0);
return php->a[0];
}
堆的数据个数
int HeapSize(Heap* php)
{
assert(php);
assert(php->size > 0);
return php->size;
}
堆是否为空
bool HeapEmpty(Heap* php)
{
assert(php);
return php->size == 0;
}
堆的打印
void HeapPrint(Heap* php)
{
/*for (int j = 0;j < php->size;j++)
{
printf("%d ",php->a[j]);
}
printf("\n");*/
int num = 0;
int maxnum = 1;
for (int i = 0; i < php->size; i++)
{
printf("%d ",php->a[i]);
num++;
//控制打印出来每行的个数
if (num == maxnum)
{
printf("\n");
maxnum *= 2;
num = 0;
}
}
printf("\n\n");
}