转载请注明源出处:http://www.cnblogs.com/lighten/p/7299233.html

1.前言

  本章介绍队列中的PriorityQueue--优先队列,顾名思义,这是一个可以指定特定排序的队列。有些违背队列的先入先出,但是其是按照有序的出队列,也是一个比较实用的类。

2.PriorityQueue

  PriorityQueue继承自抽象父类AbstractQueue,其数据结构依旧保持简单:

  一个数组队列,一个大小,一个排序规则的比较器。如果比较器为null的时候,就按照元素自身的compareTo方法进行比较排序。这个队列和之前容器又在初始化的大小和扩容大小上不一致,其默认大小为11,大小小于64的时候扩容后为原来的3倍,大于64的时候,扩容后打下是原来的2倍。

  PriorityQueue的add(E)方法和offer(E)方法是一样的。

  先判断容量大小,再判断是否是第一个,最后进行排序。

  这个排序看过去有些奇怪,怎么有parent,并且下标是(k-1)>>>1呢?其实这里的操作就反应了优先队列的真正数据结构,其实际上是一个二叉树,将二叉树存储在数组之中而已。根节点就是数组的0位。下图给出其具体结构:

  上图就是随手画的一个二叉树,下面是对应的二叉树的数组中的位置。二叉树存入数组的方式很简单,就是从上到下,从左到右。PriorityQueue的是一个有特点的完全二叉树,且不允许出现null节点,其父节点都比叶子节点小,这个是堆排序中的小顶堆。如果按数组顺序我们可以得到如下结论:

    左叶子节点=父节点下标*2+1

    右叶子节点=父节点下标*2+2

    父节点=(叶子节点-1)/2

  插入节点也就比较好处理了,和父节点比较,大于父节点的就不动,小于父节点的就上浮,这就是siftUp方法的作用了。顺便一提,最小堆并不保证左右节点的大小关系,只关心父节点和子节点的关系。

  由上面的叙述,不难看出优先队列如果不进行调整,是无法保证优先顺序的,子节点大小是无序的。所以每次出队列的都是根元素,根元素肯定是最小的。移除了一个元素后,树的结构势必会被破坏,所以每次的移除操作都会调整树,保证其符合定义。

  siftDown就是用于做这样的调整的,其具体实现如下:

  看代码就可以知道,其移除节点之后,是判断了左右节点小的那个进行上浮的,而后循环上浮。

  移除任意一个位置的内容时,其是将最后一个元素取出来变成null了。然后调用siftDown,重新找到最后一个元素应该去的位置,其它元素填补移除位。一般而言这样就应该足够了,但是在某些情况下还需要进行后面的元素与前面进行交换。就像代码中所表现的一样,最后一个元素正好填补的是移除的那个空缺,此种情况下并不能说明该结构是正确的,造成这种现象的原因就在于优先队列并不保证左右的大小顺序,看下图就能很好理解问题所在,并且此种情况需要进行siftUp(),当发生这种异常的情况,才会返回这个异常值,其它时候都是返回null.

3.示意图

  移除任意位置的图就不再给出了,2小结结尾已经进行过说明,先进行一次siftDown,再进行一次siftUp。

4.其它参考文章

  http://www.cnblogs.com/CarpenterLee/p/5488070.html

