java | 堆 - 基本操作实现(1)

概念

  1. 堆逻辑上是一棵完全二叉树
  2. 堆物理上是保存在数组中
  3. 满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆
  4. 反之,则是小堆,或者小根堆,或者最小堆
  5. 堆的基本作用是,快速找集合中的最值

在这里插入图片描述
操作-向下调整and向上调整
目的:把一个不满足堆的结构调整成满足堆的结构
操作-建堆
下面我们给出一个数组,这个数组逻辑上可以看做一颗完全二叉树,但是还不是一个堆,现在我们通过算法,把它构建成一个堆。
根节点左右子树不是堆,我们怎么调整呢?
这里我们从倒数的第一个非叶子节点的子树开始调整,一直调整到根节点的树,就可以调整成堆。

具体代码

import java.util.Arrays;

public class heap {

    //向下调整,按大堆实现(父节点值大于子节点)
    public static void shiftdown(int []array,int size,int index){
        //array表示要处理的数组。size表示处理的数据大小,index表示从什么位置开始处理。

        int parent = index;
        int child = parent*2 +1;
        //已知双亲(parent)的下标,则:左孩子(left)下标 = 2 * parent + 1; 右孩子(right)下标 = 2 * parent + 2;
        //已知孩子(不区分左右)(child)下标,则: 双亲(parent)下标 = (child - 1) / 2;

        while (child < size){ //child > size说明parent无子节点
            if(child + 1 < size && array[child] < array[child+1]){
                //找到子节点中较大的下标
                child = child + 1;
            }
            if(array[child] > array[parent]){
                // 若子节点值大于父节点值,交换。
                int tem = array[child];
                array[child] = array[parent];
                array[parent] = tem;
            }else{   //否则,说明符合要求,停止当前循环
                break;
            }
            parent = child;  //当前的子节点重新当作父节点,继续循环
            child = 2 * parent + 1;
        }
    }

    //向上调整,基本思路相同,不写注释
    public  static void shiftfup(int []array,int index){
        int child = index;
        int parent = (child -1) /2;
        while (child > 0){
            if(array[child] > array[parent]){
                int tem = array[child];
                array[child] = array[parent];
                array[parent] = tem;
            }else {break;}
            child = parent;
            parent = (child -1) /2;
        }
    }

    public static void creat(int array[],int size){
        //若基于向下调整建堆,则需要从后往前遍历。否则会出错
        for(int i = (size-1-1)/2;i >= 0;i--){
            // size-1是找到最后的叶子节点,而再-1并且除2,是找到父节点
            shiftdown( array,size ,i);
        }
    }


    public static void main(String[] args) {
        int []array = {9,5,2,7,3,6,8};
        creat(array,array.length);
        System.out.println(Arrays.toString(array));
    }

}

运行:

// 建堆前
int[] array = { 1,5,3,8,7,6 };
// 建堆后
int[] array = { 8,7,6,5,1,3 };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值