堆(heap)基础总结

二叉树的顺序存储

1.使用数组来保存二叉树结构,就是将二叉树层序遍历放到数组中。在这里插入图片描述
这种方法一般指适用于完全二叉树,因为非完全二叉树会存在空间上的浪费。主要用法,就是堆的表示
2.在数组中的下标的关系

  • 已知根节点下标(parent),则:
  • 左子树下标=2*parent+1
  • 右子树下标=2+parent+2
  • 已知左右子树(child)下标,则:
  • 根节点下标=(child-1)/2

堆的概念

1.概念:

  • 堆在逻辑上,是一颗完全二叉树
  • 堆在物理形式上,是保存在数组中的
  • 堆有两种形式:所有节点的根节点的值大于其左右子树节点的值,则为大堆。
    所有节点的值都小于其左右子树节点的值,则为小堆。
  • 基于第三点,堆的基本作用,快速的在集合中找最值。(根节点)

堆的操作

1:向下调整(将一个不是堆结构的二叉树调整为堆结构)前提:左右子树必须已经是一个堆,才能调整。
一旦堆里面元素发生改变(插入或删除),就要对堆结构进行调整,堆的规则不能破坏。
思路及代码:
1.堆是完全二叉树,没有左子树则一定没有右子树,又因为堆的存储结构是数组,所以可以通过判断左子树的下标是否越界来判断是否含有左子树(left<size)
2.再判断是否含有右子树,确定左子树和右子树的最小值,再将最小值与根节点值比较,因为是设定是小堆,所以若最小值小,则与根节点值交换,最小值大,则不动。
若没有右子树,则直接比较根节点值与最小值(此时最小值就是left)
3.因为min位置的堆性质可能被破坏,所以要将min重新视为新一轮的根节点(index),重复上述比较过程。
时间复杂度:最坏情况就是从根一路比较到叶子节点,复杂度为:O(log(n));

  //堆的向下调整,以小堆为例
    //size是array哪些元素是有效的堆元素
    //index是从哪个位置的下标开始调整,也就是当前的根节点
    public static void shifDown(int[] array,int size,int index){
        int left=index*2+1;
        while (left<size){//说明左子树是存在的
            int right=index*2+2;
            int min=left;
            if (right<size) {//如果右子树也存在
                if (array[right]<array[left]) {//找到左右子树中较小值的下标,记录近min中去,
                min=right;
                }
            }
                 //比较当前根节点的值和最小值,如果根节点小,则结束本次循环,如果根节点大,则交换。
                if (array[index]<=array[min]){
                    break;
                }
             //交换当前值和左右子树中的最小值,保证根节点的值小于左右子树
             else{
            int temp=array[index];
                array[index]=array[min];
                array[min]=temp;
                }
                //更新当前位置,继续向下调整
            index=min;
            left=index*2+1;
            }

        }

2.建堆
思路及代码:
通过算法将一个数组调整成为一个堆。从倒数第一个叶子节点的父节点开始调整,可用向上调整或向下调整法,直到调整到根节点的树,就ojk。
时间复杂度:看似是O(n*log(n))
实际上是O(n);
因为堆结构调整到一定程度就不需要再继续循环调整了

//建堆时,从前往后遍历:向上调整
    //从后往前遍历:向下调整,从最后一个叶子节点的父节点开始遍历
    //size-1,是最后一个叶子节点的位置,再-1/2,得到该叶子节点的父节点
     // 如果是size-1的话,逻辑无影响,循环会多空转几回
        public  static void createHeap(int[] array,int size){
        for (int i=(size-1-1)/2;i>=0;i--){
            shifDown(array,size,i);
        }
        }

主函数及结果:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值