建堆必须用到的向下调整方法

堆实际还是一个数组,但是我们会把它画成一个完全二叉树的样子

堆的性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

                                        

例子讲解

这里随便给一个乱序数组,并根据层序遍历画成二叉树的样子

{65,27,28,34,18,49,25,19,37,15}

                                     

                                    

采用向下调整,并不是从第一个元素开始向下调整,而是从下往上第一个非叶子节点开始,也就是如图的25,之后就是49,18,34,28,27,65;

调整大概就是:

找到他的左右孩子的最小的一个child,如果父节点parent小于这个child节点,就不交换,这个父节点就向下调整结束;如果父节点parent大于child就交换,此时父节点就变成子节点,再以该节点为父节点,找到他的两个孩子节点中的较小的一个,如果父节点parent小于这个child节点,就不交换,这个父节点就向下调整结束;如果父节点parent大于child就交换,以此类推;

比如图中的18,由于没有右孩子,所以15是最小的一个,又因为18大于15,所以交换;

                                      

18就变成父节点,由于此时18没有孩子节点,所以18向下调整结束;

再比如经过多次交换:

                                      

除了65都交换结束了,15与65交换,18在与65交换,27在于65交换,就此所有元素向下调整结束;

代码展示:

public void createHeap(int[] array) {
    int parent=(array.length-1-1)/2;
    while(parent>=0){
        shiftDown(parent,array.length-1);
        parent--;
    }
}

private void shiftDown(int root,int end) {
    int parent=root;
    int child=parent*2+1;
    while(child<=end){
        if (child + 1 <= end && elem[child+1] < elem[child]){
            child++;
        }
        if(elem[child]<elem[parent]){
            swap(child,parent);
            parent=child;
            child=parent*2+1;
        }else{
            break;
        }
    }
}

以此建小堆为例,尝试建一个大堆,用向下调整的方法;

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a添砖Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值