Java之集合(六)PriorityQueue的更多相关文章

  1. Java学习第六篇:集合类

    一.Java集合类框架 Java集合大致可分为Set.List和Map三种体系,其中Set代表无序.不可重复的集合:List代表有序.重复的集合:而Map则代表具有映射关系的集合:从Java5以后,J ...

  2. 【Java】集合_学习笔记

    一.集合 1.集合类也称容器类,主要负责保存.盛装其他数据. 2.集合可以保存数量不确定的数据,保存具有映射关系的数据(也称关联数组). 3.Java5后提供一些多线程安全的集合类,放在java.ut ...

  3. Java学习-集合(转)

    在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!java中集合大家族的成员实在是太丰富了,有常用的ArrayList. ...

  4. 浅谈Java的集合框架

    浅谈Java的集合框架 一.    初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...

  5. java的集合框架set 和map的深入理解

    Java的集合框架之Map的用法详解 Map有两种比较常用的实现:HashMap 和 TreeMap. HashMap: HashMap 也是无序的,也是按照哈希编码来排序的,允许使用null 值和n ...

  6. Java面试集合(七)

    前言: Java面试集合(六) 的回顾,对于final可以修饰常量,方法,和类,一旦常量定义好后就不可改变,而方法,用final来修饰方法,方法不可重载,继承,重写,final用来修饰类,该类不能被继 ...

  7. Java面试集合(三)

    前言 大家好,给大家带来Java面试集合(三)的概述,希望你们喜欢 三 1.在Java中是否可以含有多个类? 答:可以含有多个类,但只有一个是public类,public类的类名与文件名必须一致. 2 ...

  8. 算法篇(前序)——Java的集合

    菜鸟拙见,望请纠正:附上JDK参考文档(中文文档和英文文档):链接:https://pan.baidu.com/s/14KDmCtQxeGCViq7e0zENjA 密码:e9xs  以及算法篇全文链接 ...

  9. Java基础-集合的嵌套

    Java基础-集合的嵌套 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.静态导入 静态导入是在JDK1.5后的新特性,可以减少开发的代码量,但是实际用处是很一般,静态导入的标准 ...

随机推荐

  1. IntelliJ IDEA 2017版 开发SpringBoot的全局配置文件使用

    一.全局配置文件 描述:     Spring Boot项目使用一个全局的配置文件application.properties或者是application.yml,在resources目录下或者类路径 ...

  2. UVa 12545 Bits Equalizer (贪心)

    题意:给出两个等长的字符串,0可以变成1,?可以变成0和1,可以任意交换s中任意两个字符的位置,问从s变成t至少需要多少次操作. 析:先说我的思路,我看到这应该是贪心,首先,如果先判断s能不能变成t, ...

  3. UVa 10881 Piotr's Ants (等价变换)

    题意:一个长度为L的木棍上有n个蚂蚁,每只蚂蚁要么向左,要么向右,速度为1,当两只蚂蚁相撞时, 它们同时掉头.给定每只蚂蚁初始位置和朝向,问T秒后,每只蚂蚁的状态. 析:刚看到这个题时,一点思路也没有 ...

  4. POJ 3320 Jessica's Reading Problem (滑动窗口)

    题意:给定一个序列,求一个最短区间,使得这个区间包含所有的种类数. 析:最近刚做了几个滑动窗口的题,这个很明显也是,肯定不能暴力啊,时间承受不了啊,所以 我们使用滑动窗口来解决,要算出所有的种数,我用 ...

  5. 自定义方法实现strcpy,strlen, strcat, strcmp函数,了解及实现原理

    位置计算字符串长度 //strlen()函数,当遇到'\0'时,计算结束,'\0'不计入长度之内 //字符串的拷贝        //strcpy(字符串1,字符串2);        //把字符串2 ...

  6. hdu 1231 最大连续子序列 ,1003 Max Sum;

    题目(1231) #include<stdio.h> #include<iostream> using namespace std; int main() { int K,nu ...

  7. Spring容器中bean的生命周期以及关注spring bean对象的后置处理器:BeanPostProcessor(一个接口)

    Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1.通过构造器或工厂方法创建 Bean 实例 2.为 Bean 的属性设置值和对其他 Bean 的引用 3.将 Bean 实例传递给 ...

  8. 发个招聘贴,魔都求手游C++后端,UNITY前端,开发实习生

    上海游旺网络科技有限公司成立于2015年5月,是一家极具潜力的新创移动游戏公司.公司初创团队均来自腾讯,盛大,畅游,墨麟,蜗牛等知名互联网公司,公司创始人团队参与制作过<鬼吹灯><Q ...

  9. Python学习-35.Python中的List Comprehensions(列表解释|列表生成式)

    在某些情况下,我们需要对列表进行某些操作,例如对列表中的每一个元素都乘以2,这样一般来说就是遍历每个元素在乘以2.那么写下来就得两行了.而且这会修改原来的列表,如果要求不能修改原来的列表,又得多一行了 ...

  10. Google Summer of Code礼包

    这个暑假参加google summer of code, 给Google的分布式容器管理系统kubernates开发新的特性,希望从中学习更多的分布式的技术,锻炼自己的编程技巧. 中午在学校的图书馆吗 ...