优先级队列

1、堆

->堆总是一棵完全二叉树

-> 堆中某个节点的值总是不大于或不小于其父节点的值

->堆的所有元素按照顺序存储的方式存储在一维数组中

-> 大根堆【根节点最大】;小根堆【根节点最小】

-> 堆是一棵完全二叉树,因此可以采用层序规则来顺序存储数值。

-> 对于非完全二叉树,不适合用顺序存储的方式。因为会有空间的浪费,导致空间利用率比较低。

2、堆的创建

上边所示二叉树不满足大根堆或者小根堆,所以需要进行调整。

以大根堆为例:【从下边开始】调整后的树:

2-1 建立大根堆

思想:从每棵子树的根节点开始向下调整;对于建大根堆,需要从最下边的子树开始进行调整;

-> 如何确定最后一棵子树根节点的位置:(len-1-1)/2(数组长度为len)

->如何确定下一个根节点的位置:当前根节点的下标-1

->如何调整:每棵子树均实现向下调整

2-2建立大根堆----代码实现

3、堆的插入与删除

3-1堆的插入

思想:step1.将要插入的数据先放在该数组最后一个位置【不是数组长度的最后一个,而是usedSize】;

step2.将插入的该数据与每棵子树的根节点比较,(建立大根堆),如果该节点值比其父结点的值大,就向上调整,直到孩子节点下标为0;

3-1堆的删除

思想:step1.将堆顶元素与最后一个位置元素交换,此时usedSize-1【不是数组长度的最后一个,而是usedSize】;

step2.交换完之后,从0节点开始向下调整即可

4、常用接口介绍

4-1 PriorityQueue

-> PriorityQueue线程不安全,PriorityBlockingQueue是线程安全的;

->不能插入null对象

->优先级队列中放的必须是能够比较大小的对象

->插入和删除元素的时间复杂度:O(log2(N))

->优先级队列没有容量限制,其内部可以自动扩容,可以插入任意多个元素

->优先级队列底层使用了堆数据结构

->目前自己所用的编辑器对于PriorityQueue来说是小堆,如果需要大堆,则需要用户提供比较器。【实现Comparator接口,然后重写该接口中的compare方法即可】

4-2 插入/删除/获取优先级最高的元素

boolean offer(E e):插入元素e,插入成功返回true;不能插入空对象;空间不够时会自动扩容;

E peek():获取优先级最高的元素;如果优先级队列为空,返回null

E poll(): 删除优先级最高的元素并返回

boolean isEmpty():检测优先级队列是否为空,空则返回true

5、堆的典型应用

1、找前k个最大的值

把元素全部放到大根堆里头;最大值即为堆顶元素,弹出K次就可拿到前K个最大值。

eg:

2、上面代码实现的时间复杂度为O(NlogN);

下面实现的为O(logN);

思想:获取前K个最大---->建立小根堆

获取前K个最小---->建立大根堆【如下】

3、堆排序

从小到大排序---->建立大根堆

从大到小排序---->建立小根堆

具体操作如下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值