Java精讲建立小根堆问题

一.小根堆

大根堆实际上就是一组数据  可以按照二叉树的逻辑结构进行建立,并且进行相关的算法                                                                      

二.建立小根堆

如何建立小根堆

大根堆的意思就是堆顶元素永远比它左右孩子元素大,也就是说 首先比较俩孩子节点,找到其中最大的元素,然后这个最大的元素和堆顶元素(父亲节点)进行比较。然后大的当父亲,小的当孩子去(也就是交换元素)。

数组中每个元素都是有下标的,        70的下标是0   

                                ​​​​​​​        ​​​​​​​                  56的下标是1   

                ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​           30的下标是2           这在左上图 指的是父亲节点

那么如何获得每一棵树的父亲节点呢?

我们发现我们只需要获得 0 1 2下标就可以了  

通过观察可以发现   (数组长度 - 1 - 1) / 2 可以得到 30节点的下标,也就是2 

代码如下

public void createHeap(int[] array) {
        //传建一个大根堆
        for (int parent = (array.length - 1 - 1) / 2; parent >=0 ; parent--) {
            shiftDown(array,parent,array.length);
        }
    }

父亲节点就是  (数组长度 - 1 - 1) / 2   

我们首先要做的就是要调整每一棵小树  也就是0 1 2 下标的树

那么如何得到孩子节点呢?

举个例子 我想要通过 56(1) 来找到15(4) 和 25 (3) 

                ​​​​​​​        ​​​​​​​        ​​​​​​​        父亲节点*2 + 1 就能找到 25 那么 15也能找到

代码如下

public void shiftDown(int parent,int length) {
        ;
        //向下开始调整 先标记最后一个父节点,依次往上调整
        int child = 2 * parent + 1; //此时的child下标为5
        //什么时候停止循环? 当我的child大于当前数组下标的时候
        while (child < length) {
            //开始判断左右孩子节点值的大小
            //此处需要注意 如果当前左孩子就是当前最大的下标,那么在进行比较的时候会出现数组越界异常
            //所以有可能子树只有一个左孩子
            if(child+1 < length && elem[child] > elem[child + 1]) {
                child++;
            }
            //开始判断最大的孩子和父亲节点
            if(elem[child] < elem[parent]) {
                //如果孩子节点比父亲节点小,开始交换
                int tmp = elem[child];
                elem[child] = elem[parent];
                elem[parent] = tmp;
                //交换完成之后 继续向下调整parent树,因为不知道5的下面是否还有子树
                parent = child;
                child = parent * 2 + 1;
            } else {
                //如果父亲节点大于当前最大的孩子节点,说明父亲节点是最大的,无需比较与交换
                break;
            }
        }
    }


  public void swap(int[] array,int index1 ,int index2) {  //交换函数
        int tmp = array[index1];
        array[index1] = array[index2];
        array[index2] = tmp;

    }

此时我们就建立好了一个小根堆

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值