PriorityQueue 源码分析
public boolean hasNext() {
return cursor < size ||
(forgetMeNot != null && !forgetMeNot.isEmpty());
} //内部的迭代器,就是数组的迭代,迭代指针cursor,
public E next() {
if (expectedModCount != modCount)
throw new ConcurrentModificationException();
if (cursor < size)
return (E) queue[lastRet = cursor++];
if (forgetMeNot != null) {
lastRet = -1;
lastRetElt = forgetMeNot.poll();
if (lastRetElt != null)
return lastRetElt;
}
throw new NoSuchElementException();
}
扩容:
private void grow(int minCapacity) {
int oldCapacity = queue.length;
// 小于64扩大为原来2倍,大于等于64扩大为原来1.5倍,
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);//丢弃原来的数组,指向新的数组,
}
public class zusheQueue {
private static PriorityQueue<Integer> queue = new PriorityQueue<Integer>(3); public static void main(String[] args) {
queue.offer(80);
queue.offer(60);
queue.offer(70);
queue.offer(40);
queue.offer(20);
queue.offer(10);
queue.offer(90);
queue.offer(22);
queue.offer(15);
queue.offer(4);
queue.offer(1);
System.out.println(queue);//[1, 4, 20, 22, 10, 70, 90, 80, 40, 60, 15] 数组实现最小堆
System.out.println("出来 "+queue.poll());
System.out.println("出来 "+queue.poll());
System.out.println("出来 "+queue.poll());
System.out.println("出来 "+queue.poll());
/*出来 1
出来 4
出来 10
出来 15 出来最小的*/
System.out.println(queue); Iterator i = queue.iterator();
while(i.hasNext()) {
System.out.print(i.next() + " ");//1 4 20 22 10 70 90 80 40 60 15
} List<Integer> l = Arrays.asList(7,85,4,9,5,85,74,5,8);
PriorityQueue<Integer> p = new PriorityQueue<>(l);
System.out.println(p);
} }
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;
}
private void siftDownComparable(int k, E x) { // k = 0
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1; // 非叶子节点
while (k < half) {
int child = (k << 1) + 1; // child = 左孩子
Object c = queue[child]; // c = 左孩子
int right = child + 1;//right = 右孩子
if (right < size &&
((Comparable<? super E>) c).compareTo((E) queue[right]) > 0) //有右孩子,并且左孩子大于右孩子
c = queue[child = right];// c = 右孩子,child = 右孩子
if (key.compareTo((E) c) <= 0) //key小于右孩子,就是小于所有孩子
break; //结束循环
queue[k] = c; // 否则key大于右孩子,k位置是右孩子,就是较小的孩子
k = child; //指针k值为right右孩子的位置, 比较都是根据指针位置比较,放的时候才放对象。
}
queue[k] = key;
}
构造函数:
public PriorityQueue(Collection<? extends E> c) {
if (c instanceof SortedSet<?>) {
SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
this.comparator = (Comparator<? super E>) ss.comparator();
initElementsFromCollection(ss);
}
else if (c instanceof PriorityQueue<?>) {
PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
this.comparator = (Comparator<? super E>) pq.comparator();
initFromPriorityQueue(pq);
}
else {
this.comparator = null;
initFromCollection(c);
}
}
private void initFromCollection(Collection<? extends E> c) {
initElementsFromCollection(c);
heapify();
}
private void initElementsFromCollection(Collection<? extends E> c) {
Object[] a = c.toArray();
// If c.toArray incorrectly doesn't return Object[], copy it.
if (a.getClass() != Object[].class)
a = Arrays.copyOf(a, a.length, Object[].class);
int len = a.length;
if (len == 1 || this.comparator != null)
for (int i = 0; i < len; i++)
if (a[i] == null)
throw new NullPointerException();
this.queue = a;
this.size = a.length;
}
private void heapify() {
for (int i = (size >>> 1) - 1; i >= 0; i--) //(size >>> 1) - 1就是找到第一个非叶子节点,然后从下到上从右到左,
siftDown(i, (E) queue[i]);
}
public E poll() {
if (size == 0)
return null;
int s = --size;
modCount++;
E result = (E) queue[0]; //取出第0个元素
E x = (E) queue[s]; //取出最后一个元素
queue[s] = null; // 最后一个元素置为空
if (s != 0)
siftDown(0, x); // 最后一个元素不要先不要放在第0个元素位置,比较之后确定位置了再放。放置的都是左右孩子,改变的是k的值,key不到最后不放。
return result; //返回第0个元素
}
private void siftDownComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1;
while (k < half) {
// sI, sV是左右子节点的较小位置和值,k,key是要比较的元素和准备放的位置(落之前要比较在放)
int sI = (k << 1) + 1; // 较小位置=左孩子索引
Object sV = queue[sI];//较小值=左孩子
int right = sI+ 1;
if (right < size &&
((Comparable<? super E>) sV ).compareTo((E) queue[right]) > 0) //有右孩子,并且左孩子大于右孩子,
sV = queue[sI= right]; // 较小位置=右孩子索引,较小值=右孩子,
if (key.compareTo((E) sV ) <= 0) //key比左右都小,放上去,
break;
queue[k] = sV ;//否则key比子节点要大,交换位置,并且自己准备放在sl的位置。放置的都是左右孩子,改变的是k的值,key不到最后不放。
k = sI; //自己放在sl的位置之前,也要跟子节点比较一下,在放。
}
queue[k] = key;//key放在k的位置
}
PriorityQueue 源码分析的更多相关文章
- 死磕 java集合之PriorityQueue源码分析
问题 (1)什么是优先级队列? (2)怎么实现一个优先级队列? (3)PriorityQueue是线程安全的吗? (4)PriorityQueue就有序的吗? 简介 优先级队列,是0个或多个元素的集合 ...
- PriorityQueue源码分析
PriorityQueue其实是一个优先队列,和先进先出(FIFO)的队列的区别在于,优先队列每次出队的元素都是优先级最高的元素.那么怎么确定哪一个元素的优先级最高呢,jdk中使用堆这么一 ...
- 死磕 java集合之DelayQueue源码分析
问题 (1)DelayQueue是阻塞队列吗? (2)DelayQueue的实现方式? (3)DelayQueue主要用于什么场景? 简介 DelayQueue是java并发包下的延时阻塞队列,常用于 ...
- 死磕 java集合之PriorityBlockingQueue源码分析
问题 (1)PriorityBlockingQueue的实现方式? (2)PriorityBlockingQueue是否需要扩容? (3)PriorityBlockingQueue是怎么控制并发安全的 ...
- java读源码 之 queue源码分析(PriorityQueue,附图)
今天要介绍的是基础容器类(为了与并发容器类区分开来而命名的名字)中的另一个成员--PriorityQueue,它的大名叫做优先级队列,想必即使没有用过也该有所耳闻吧,什么?没..没听过?emmm... ...
- 介绍开源的.net通信框架NetworkComms框架 源码分析
原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 售价249英镑 我曾经花了 ...
- Mahout源码分析:并行化FP-Growth算法
FP-Growth是一种常被用来进行关联分析,挖掘频繁项的算法.与Aprior算法相比,FP-Growth算法采用前缀树的形式来表征数据,减少了扫描事务数据库的次数,通过递归地生成条件FP-tree来 ...
- 细说并发5:Java 阻塞队列源码分析(下)
上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...
- HDFS源码分析EditLog之获取编辑日志输入流
在<HDFS源码分析之EditLogTailer>一文中,我们详细了解了编辑日志跟踪器EditLogTailer的实现,介绍了其内部编辑日志追踪线程EditLogTailerThread的 ...
随机推荐
- python 中 __init__方法
注意1,__init__并不相当于C#中的构造函数,执行它的时候,实例已构造出来了. class A(object): def __init__(self,name): self.name=name ...
- Code::Blocks设置支持C++ 11
进入codeblocks,点击Settings --> Compiler..,进入如下页面 勾选“Have g++ follow the C++11 ISO language standard ...
- sublime 安装ctags跳转以及跳转快捷键
在source insight中有一个很好用的功能,就是函数的跟踪跳转,在阅读别人的代码的时候轻松的浏览原函数.我们知道,在使用vim的时候有个插件叫ctags,同理,在sublime text中也能 ...
- AWS事故总结,几招教你规避风险
版权声明:本文由王煜奕原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/90687001488360802 来源:腾云阁 ht ...
- 网络流24T
说出来你们可能不信,我咕了三个多星期了,今晚忽然不想再写题了,(写自闭了,把这边整理一下 1. 洛谷P2756 飞行员配对问题 二分图匹配: #include <bits/stdc++.h> ...
- Linux 的基本操作(文件与目录管理)
文件与目录管理 在linux中什么是一个文件的路径呢,说白了就是这个文件存在的地方,例如在上一章提到的/root/.ssh/authorized_keys 这就是一个文件的路径.如果你告诉系统这个文件 ...
- Laravel使用Form(转载)
laravel到了5.1.*以上版本,便没有了illuminate/html类库的支持, 我试着把illuminate/html类库加入了laravel5.2,依然没有用, 但是laravelcoll ...
- Palindromic Matrix
Palindromic Matrix time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- (转)JVM中的OopMap(zz)
原文地址: http://www.cnblogs.com/strinkbug/p/6376525.html 在读周智明的深入理解JVM虚拟机时,关于枚举根节点/安全点这部分感觉书上写的不是太明白,找了 ...
- db2look 工具
db2look -d sample -m > db2look_stat.out