Java笔记(十)堆与优先级队列
优先级队列
一、PriorityQueue
PriorityQueue是优先级队列,它实现了Queue接口,它的队列长度
没有限制,与一般队列的区别是,它有优先级概念,每个元素都有优先
级,队头的元素永远都是优先级最高的。PriorityQueue内部是用堆实现的。
一、基本用法
主要构造方法:
- public PriorityQueue()
- public PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
- public PriorityQueue(Collection<? extends E> c) //动态数组大小等于容器中元素的个数
PriorityQueue使用动态数组initialCapacity表示初始数组的大小。举例:
- PriorityQueue<Integer> ints = new PriorityQueue<>();
- ints.offer(10);
- ints.add(28);
- ints.addAll(Arrays.asList(22, 33, 55, 66));
- while (ints.peek() != null) {
- System.out.println(ints.poll() + " ");
- }
二、实现原理
内部成员:
- private transient Object[] queue;
- private int size = 0;
- private final Comparator<? super E> comparator;
- private transient int modCount = 0;
构造方法:
- public PriorityQueue() {
- this(DEFAULT_INITIAL_CAPACITY, null);
- }
- public PriorityQueue(int initialCapacity) {
- this(initialCapacity, null);
- }
- public PriorityQueue(int initialCapacity,
- Comparator<? super E> comparator) {
- if(initialCapacity < 1)
- throw new IllegalArgumentException();
- this.queue = new Object[initialCapacity];
- this.comparator = comparator;
- }
添加元素的代码
- public boolean offer(E e) {
- if(e == null)
- throw new NullPointerException();
- modCount++;
- int i = size;
- if(i >= queue.length) //先确保数组长度是否足够,如果不够,用grow方法扩展
- grow(i + 1);
- size = i + 1;
- if(i == 0) //如果是第一次添加
- queue[0] = e;
- else //否则将其放入最后一个位置,并向上调整
- siftUp(i, e);return true;
- }
- 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 code
- if(newCapacity - MAX_ARRAY_SIZE > 0)
- newCapacity = hugeCapacity(minCapacity);
- queue = Arrays.copyOf(queue, newCapacity);
- }
- private void siftUp(int k, E x) {
- if(comparator != null)
- siftUpUsingComparator(k, x);
- else
- siftUpComparable(k, x);
- }
- private void siftUpUsingComparator(int k, E x) {
- while(k > 0) {
- int parent = (k - 1) >>> 1;
- Object e = queue[parent];
- if(comparator.compare(x, (E) e) >= 0)
- break;
- queue[k] = e;
- k = parent;
- }
- queue[k] = x;
- }
查看元素头部元素:
- public E peek() {
- if(size == 0)
- return null;
- return (E) queue[0];
- }
删除头部元素:略
三、总结
1)实现了优先级队列,最先出队的总是优先级最高的,即排序中的第一个。
2)优先级可以有相同的,内部元素不是完全有序的,如果遍历输出,除了第一个其他没有特定顺序。、
3)查看头部元素,入队出队的效率都很高
4)根据值查找和删除元素的效率很低。
Java笔记(十)堆与优先级队列的更多相关文章
- 自己动手实现java数据结构(八) 优先级队列
1.优先级队列介绍 1.1 优先级队列 有时在调度任务时,我们会想要先处理优先级更高的任务.例如,对于同一个柜台,在决定队列中下一个服务的用户时,总是倾向于优先服务VIP用户,而让普通用户等待,即使普 ...
- 笔试算法题(57):基于堆的优先级队列实现和性能分析(Priority Queue based on Heap)
议题:基于堆的优先级队列(最大堆实现) 分析: 堆有序(Heap-Ordered):每个节点的键值大于等于该节点的所有孩子节点中的键值(如果有的话),而堆数据结构的所有节点都按照完全有序二叉树 排.当 ...
- Java集合总结(三):堆与优先级队列
堆 满二叉树:满二叉树是指,除了最后一层外,每个节点都有两个孩子,而最后一层都是叶子节点,都没有孩子. 完全二叉树:完全二叉树不要求最后一层是满的,但如果不满,则要求所有节点必须集中在最左边,从左到右 ...
- 【数据结构与算法Python版学习笔记】树——利用二叉堆实现优先级队列
概念 队列有一个重要的变体,叫作优先级队列. 和队列一样,优先级队列从头部移除元素,不过元素的逻辑顺序是由优先级决定的. 优先级最高的元素在最前,优先级最低的元素在最后. 实现优先级队列的经典方法是使 ...
- java数据结构与算法值优先级队列
一.优先级队列 什么是优先级队列:优先级队列是一种比栈和队列更加常用的一种数据结构.在优先级队列中,数据项按照关键字的值有序.数据项插入到队列中时,会按照顺序插入到合适的位置,用来保证队列的顺序. 生 ...
- Java笔记(十二)……类中各部分加载顺序及存放位置问题
什么时候会加载类 使用到类中的内容时加载,三种情况: 创建对象:new StaticDemo(); 使用类中的静态成员:StaticCode.num = 9; StaticCode.getNum() ...
- SpringBoot笔记十四:消息队列
目录 什么是消息队列 消息队列的作用 异步通信 应用解耦 流量削峰 RabbitMQ RabbitMQ流程简介 RabbitMQ的三种模式 安装RabbitMQ RabbitMQ交换器路由和队列的创建 ...
- Java笔记(十九)……多线程
概述 进程: 是一个正在执行中的程序 每一个进程执行都有一个执行顺序,该执行顺序是一个执行路径,或者叫一个控制单元 线程: 就是进程中的一个独立的控制单元,线程在控制着进程的执行 一个进程中至少有一个 ...
- Java笔记(十八)……包
概述 对类文件进行分类管理. 给类提供多层命名空间. 写在程序文件的第一行. 类名的全称的是 包名.类名. 包也是一种封装形式. 访问权限 引用<The Complete Reference&g ...
随机推荐
- hdu1565 用搜索代替枚举找可能状态或者轮廓线解(较优),参考poj2411
这题用直接枚举是超时的,必须要用搜索来搜索出所有可能的状态,然后再进行枚举 这是较慢的做法 /* 方格取数,相邻格子的数不可取,问最多取到的和是什么 有点类似炮兵布阵,先打出所有可能的状态,然后dp[ ...
- Java将文件中的内容转换为sql语句(和并发定时读取文件)
数据文件内容data.txt {USER_TYPE=1,CREATE_USER=ZHANG,UPDATE_USER=li,OPER_NUM=D001,SRC=2,UPDATE_TIME=2018-11 ...
- SSM 三大框架---事务处理
SSM 三大框架---事务处理 原创 2016年05月12日 20:57:03 标签: spring / J2EE / java / 框架 / 事务 7010 在学习三大框架的时候,老师说事务处理是最 ...
- python之多线程 queue 实践 筛选有效url
0.目录 1.背景 某号码卡申请页面通过省份+城市切换归属地,每次返回10个号码. 通过 Fiddler 抓包确认 url 关键参数规律: provinceCode 两位数字 cityCode 三位数 ...
- 【译】理解JavaScript中的柯里化
译文开始 函数式编程是一种编程风格,这种编程风格就是试图将传递函数作为参数(即将作为回调函数)和返回一个函数,但没有函数副作用(函数副作用即会改变程序的状态). 有很多语言采用这种编程风格,其中包括J ...
- Jhipster Registry(Eureka Server) Docker双向联通与高可用部署
使用Compose来编排这个Eureka Server集群: peer1配置: server: port: 8761 eureka: instance: hostname: eureka-peer-1 ...
- MySql中Week()函数的用法
WEEK(date[,mode]):该函数返回日期的星期数 模式 星期的第一天 范围 星期 1 是第一天 0 Sunday 0-53 一年中多一个星期天 1 Monday 0-53 一年多3天 2 S ...
- python3改版后的特征
1.原始数据类型和运算符 # 整数 3 # => 3 # 算术没有什么出乎意料的 1 + 1 # => 2 8 - 1 # => 7 10 * 2 # => 20 # 但是除法 ...
- python对象、引用
1.python对象 python中 所有的python对象都有3个特征: 身份,类型和值 身份: 每个对象有一个唯一的身份标识自己,这个值可以被认为是该对象内存地址.id()查看. 类型 type( ...
- Codeforces Round #487 (Div. 2) 跌分有感
又掉分了 这次的笑话多了. 首先,由于CF昨天的比赛太早了,忘记了有个ER,比赛开始半个小时才发现. 于是只能今天了. 嗯哈. 今天这场也算挺早的. 嗯嗯,首先打开A题. 草草看了一遍题意,以为不是自 ...