优先级队列

news/2025/2/15 15:25:26/

目录

 前言:

1、PriorityQueue的特性

.2 PriorityQueue常用接口介绍

Ⅰ、PriorityQueue常见的构造方法

 Ⅱ、常用的方法

Ⅲ、PriorityQueue的扩容方式:

 3、应用


 前言:

普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用数据结构来实现。
在下面这篇文章中讲解了堆。
八大排序之选择排序_冷兮雪的博客-CSDN博客

1、PriorityQueue的特性

Java集合框架中提供了PriorityQueuePriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线 程不安全的,PriorityBlockingQueue是线程安全的,本文主要介绍PriorityQueue

 查看源码发现:PriorityQueue继承了AbstractQueue,并且初始容量为11,AbstractQueue又实现了Queue接口

 

关于PriorityQueue的使用要注意:
  1.  使用时必须导入PriorityQueue所在的包,即: 
    import java.util.PriorityQueue;
  2.  PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出 ClassCastException异常
  3. 不能插入null对象,否则会抛出NullPointerException
  4.  没有容量限制,可以插入任意多个元素,其内部可以自动扩容
  5. 插入和删除元素的时间复杂度为log₂N
  6. PriorityQueue底层使用了堆数据结构,
  7.  PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素(如果要设置为大根堆的话需要重写比较器来实现或者借助lambda表达式
    package 选择排序;import java.util.PriorityQueue;public class 优先级队列 {public static void main(String[] args) {PriorityQueue<Integer> queue=new PriorityQueue<>();queue.offer(4);queue.offer(2);queue.offer(3);queue.offer(7);queue.offer(9);System.out.println(queue.peek());//2}
    }
    

方法一:比较器

PriorityQueue<Integer> queue=new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o2-o1;}});

方法二:lambda表达式

Queue<Integer> queue = new PriorityQueue<>((o1, o2) -> o2 - o1);

