ArrayList:动态扩容(相对于数组),数组实现查询非常快但要求连续内存空间。

双向队列LinkedList:不需要像ArrayList一样创建连续的内存空间,它以链表的形式连接各个节点,但是查询搜索效率极低。

HashMap存放键值对:内部使用数组加链表实现,检索快但是由于键是按照Hash值存储的,所以无序,在某些情况下不合适。

TreeMap:使用优化了的排序二叉树(红黑树)作为逻辑实现,物理实现使用一个静态内部类Entry代表一个树节点,这是一个完全有序的结构,但是每个树节点都需要保存一个父节点引用,                       左右孩子节点引用,还有一个value值,虽然效率高但开销很大。

  今天我们将要介绍的PriorityQueue优先队列,更多的可以理解为是上述所有集合实现的一种折中的结构,它逻辑上使用堆结构(完全二叉树)实现,物理上使用动态数组实现,并非像TreeMap一样完全有序,但是如果按照指定方式出队,结果可以是有序的

(补充:完全二叉树:完全二叉树的定义:深度为k,有n个结点的二叉树当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称为完全二叉树。)

一:堆结构的简单介绍:

  堆结构在逻辑上是完全二叉树,物理存储上是数组。

  但是完全二叉树并不是堆结构,堆结构是不完全有序的完全二叉树。我们知道完全二叉树有个非常大的优点,你可以从任意节点根据公式推算出该节点的左右孩子节点的位置以及父节点的位置(也是应为这个优点的原因,物理上用数组的结构来存,因为数组可以随机访问任意位置。)

  当前节点位置为 i ,父节点位置 i/2,左孩子节点位置2*i,右孩子节点2*i+1。利用这个特性,我们就不必维护节点与节点之间的相互引用,TreeMap中定义一个Entry类,分别一个parent引用,left引用,right引用,并使用它们维护当前节点和别的节点之间的关系。而我们利用完全二叉树的这种特性,完全可以用数组作为物理存储。上述完全二叉树可以存储为以下的数组:

逻辑结构:

 物理结构:

堆分大根堆(父节点比子节点的值大)和小根堆(父节点的值比子节点的值小),左右孩子节点的值的大小没有要求,所以我们说堆是不完全有序结构。

添加元素过程:

  • 将新元素添加到堆结构的末尾(不论该值的大小)。
  • 不断调整直至满足堆结构。

 删除元素的过程:

  • 用最后一个元素替换将要被删除的元素并删除最后元素。
  • 判断该节点的值与其子节点中最小的值比较,如果小于最小值则维持堆结构,否则向下调整。
  • 判断该节点的值是否小于父节点的值,如果小于则向上调整,否则维持堆结构。

上面是优先队列的基本原理,下面介绍具体的使用方法;

二: PriorityQueue实例

  PriorityQueue中的元素在逻辑上构成了一棵完全二叉树,但是在实际存储时转换为了数组保存在内存中,而我们的PriorityQueue继承了接口Queue,表名这是一个队列,只是它不像普通队列(例如:LinkedList)在遍历输出的时候简单的按顺序从头到尾输出,PriorityQueue总是先输出根节点的值,然后调整树使之继续成为一棵完全二叉树 样每次输出的根节点总是整棵树优先级最高的,要么数值最小要么数值最大。下面我们看如何构造一个PriorityQueue实例。

//默认用于存储节点信息的数组的大小
private static final int DEFAULT_INITIAL_CAPACITY = 11;
//用于存储节点信息的数组
transient Object[] queue;
//数组中实际存放元素的个数
private int size = 0;
//Comparator比较器
private final Comparator<? super E> comparator;
//用于记录修改次数的变量
transient int modCount = 0;

主要有四个构造函数

public PriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY, null);
}
public PriorityQueue(int initialCapacity) {
this(initialCapacity, null);
}
public PriorityQueue(Comparator<? super E> comparator) {
this(DEFAULT_INITIAL_CAPACITY, comparator);
} public PriorityQueue(int initialCapacity,Comparator<? super E> comparator) {
if (initialCapacity < 1)
throw new IllegalArgumentException();
this.queue = new Object[initialCapacity];
this.comparator = comparator;
}

 三  PriorityQueue 不是线程安全的。

 四  add()  和  offer()区别

   看源码, add(e) 内部offer(e)

五  poll() 和 peek() 区别?

  poll()  取得队首元素,并且删除。

  peek() 取得队首元素,但不删除;

