java优先队列 PriorityQueue详解(附图)
文章目录
- 前言
- 一、概念及应用场景
- 二、原理及源码分析
- 1. 了解继承图
- 2. 优先队列的插入
- 总结
前言
最近接触到优先队列的题目,正好趁这个机会复习一下优先队列,并深入了解一下源码。
一、概念及应用场景
PriorityQueue翻译过来是优先队列,是队列中的一种特殊队列。PriorityQueue里的元素是有序的,默认情况下是单调增,可以通过传入Comparator根据自己的需求来更改。
在概念上,它是一个有序的二叉树,这种顺序的规则是(默认情况下),每个节点的值都比它的孩子节点的值小。一个最小堆如下图所示:
只要符合每个节点的值都比它的孩子节点小即可。
在实现上,它使用数组来存储。因为该最小堆的是完全二叉树,所以按照每层从左向右的顺序存储,那么节点下标为 n 的孩子节点分别(2n+1)和(2n+2)为如上图的存储方式为:
应用场景
* 数据的操作为每次需要取最大值或最小值时
二、原理及源码分析
1. 了解继承图
以上是PriorityQueue属于集合框架下的类。它具有集合的特点,所以集合中的方法它能够使用。PriorityQueue继承自AbstractQueue,不允许插入null元素。
PriorityQueue继承自Queue, 所以在使用上 也继承了Queue的 offer()与poll()。鉴于PriorityQueue的 #有序 它重写了该方法
2. 优先队列的插入
为了保持PriorityQueue元素的有序性,在进行插入时,我们总是对插入后的数组做调整,这种调整的方式如下:
- 首先将新增元素放到队尾
- 将插入元素与它的父节点比较,如果父节点比元素大,将元素与父节点元素调换位置
- 继续将该元素与父节点比较,直到该元素为根节点或比父节点的元素大为止
上述步骤如下图所示
这个时候得到的队列就是有序队列了。那我们来一起看看源码实现的方法吧!
以下是PriorityQueue的offer有关源码(jdk1.8):
public boolean offer(E e) {if (e == null) //判空throw new NullPointerException();modCount++; //记录优先队列修改的次数int i = size;if (i >= queue.length) // 元素的个数大于等于数组的大小grow(i + 1); // 扩容size = i + 1;if (i == 0) //元素个数为空,将元素放入数组的第一个格子中queue[0] = e;elsesiftUp(i, e);// 增加元素return true;}
private void siftUp(int k, E x) {if (comparator != null) //传入了comparator 时siftUpUsingComparator(k, x);else //没有传入comparator 时siftUpComparable(k, x);}
//传入了comparator时
private void siftUpUsingComparator(int k, E x) {//k刚开始为数组中现有元素的最后一个下标while (k > 0) { int parent = (k - 1) >>> 1; //找到k所在位置的父节点下标Object e = queue[parent];//使用传入的comparator比较if (comparator.compare(x, (E) e) >= 0) //比较元素大于父节点,则什么也不做break;//否则将两个值互换queue[k] = e;k = parent;}queue[k] = x;}
没有传入comparator的与传入的同理,比较时使用的是默认的比大小方法:
// 没有传入comparator时
private void siftUpComparable(int k, E x) {Comparable<? super E> key = (Comparable<? super E>) x;while (k > 0) {int parent = (k - 1) >>> 1;Object e = queue[parent];if (key.compareTo((E) e) >= 0)break;queue[k] = e;k = parent;}queue[k] = key;}
总结
PriorityQueue 作为有序队列能很好的解决每次去最大或最小元素的问题。以上就是优先队列的有关内容。
java优先队列 PriorityQueue详解(附图)相关推荐
- JAVA中priorityqueue详解
Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示.本文从Queue接口函数出发,结合生动的图解,深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度, ...
- 优先队列——PriorityQueue详解
优先队列 PriorityQueue(优先队列) 采用的是堆排序, 实际上是一个堆(不指定Comparator时默认为最小堆) 队列既可以根据元素的自然顺序来排序,也可以根据 Comparator来设 ...
- java多线程学习-java.util.concurrent详解
http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...
- java多线程设计模式详解[推荐]
java多线程设计模式详解[推荐] java多线程设计模式详解之一 线程的创建和启动 java语言已经内置了多线程支持,所有实现Runnable接口的类都可被启动一个新线程,新线程会执行该实例的run ...
- Java内存溢出详解之Tomcat配置
Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...
- java基础(十三)-----详解内部类——Java高级开发必须懂的
java基础(十三)-----详解内部类--Java高级开发必须懂的 目录 为什么要使用内部类 内部类基础 静态内部类 成员内部类 成员内部类的对象创建 继承成员内部类 局部内部类 推荐博客 匿名内部 ...
- Java类加载机制详解【java面试题】
Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...
- Java线程池详解学习:ThreadPoolExecutor
Java线程池详解学习:ThreadPoolExecutor Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) - zhangpeterx的博客 在源码的目录java/util/ ...
- Java 线程池详解学习:FixedThreadPool,CachedThreadPool,ScheduledThreadPool...
Java常用的线程池有FixedThreadPool和CachedThreadPool,我们可以通过查看他们的源码来进行学习. Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) ...
最新文章
- java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode
- python小工具封装_python接口自动化(二)——封装需要用到的工具类
- 学习Python遇到的热门问题整理
- mysql数据库备份还原
- eclipse中hibernate和mybatis中xml配置文件的没有标签提醒解决方法
- MySQL SHELL 缓存历史命令
- Linux内核 触摸板,Linux下关闭触摸板和触摸杆
- 服务器端提交form
- arcgis利用Model Builder构建器进行批量处理数据
- 传感器实验——LCD显示SHT20
- 【嵌入式】MCU外接Flash图片数据存取实例
- jquery 实现的省市区级联,无ajax
- 九九乘法表居中c语言,JavaScript实现九九乘法表的简单实例
- R语言入门——常用函数50个
- 项目实训-中医药知识图谱5
- Android - xml动画,识别手势动作,代码抽取,获取手机SIM卡串号,获取联系人数据,开机广播,发送/解析短信,报警音乐
- 基于JSP的婚恋交友网
- 程序员必备的17个软件开发工具
- 【初等数论】整除、公约数、同余与剩余系
- R语言逻辑回归 logistic regression
热门文章
- 计算机cdef盘无法显示,win7计算机不显示硬盘分区盘符
- java apdu读取社保卡_使用javax.smartcardio的用于智能卡的ISO 7816 APDU
- Markdown的基本使用
- 2019年,把时间分给靠谱的人和事!(三月复盘)
- 看到别人比自己优秀,为何会难受?
- Unity 之 Ping类简析尝试使用
- 程序员找不到合适工作的原因总结
- 浏览器主页进来是hao123
- Precision、Recall、F1-score、Micro-F1、Macro-F1、Recall@K
- 鲸会务会议管理系统线上会议邀约、推广、获客、互动一站式解决方案