上标3下标6算法_图解堆排序算法

堆排序定义一般来说,算法就像数学公式,前人经过不断优化和验证得到有规律性的公式留给后人使用,当然也会交给后人验证的思路。那么堆排序算法就是这样,它有基本固定的定义如下:1、将数组构建为一颗有规则的完全二叉树2、该二叉树任意父结点值必须大于(最大堆)或小于(最小堆)孩子结点3、该二叉树除了最底层外,其它层都是从左往右充满地4、该二叉树任意父结点左孩子数组下标 = 父结点数组下标 * 25、该二叉树任...
摘要由CSDN通过智能技术生成

堆排序定义

一般来说,算法就像数学公式,前人经过不断优化和验证得到有规律性的公式留给后人使用,当然也会交给后人验证的思路。那么堆排序算法就是这样,它有基本固定的定义如下:

1、将数组构建为一颗有规则的完全二叉树

2、该二叉树任意父结点值必须大于(最大堆)或小于(最小堆)孩子结点

3、该二叉树除了最底层外,其它层都是从左往右充满地

4、该二叉树任意父结点左孩子数组下标 = 父结点数组下标 * 2

5、该二叉树任意父结点右孩子数组下标 = 父结点数组下标 * 2 + 1

6、该二叉树任意孩子父结点数组下标 = 孩子结点数组下标 / 2

7、该二叉树高度(所有父结点)= 数组长度 / 2

8、最后再对构建好的二叉树进行排序

图解堆排序

2ad12c1fe123a6e94bf0f32880c2bd4f.png

下面我们通过堆排序算法来实现。

构建最大堆二叉树

将数组构建为一颗有规则的完全二叉树,该二叉树遵循任意父结点必须大于(最大堆)孩子结点。当然,构建最小堆也是可以的,具体看场景来设计,一般从小到大排序可以选择最大堆,从大到小排序可以选择最小堆。当然最大堆也可以实现从大到小排序。

最大堆二叉树定义如下:

1、左孩子结点数组索引=父结点数组索引 * 2。伪代码如下:

private int leftIndex(int i) { return 2 * i;}

2、右孩子结点数组索引=父结点数组索引 * 2 + 1。伪代码如下:

private int rightIndex(int i) { return 2 * i + 1;}

3、父结点数组索引=孩子结点数组索引 / 2

private int parentIndex(int i) { return i / 2;}

为了描述直观,数组下标从1开始,但实际编写代码在操作数组取值时候需要减去1,因为实际程序中的索引是从0开始的。

808f185da2bb16b7fadc502bfa09915a.png

假设我们按数组顺序开始构建

b0c47275d6b02cb48ace53d2bc1bf18a.png

上图满足了父子结点直接的数组索引计算定义,但是它不满足最大堆的定义(任意父结点必须大于孩子结点),父结点6比右子结点9要小,所以我们需要对原数组值进行交换(注意:只是将两个下标对应的值进行交换,下标不变)来满足最大堆二叉树的定义,调整后结果如下:

e477211a7b454815ed38bfbbded2b617.png

此时,再根据定义绘制最大堆二叉树如下:

7d696e34f6372e22e4b7444cbaae3b4d.png

下面我们继续按这种思路构建左孩子结点数组值为3下标为2的左右孩子结点,构建结果如下:

8f95f546e7c07d55c671eb61b54fd7f8.png

按照下标计算公式构建如下:

d7dc2cff9636e93bbd4343d3c08c3d39.png

按照最大堆定义中任意父结点必须大于孩子结点交换后如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值