import java.util.Comparator;
import java.util.PriorityQueue;public class 优先级队列 {public static void main(String[] args) {PriorityQueue<Integer> queue = new PriorityQueue<>();queue.offer(4);queue.offer(2);queue.offer(3);queue.offer(7);queue.offer(9);System.out.println(queue.peek());//2PriorityQueue<Integer> queue1=new PriorityQueue<>((o1, o2) -> o2-o1);queue1.offer(4);queue1.offer(2);queue1.offer(3);queue1.offer(7);queue1.offer(9);System.out.println(queue1.peek());//9}
}

2 PriorityQueue常用接口介绍

Ⅰ、PriorityQueue常见的构造方法

构造器
解释
PriorityQueue()
创建一个空的优先级队列,默认容量是11
PriorityQueue(int
initialCapacity)
创建一个初始容量为initialCapacity的优先级队列,注意:
initialCapacity不能小于1,否则会抛IllegalArgumentException异 常
PriorityQueue(Collection<?
extends E> c)
用一个集合来创建优先级队列
import java.util.PriorityQueue;class Student implements Comparable<Student>{public int age;@Overridepublic int compareTo(Student o) {//如果没有比较器,则下面添加时则会报错return this.age-o.age;}
}
public class 优先级队列 {public static void main(String[] args) {PriorityQueue<Student> queue=new PriorityQueue<>();queue.offer(new Student());queue.offer(new Student());}
}

 因为PriorityQueue不能插入无法比较大小的对象,需要实现比较器。

 Ⅱ、常用的方法

Modifier and TypeMethod and Description
boolean
add(E e)
将指定的元素插入到此优先级队列中。
voidclear()
从此优先级队列中册除所有元素。
Comparatore<? super E>

comparator(

返回用于为了在这个队列中的元素,或比较null如果此队列根据所述排序natural ordering的元素。

booleancontains(object o)
如果此队列包含指定的元素,则返回true.
Iteratore<E>iterator()
返回此队列中的元素的迭代器。
booleanoffer(E e)
将指定的元素插入到此优先级队列中。
Epeek ()
检素但不删除此队列的头,如果此队列为空,则返回null.
Epoll()
检索并删除此队列的头,如果此队列为空,则返回null。
booleanremove(object o)
从该队列中删除指定元素的单个实例(如果存在)。
intsize()
返回此集合中的元素数。
object[]toArray()
返回一个包含此队列中所有元素的数组。
<T>  T[]

toArray(T[]a)
返回一个包含此队列中所有元素的数组;返回的数组的运行时类型是指定数组的运行时类型。

Ⅲ、PriorityQueue的扩容方式:

private void grow(int minCapacity) {int oldCapacity = queue.length;// Double size if small; else grow by 50%int newCapacity = oldCapacity + ((oldCapacity < 64) ?(oldCapacity + 2) :(oldCapacity >> 1));// overflow-conscious codeif (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);queue = Arrays.copyOf(queue, newCapacity);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0) // overflowthrow new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}
优先级队列的扩容说明:
  • 如果容量小于64时,是按照oldCapacity2倍方式扩容的
  • 如果容量大于等于64,是按照oldCapacity1.5倍方式扩容的
  • 如果容量超过MAX_ARRAY_SIZE,按照MAX_ARRAY_SIZE来进行扩容

 3、应用

经典优先级队列问题——TOP-K问题:最大或者最小的前k个数据

面试题 17.14. 最小K个数 - 力扣(Leetcode)

class Solution {public int[] smallestK(int[] arr, int k) {
// 参数检测if (null == arr || k <= 0)return new int[0];PriorityQueue<Integer> q = new PriorityQueue<>(arr.length);
// 将数组中的元素依次放到堆中for (int i = 0; i < arr.length; ++i) {q.offer(arr[i]);}
// 将优先级队列的前k个元素放到数组中int[] ret = new int[k];for (int i = 0; i < k; ++i) {ret[i] = q.poll();}return ret;}
}

 692. 前K个高频单词 - 力扣(Leetcode)

 这题既可以使用HashMap也可以使用优先级队列。

优先级队列思想

我们可以创建一个小根优先队列(顾名思义,就是优先队列顶端元素是最小元素的优先队列)。我们将每一个字符串插入到优先队列中,如果优先队列的大小超过了 k,那么我们就将优先队列顶端元素弹出。这样最终优先队列中剩下的 k个元素就是前 k 个出现次数最多的单词。


http://www.ppmy.cn/news/42711.html

相关文章

Ajax简介、axios异步提交

一、Ajax简介 Ajax全称为&#xff1a;“Asynchronous JavaScript and XML”&#xff08;异步JavaScript 和 XML&#xff09; 使用ajax&#xff0c;可以无刷新状态更新页面&#xff0c;并且实现异步提交&#xff0c;提升了用户体验。Ajax其实质是利用浏览器提供的一个特殊的对象…

redis中的持久化操作AOF与RDB区别

通过阅读Redis官网&#xff1a; 持久性&#xff1a;是指将数据写入持久存储&#xff0c;例如固态磁盘 &#xff08;SSD&#xff09; 包括&#xff1a; RDB&#xff08;Redis数据库&#xff09;&#xff1a;RDB持久性按指定的时间间隔执行数据集的时间点快照AOF &#xff08;…

掌握这些“学习方法和工具”,让你事半功倍!

在中国这个高竞争的社会环境下&#xff0c;学习成为了每个人都需要掌握的技能。然而&#xff0c;学习并不仅仅是读书和听课&#xff0c;更是需要一系列高效的方法和习惯来提高效率。本文将介绍一些实用的学习经验和方法&#xff0c;以及推荐一些国内好的学习工具和平台&#xf…

Apollo配置中心使用篇

Apollo配置中心使用篇常见配置中心对比Apollo核心概念Apollo核心特性Apollo架构设计各模块介绍服务端设计客户端设计Apollo与Spring集成的底层原理Apollo安装安装apollo-portalconfig service和admin service部署多网卡问题解决修改Portal环境配置调整ApolloPortal配置Apollo权…

设备是如何实现延时关机的

文章目录1. 引言2. 延时关机的实现方式2.1 自建定时服务实现2.2 RocketMQ中间件实现2.2.1 生成端demo2.2.2 消费端demo3. 结尾1. 引言 在设备联动中&#xff0c;有些场景需要保持设备继续工作一段时间再关机。比如在厨房场景下&#xff0c;存在燃气灶和烟机的联动场景&#xf…

Docker开启并配置远程安全访问

前言 在工作学习中&#xff0c;为了提高项目部署效率&#xff0c;一般会在Idea中直接使用Docker插件连接服务器Docker容器&#xff0c;然后将项目打包与DockerFile一起build成Docker镜像部署运行。但是不可能服务器总是跟着主机的&#xff0c;因此呢时常会面临的一个问题就是从…

LinuxGUI自动化测试框架搭建(一)- 使用前阅读/总体需求

&#xff08;一&#xff09;- 使用前阅读/总体需求1 实现目的2 功能需求3 其他要求4 适用人员5 学习周期6 学习建议7 内容直达8 反馈联系1 实现目的 在LInux操作系统上&#xff0c;针对桌面端软件&#xff0c;模拟用户&#xff08;鼠标、键盘&#xff09;操作&#xff0c;达到…

SCSS中使用typescript变量

TS读取配置文件中的内容后&#xff0c;需要交给定义好的scss元素使用。 读取外放配置信息参见&#xff1a;Vue3TS配置信息外放 在APP.vue中添加如下几部分内容 声名变量&#xff1a; <script lang"ts" setup> //颜色变量来源于外部配置文件&#xff0c;在…