慕课网liuyubobobo老师课程学习笔记---part7:优先队列和堆

1、什么是优先队列
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、堆的基础表示
在这里插入图片描述

  二叉堆的2个性质:
在这里插入图片描述
在这里插入图片描述
  下面介绍二叉堆的实现技巧:使用数组存储二叉堆(当然,也可以像前面的二分搜索树那样,通过左右指针的指定某个结点的左右孩子)
在这里插入图片描述
在这里插入图片描述

3、二叉堆的各类操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  代码如下:

package com.lkj;
//同样,二叉堆也是树,它里面的结点的值也必须要具有比较性,因为我们规定每一个结点的值必须大于等于它的孩子结点的值
// (大于需要使用compareTo(),如果只是等于重写equals()即可)
public class MaxHeap<E extends Comparable<E>>
{
   
    //使用我们之前定义的动态数组保存二叉堆的元素
    private Array<E> data;
    public MaxHeap(int capacity)
    {
   
        data = new Array<>(capacity);//用户知道堆要存储多少元素:capacity
    }
    public MaxHeap()
    {
   
        data = new Array<>();//用户不知道堆要存储多少元素,不初始化数组容量
    }

//-------------------------------------------------heapify:将任意数组整理成堆的形状

    /**
     * 分析:
     * 方法1:将数组的每一个元素,使用堆的add()方法添加到堆中,由于每次添加一个元素,这个元素都要上浮到合适的位置,
     *      那么添加n个元素,需要上浮n次,每次上浮的时间复杂度是 O(logn),这种方法的时间复杂度是 O(nlogn)
     *
     * 方法2:直接将这个数组看成一个堆,然后,我们找到在数组中下标最大的非叶子结点,从最大的非叶子结点开始,将这些数siftdown 到
     *      合适的位置,最后就可以得到一个满足堆2个性质的堆,这种方法的时间复杂度是 O(n);
     *      另外,下标最大的非叶子结点的 下标=最后一个结点父亲结点的下标!
     *
     * 我们将 heapify() 方法构造成为一个 构造方法
     */
    //首先,我们需要给自己的 Array数组类创建一个:传入一个数组,将这个数组构造成为我们自己的动态数组的构造函数
    public MaxHeap(E[] arr)
    {
   
        data = new Array<>(arr);//通过Array类的构造方法,将普通数组arr转换成为动态数组data,这样我们就可以使用动态数组的方法

        //最后一个结点在数组的下标:data.getSize()-1;最后一个非叶子结点在数组的下标:parent(data.getSize()-1)
        for (int i = parent(data.getSize()-1); i >= 0 ; i--)
        {
   
            siftDown(i);//将这个结点下沉到合适位置
        }
    }
    //这样,通过这个方法我们就 可以通过数组 得到一个堆!

//--------------------------------------------------------------------------------

    // 返回堆中的元素个数
    public int size()
    {
   
        return data.getSize();
    }

    // 返回一个布尔值, 表示堆中是否为空
    public boolean isEmpty()
    {
   
        return data.isEmpty();
    }

//--------------------------------------下面是查找某个在数组中下标为index的结点的父亲结点、左右孩子结点在数组中的下标

    // 返回完全二叉树的数组表示中,一个索引所表示的元素的父亲节点的索引
    private int parent(int index)
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值