C语言实现的堆的向下调整算法和建堆算法

->Gitee源代码点击这里<-
堆是特殊的二叉树,其性质为:
①堆中的某个结点总是不大于或不小于其子结点
②堆总是完全二叉树。(第1到第n-1层为满,最后一层从左往右结点连续)
我们经常用顺序结构的数组来实现二叉树
对于一个普通的数组int a[10] = {18,29,42,8,50,9,22,88,19,74};
如果该数组表示的是二叉树,则其逻辑结构为
image.png
而目前该二叉树还能称为堆,所以我们要借助一些算法来把一个表示二叉树的数组变成堆。

一、向下调整算法

当父节点的子树已经是大堆或者小堆,而整个二叉树还不满足堆的条件时,则需要向下调整算法来把二叉树变成堆
image.png
如图,根节点18的子树都符合大堆的条件(父节点>=子结点),但二叉树本身还不是大堆,这是我们就需要利用向下调整算法来将该二叉树调整为大堆,即:
image.png
调整思路:
以二叉树{18,29,42,8,28,9,22,3,4,19}为例
从需要调整的那个结点开始,把该节点视作父节点,比较其子节点的大小,取大的那个和父结点比较,如果大于父节点,则交换两个结点的值
image.png
图中要调整的是结点18 ,比较其两个子节点29 和42的大小,42较大,再比较42和18,42较大,交换42和18
此时42变为根结点,18变为右子树的父节点。如下图:
image.png
此时二叉树仍然不满足大堆的条件,以18为父节点的右子树还符合大堆的条件,仍需要向下调整,重复上述步骤,交换18 和 22:
image.png
得到下图结果:
image.png
此时二叉树已经调整为大堆
其用数组表示为:{42,29,22,8,28,9,18,3,4,19};
我们借助该例子来写出大堆的向下调整算法的代码实现
实现代码时,我们要了解以下内容:
a. 父节点坐标parent和子节点的关系为:
右子结点坐标 right= parent*2+2;
左子节点坐标 left = parent*2+1;
b. 设计算法函数时,我们不但要将数组传给函数,还要告诉函数从那个结点开始调整,即参数还需要一个坐标变量;同时调整过程是一个循环的动作,还需要传入数组的长度控制循环的停止
c. 向下调整的过程中(以调大堆为例),本质是就是不断地调整父节点和子节点的关系;当父节点比两个子结点中最大的那个结点还要小时,则说明还需要调整;反之则已经调整完成
d. 调整过程中可能会出现一个父节点只有一个子节点的情况,如上图中的[4]结点和[9]结点,此时则要注意细节,防止越界访问

void Swap(int* a
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值