文章目录

  • 前言
  • 一、概念及应用场景
  • 二、原理及源码分析
    • 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详解(附图)相关推荐

  1. JAVA中priorityqueue详解

    Java中PriorityQueue通过二叉小顶堆实现,可以用一棵完全二叉树表示.本文从Queue接口函数出发,结合生动的图解,深入浅出地分析PriorityQueue每个操作的具体过程和时间复杂度, ...

  2. 优先队列——PriorityQueue详解

    优先队列 PriorityQueue(优先队列) 采用的是堆排序, 实际上是一个堆(不指定Comparator时默认为最小堆) 队列既可以根据元素的自然顺序来排序,也可以根据 Comparator来设 ...

  3. java多线程学习-java.util.concurrent详解

    http://janeky.iteye.com/category/124727 java多线程学习-java.util.concurrent详解(一) Latch/Barrier 博客分类: java ...

  4. java多线程设计模式详解[推荐]

    java多线程设计模式详解[推荐] java多线程设计模式详解之一 线程的创建和启动 java语言已经内置了多线程支持,所有实现Runnable接口的类都可被启动一个新线程,新线程会执行该实例的run ...

  5. Java内存溢出详解之Tomcat配置

    Java内存溢出详解 转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError ...

  6. java基础(十三)-----详解内部类——Java高级开发必须懂的

    java基础(十三)-----详解内部类--Java高级开发必须懂的 目录 为什么要使用内部类 内部类基础 静态内部类 成员内部类 成员内部类的对象创建 继承成员内部类 局部内部类 推荐博客 匿名内部 ...

  7. Java类加载机制详解【java面试题】

    Java类加载机制详解[java面试题] (1)问题分析: Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数 ...

  8. Java线程池详解学习:ThreadPoolExecutor

    Java线程池详解学习:ThreadPoolExecutor Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) - zhangpeterx的博客 在源码的目录java/util/ ...

  9. Java 线程池详解学习:FixedThreadPool,CachedThreadPool,ScheduledThreadPool...

    Java常用的线程池有FixedThreadPool和CachedThreadPool,我们可以通过查看他们的源码来进行学习. Java的源码下载参考这篇文章:Java源码下载和阅读(JDK1.8) ...

最新文章

  1. java.lang.IllegalArgumentException: Can only use lower 16 bits for requestCode
  2. python小工具封装_python接口自动化(二)——封装需要用到的工具类
  3. 学习Python遇到的热门问题整理
  4. mysql数据库备份还原
  5. eclipse中hibernate和mybatis中xml配置文件的没有标签提醒解决方法
  6. MySQL SHELL 缓存历史命令
  7. Linux内核 触摸板,Linux下关闭触摸板和触摸杆
  8. 服务器端提交form
  9. arcgis利用Model Builder构建器进行批量处理数据
  10. 传感器实验——LCD显示SHT20
  11. 【嵌入式】MCU外接Flash图片数据存取实例
  12. jquery 实现的省市区级联,无ajax
  13. 九九乘法表居中c语言,JavaScript实现九九乘法表的简单实例
  14. R语言入门——常用函数50个
  15. 项目实训-中医药知识图谱5
  16. Android - xml动画,识别手势动作,代码抽取,获取手机SIM卡串号,获取联系人数据,开机广播,发送/解析短信,报警音乐
  17. 基于JSP的婚恋交友网
  18. 程序员必备的17个软件开发工具
  19. 【初等数论】整除、公约数、同余与剩余系
  20. R语言逻辑回归 logistic regression

热门文章

  1. 计算机cdef盘无法显示,win7计算机不显示硬盘分区盘符
  2. java apdu读取社保卡_使用javax.smartcardio的用于智能卡的ISO 7816 APDU
  3. Markdown的基本使用
  4. 2019年,把时间分给靠谱的人和事!(三月复盘)
  5. 看到别人比自己优秀,为何会难受?
  6. Unity 之 Ping类简析尝试使用
  7. 程序员找不到合适工作的原因总结
  8. 浏览器主页进来是hao123
  9. Precision、Recall、F1-score、Micro-F1、Macro-F1、Recall@K
  10. 鲸会务会议管理系统线上会议邀约、推广、获客、互动一站式解决方案