二叉堆中上滤和下滤的问题

在学习到堆排序时,对于上滤和下滤的知识掌握的不清楚,回来复习了一下。有了些感悟,记下来。


上滤(percolate up)
上滤一般应用于在一个已经排序好的二叉堆中插入一个新节点。通过上滤,使堆在容纳了新节点后仍能保持原来的堆序。
上滤的主要思想:
首先在堆末新建一个空间,称为空穴(hole),然后比较穴的值和其父节点的值。如果空穴的当前位置满足整个堆的堆序,那么就把要插入的值赋给空穴;否则,交换空穴和父节点的位置。迭代实现上面的过程,直到符合整个堆的堆序为止。从宏观上看,空穴会自下而上 地到达满足堆序的位置,称为上滤(percolate up)。


下滤(percolate down)
下滤一般应用于删除了堆顶后的堆序重整过程中。通过下滤,使堆在删除堆顶后把新的堆顶放置在满足堆序的正确的位置上。同时,亦可应用于对一个无序数组的堆排序的算法中。把数组视为一个无序的堆,通过下滤,使堆重新满足一定的堆序。
下滤一般针对堆中的某一个位置进行,传入的参数一般为三个:数组的引用&v、下滤的位置i、数组的大小n(也可以重载为4个参数,添加一个比较器来确定下滤为最大堆还是最小堆。)。假设下滤为最小堆,首先寻找该节点的左右两个孩子中最小的孩子,然后比较该节点和最小的孩子,如果孩子比较小,就交换二者的位置。迭代进行这个过程,直到该节点为叶子节点为止。从宏观上看,节点会在以该节点为根的堆中,自上而下地到达其满足整个堆序的正确位置,称为下滤(percolate down)
在删除堆顶后的堆序重整过程中,堆末的元素会放入堆顶,而其他元素位置不变,从而保证了所有真子堆满足堆序,所以只需对堆顶执行下滤即可。
在堆排序的过程中,由于不是所有元素都按照堆序排列,因此需要对每一个非叶子节点进行下滤。节点进行下滤的顺序是,从堆中最后一个非叶子节点开始,到堆顶结束。这样可以保证对于每个即将进行下滤的节点,以他们为根的子堆都是满足堆序的,因此对该节点下滤后以该节点为根的堆可以得到正确的堆序。(为什么不从叶子节点开始下滤?因为下滤过程不会对叶子节点进行,所以没有必要从叶子节点开始,只需从n / 2的位置开始就可以了)


最后总结一下构造堆的方法
对于一个无序数组,构造一个堆的方法有两种:
1. 建立一个数组,遍历无序数组的每个元素,依次对新数组执行堆的插入操作,每次插入都执行一次上滤的过程。
2. 直接从数组中抽象的最后一个非叶子节点开始,对经过的每个节点执行一次下滤的过程,直到抽象的堆顶结束。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值