//我先以大堆的实现为例
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int HPDataType;
typedef struct Heap//堆的存储结构是顺序存储,以数组结构存储数据,但逻辑结构是二叉树
{
HPDataType* _a;
int _size;//下标
int _capacity;//容量大小
}Heap;
// 堆的构建
void HeapCreate(Heap* hp)
{
hp->_a = NULL;
hp->_size = 0;
hp->_capacity = 0;
}
// 堆的销毁
void HeapDestory(Heap* hp)
{
assert(hp);
free(hp->_a);
hp->_a = NULL;
hp->_capacity = 0;
hp->_size = 0;
}
// 堆的插入
void HeapPush(Heap* hp, HPDataType x)
{
assert(hp);
//判断容量大小
HPDataType newcapcity;
if (hp->_capacity == hp->_size)
{
newcapcity = hp->_capacity==0? 4 : hp->_capacity * 2;//三目操作符,
//如果原来的堆容量为0,就给他先创建一块空间。如果有空间,就对他进行二倍扩容
HPDataType* tmp = realloc(hp->_a, sizeof(HPDataType) * newcapcity);
if (tmp==NULL)//判断realloc返回的地址是否为空,即扩容是否成功
{
perror("realloc fail");
return;
}
else//更新空间大小
{
hp->_a = tmp;
hp->_capacity = newcapcity;
}
}
hp->_a[hp->_size] = x;
hp->_size++;
Adjustup(hp->_a,hp->_size-1);//向上调整,调整插入的数的位置,让小的数在前面
// 堆的删除
void HeapPop(Heap* hp)
{
assert(hp);
assert(hp->_size > 0);
Swap(&hp->_a[0], &hp->_a[hp->_size - 1]);
hp->_size--;
Adjustdown(hp->_a, hp->_size, 0);
}
// 取堆顶的数据
HPDataType HeapTop(Heap* hp)
{
return hp->_a[0];
}
// 堆的数据个数
int HeapSize(Heap* hp)
{
return hp->_size;
}
// 堆的判空
int HeapEmpty(Heap* hp)
{
assert(hp);
return hp->_size == 0;
}
//向上调整 注:在数列数中,树节点的左孩子的下标=父节点下标*2+1,右孩子的下标=父节点下标*2+2
void Adjustup(HPDataType* a, HPDataType child)
{ //因为push后,数据越来越多,数据应该从后往前调整,
//所以默认传进来的下标为child,chiid是最后一个数据的下标
assert(a);
HPDataType parent = (child - 1) / 2;
while(child>0)
{
if (a[child] < a[parent])//child在后面,如果child的数更小,就跟parent换位置,
{
Swap(&a[child], &a[(child - 1) / 2]);
}
else break;
}
}
//向下调整
void Adjustdown(HPDataType* a, HPDataType n, HPDataType parent)
{
assert(a);
HPDataType child = parent * 2 + 1;
//用假设法,求出小的孩子,默认左孩子更小
while(child>n)
{
if (a[child] > a[child + 1])
{
child++;
}
if (a[child] < a[parent])
{
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else break;
}
}
//交换
void Swap(HPDataType* x, HPDataType* y)
{
HPDataType tmp = *x;
*x = *y;
*y = tmp;
}
//打印
void Print(HPDataType* a, HPDataType n)
{
for (int i = 0; i < n; i++)
{
printf("%d\n", a[i]);
}
}
//测试代码
void Test1()
{
Heap Hp ;
HeapCreate(&Hp);
HeapPush(&Hp, 2);
HeapPush(&Hp, 1);
HeapPush(&Hp, 6);
HeapPush(&Hp, 3);
HeapPush(&Hp, 8);
int size = HeapSize(&Hp);
Print(Hp._a, size);
}
int main()
{
Test1();
return 0;
}
结果为
其大堆结构示意图为