java 基础知识学习 priorityQueue的更多相关文章

  1. Java基础知识学习(九)

    GUI开发 先前用Java编写GUI程序,是使用抽象窗口工具包AWT(Abstract Window Toolkit).现在多用Swing.Swing可以看作是AWT的改良版,而不是代替AWT,是对A ...

  2. java基础知识学习笔记

    本文知识点以js为参照.对比分析得出笔记.JavaScript之所以叫JavaScript是打算借助java推广自己.虽然都是开发语言,但JavaScript一开始主要运行在 客户端,而java主要运 ...

  3. Java基础知识学习(三)

    面向对象部分 首先要了解面向对象的思想,与C#一致,都是面向对象的语言 访问修饰符 public 共有的,对所有类可见. protected 受保护的,对同一包内的类和所有子类可见. private ...

  4. Java基础知识学习(一)

    部门接了新项目,后台使用Java框架play framework,前端是html,前后台通过rest交互,能够支持多端的互联网架构. 因为之前没有Java基础,前端使用的也很少,决定深入学习一下Jav ...

  5. Java基础知识学习(二)

    Java语法基础 数据类型.类型转换.运算符.逻辑运算符.参考C#,基本一致 输入输出 输出 System.out.print("abc"); System.out.printf( ...

  6. java基础知识学习 内存相关

    Java 内存分配策略 静态存储区(方法区):主要存放静态数据.全局 static 数据和常量.这块内存在程序编译时就已经分配好,并且在程序整个运行期间都存在. 栈区 :当方法被执行时,方法体内的局部 ...

  7. Java基础知识学习(八)

    IO操作 5个重要的类分别是:InputStream.OutStream.Reader.Writer和File类 面向字符的输入输出流 输入流都是Reader的子类, CharArrayReader ...

  8. Java基础知识学习(七)

    线程(续) 线程同步 当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用.达到此目的的过程叫做同步(synchronization) 可以用两种方法同步化代码.两者 ...

  9. Java基础知识学习(六)

    多线程 先了解线程的概念 多线程需要注意的地方 优先级.线程同步.消息传递.数据共享.死锁等 Java线程类 Thread,实现接口 Runnable Thread常用方法 getName 获得线程名 ...

随机推荐

  1. C语言高速入门系列(四)

    C语言高速入门系列(四) C语言数组 ---------转载请注明出处:coder-pig 贴心小提示:假设图看不清晰可右键另存为,应该就非常清晰了; 注意上面的代码都要自己过一遍哦! 本节引言: 经 ...

  2. mnesia的脏读和事物读的测试

    在mnesia中,有脏读脏写等以及事物读写,它们的差异通过测试不难发现: 代码如下: -module(mnesia_read_test). -compile(export_all). -record( ...

  3. Go语言入门系列1:安装,How to Write Go Code

    https://golang.org/doc/code.html src contains Go source files, pkg contains package objects, and bin ...

  4. asm 与 cglib(整理的)

    参考博客地址 http://www.oseye.net/user/kevin/blog/304#top http://www.blogjava.net/vanadies10/archive/2011/ ...

  5. 常用sql集锦

    1.从数据库A中把表tableA导入到数据库B中 --如果主键是自增,则必须列出具体字段.-- select * into tableA from A..tableA 2.批量更改表中某列中的某个字符 ...

  6. iOS 设置字体样式

    1.iOS设置字体样式   label.font = [UIFont fontWithName:@"Arial-BoldItalicMT" size:24];   字体名如下: F ...

  7. COPY SAP 标准gui状态

    [转]如何COPY SAP标准gui状态 1.可以自己建立 2.找到合适的ALV程序,然后找到合适的 gui_statu,进行copy. 但是这个是系统有过自定义开发会方便很多,如果没有,那要找标准程 ...

  8. Java for LeetCode 086

    Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...

  9. Gemini.Workflow 双子工作流入门教程五:业务表单开发

    简介: Gemini.Workflow 双子工作流,是一套功能强大,使用简单的工作流,简称双子流,目前配套集成在Aries框架中. 下面介绍本篇教程:业务表单开发. 业务表单开发 业务表单的开发,和在 ...

  10. 有关svg的一些理解

    SVG 是使用XML来描述二维图形和绘图程序的语言. SVG指可伸缩的矢量图形(Scalable Vector Graphics) SVG使用XML格式定义图形 SVG图形在放大或改变尺寸的情况下,图 ...