提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本文采用小堆(数组),向下调整算法(要注意左右分树都为小堆,根节点这颗树不满足才可以使用向下调整算法)
一、小堆是什么?向下调整是什么?
小堆
逻辑结构如下:
在数组中如下:
可以抽象理解为:
每一个父节点都要小于子节点称为小堆(反之为大堆)
向下调整
因此我们可以从倒数第一个根节点开始(n-1-1)/2从后往前依次调整
二、代码实现
1.向下调整函数
代码如下(示例):
void Swap(HPDataType* p1, HPDataType* p2)
{
HPDataType temp = *p1;
*p1 = *p2;
*p2 = temp;
}
//向下调整(左右分树为小堆)
void AdjustDown(HPDataType* a, int len ,int root)
{
//找出左右孩子最小的哪个
int parent = root;
int child = parent * 2 + 1;
while (child < len)
{
if (a[child] > a[child + 1] && (child + 1) < len)//找出左右孩子中最小的那个(注意child+1要小于数组长度防止越界)
{
child++;
}
if (a[child] < a[parent])//如果父亲小于最小的孩子则交换
{
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else//否则结束
{
break;
}
}
}
//堆初始化
void HeapInit(Heap* php, HPDataType* a, int len)
{
assert(a);//判断数组传址不能为空
php->_a = (HPDataType*)malloc(sizeof(HPDataType) * len);//动态开辟内存空间
memcpy(php->_a, a, sizeof(HPDataType) * len);//使用内存拷贝将数组a拷贝到结构体_a
php->_size = len;
php->_capacity = len;
//构建堆
for (int i = (len - 1 - 1) / 2; i >= 0; i--)
{
AdjustDown(php->_a, php->_size, i);
}
}
2.运行结果
样例
结果