数据结构-堆

一.定义

堆是一颗具有特定性质的二叉树
满足条件

  1. 非叶子父亲节点一定大于或者小于 叶子子节点
  2. 是一颗完全二叉树

    在这里插入图片描述

大顶堆

非叶子节点一定大于叶子节点

  • a[i] 非叶子节点
  • a[2*i+1] 左叶子节点
  • a[2i + 2] 右叶子节点
    也就是满足 **a[i]>a[2
    i+1] && a[i] > a[2*i] + 2**

小顶堆

非叶子节点一定小于叶子节点

  • a[i] 非叶子节点
  • a[2*i+1] 左叶子节点
  • a[2i + 2] 右叶子节点
    也就是满足 **a[i] < a[2
    i+1] && a[i] < a[2*i] + 2**

二.堆的插入数据

如下图,图引用 https://zhuanlan.zhihu.com/p/39615266
也就是插入26这个节点 与父节点比较如果比父节点大的话就和父节点交换,再和父亲节点去比较,如果还比父亲节点大 则继续交换 直到到达满足a[i]>a[2i+1] && a[i] > a[2i] + 2 为止

  • 假设插入的下标为i 则父节点的下标为 (i-1)*2 或者 (i-1) >>>
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

实现

大顶堆heapify

此处用数组实现

    /**
     * 大顶堆
     * @param array
     */
    public static void maxHeap(int[] array,int length){
        int parent = length/2-1;
        //从最底层 最右边开始遍历
        for(int i=parent;i>=0;i--){
            adjustMaxHeap(array,i,length);
        }
    }

    /**
     *  调整大顶堆
     * @param array
     * @param i 调整开始位置 向下调整
     * @param length  可以自定义堆调整的实际长度
     */
    public static void adjustMaxHeap(int[] array,int i,int length){
        int temp = array[i];
        for(int j=(2*i+1);j<length;j=2*j+1){

            //j代表下一次需要遍历的起始节点
            if(j+1<length && array[j] < array[j+1]){
                j++;
            }
            //如果叶子节点存在大于父节点的值 则交换值
            if(array[j] > temp){
                array[i] = array[j];
                //替换下标 继续遍历 小标为maxIndex之后的数据 也就是 2*maxIndex+1
                i = j;
            }
        }
        array[i] = temp;
    }

小顶堆heapify (和大顶堆类型)

    /**
     * 小顶堆
     * @param array
     */
    public static void minHeap(int[] array,int length){
        int parent = length/2-1;
        for(int i=parent;i>=0;i--){
             adjustMinHeap(array,i,length);
        }
    }

    /**
     * 调整小顶堆
     * @param array
     * @param i
     * @param length
     */
    public static void adjustMinHeap(int[] array,int i,int length){
        int temp = array[i];
        //k是实际继续调整堆的起点
        for(int k=2*i+1;k<length;k=k*2+1){
            //右叶子小于左叶子 k右移
           if(k+1<length && array[k] > array[k+1]){
               k++;
           }
           if(array[k] < temp){
               array[i] = array[k];
               //i变为实际开始遍历的下标 也是等待被替换的小标
               i = k;
           }else {
               break;
           }
        }
        array[i] = temp;
    }

三.入大顶堆

    /**
     * 入大顶堆
     * @param array
     * @param a
     * @param index  入堆小标
     */
    public static void addMaxHeap(int[] array,int a,int index){
        array[index] = a;
        adjustMaxHeap(array,(index-1)/2,index+1);
    }

    /**
     * 入小顶堆
     * @param array
     * @param a
     * @param index
     */
    public static void addMinHeap(int[] array,int a,int index){
        array[index] = a;
        adjustMinHeap(array,(index-1)/2,index+1);
    }

四.弹出大顶堆

/**
 * 弹出大顶堆  堆首和堆尾交换后 重新堆话
 * @param array 已经堆化的大顶堆
 * @return
 */
public static int popMaxHeap(int[] array){
     int pop = array[0];
     array[0] = array[array.length-1];
     array[array.length-1] = pop;
     maxHeap(array,array.length-1);
     return pop;
}

五.弹出小顶堆

   /**
     * 弹出小顶堆  堆首和堆尾交换后 重新堆话
     * @param array 已经堆化的小顶堆
     * @return
     */
    public static int popMinHeap(int[] array){
        int pop = array[0];
        array[0] = array[array.length-1];
        array[array.length-1] = pop;
        minHeap(array,array.length-1);
        return pop;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值