java源码分析-优先队列
来源:互联网 发布:python import路径 编辑:程序博客网 时间:2024/06/14 17:25
愿她好!
优先队列PriorityQueue
1.类结构
2.优先队列分析
主要是怎么确定优先级
首先我们来看下add(E)方法
public boolean add(E e) { return offer(e); }
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; else siftUp(i, e); return true; }
private void siftUp(int k, E x) { if (comparator != null) siftUpUsingComparator(k, x); else siftUpComparable(k, x); }
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 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; }
从上述代码可以看出:第一,add方法实际上是调用offer方法;第二,加入的元素不能为空,都在抛出空指向异常,这类问题在有序的集合中都会存在;第三,若队列满了,则采用grow方法扩容;第四,通过siftUp来重整队列,如果没有从外部传入比较器,采用siftUpUsingComparator方法来重整;否则,利用传入的比较器以及siftUpComparable来重整队列。
怎么比较优先级的?以自带的比较器为例子
关键代码在于parent的确定:int parent=(k-1)>>>1; 不断地找到中值,并利用比较器比较,直到比较器判断为true
java中有三种移位运算符
<< : 左移运算符,num << 1,相当于num乘以2
>> : 右移运算符,num >> 1,相当于num除以2
>>> : 无符号右移,忽略符号位,空位都以0补齐
无符号右移的规则只记住一点:忽略了符号位扩展,0补最高位 无符号右移运算符>>> 只是对32位和64位的值有意义
扩容
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); }
分为两种情况:如果原有容量小于64,扩容方式为加倍再加2;否则,每次增加原有容量的一半
最大容量
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
数组可能保留一些特殊字段
查找
public E peek() { if (size == 0) return null; return (E) queue[0]; }
private int indexOf(Object o) { if (o != null) { for (int i = 0; i < size; i++) if (o.equals(queue[i])) return i; } return -1; }
public E poll() { if (size == 0) return null; int s = --size; modCount++; E result = (E) queue[0]; E x = (E) queue[s]; queue[s] = null; if (s != 0) siftDown(0, x); return result; }
private void siftDown(int k, E x) { if (comparator != null) siftDownUsingComparator(k, x); else siftDownComparable(k, x); } private void siftDownComparable(int k, E x) { Comparable<? super E> key = (Comparable<? super E>)x; int half = size >>> 1; // loop while a non-leaf while (k < half) { int child = (k << 1) + 1; // assume left child is least Object c = queue[child]; int right = child + 1; if (right < size && ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0) c = queue[child = right]; if (key.compareTo((E) c) <= 0) break; queue[k] = c; k = child; } queue[k] = key; } private void siftDownUsingComparator(int k, E x) { int half = size >>> 1; while (k < half) { int child = (k << 1) + 1; Object c = queue[child]; int right = child + 1; if (right < size && comparator.compare((E) c, (E) queue[right]) > 0) c = queue[child = right]; if (comparator.compare(x, (E) c) <= 0) break; queue[k] = c; k = child; } queue[k] = x; }
0 0
- java源码分析-优先队列
- 数据结构和算法分析java--优先队列(堆实现)
- JAVA队列之优先队列
- JAVA队列之优先队列
- java优先队列
- java PriorityQueue优先队列
- java优先队列 PriorityQueue
- [java]优先队列
- 【Java】优先队列PriorityQueue
- Java优先队列
- JAVA优先队列
- 优先队列 java PriorityQueue
- Java数据结构----优先队列
- (java)优先队列
- Java 优先队列
- Java中的优先队列
- java优先队列
- 优先队列java-PriorityQueue
- 06_UIScrollView
- 虚拟机Ubuntu下Hadoop2.6.1的安装和配置(伪分布式)
- 11-19 Linux
- 容量规划和Region配置
- C# 设计模式----抽象工厂模式
- java源码分析-优先队列
- Feng是LSCUBE维护的开源流媒体服务器,兼容IETF标准,实现了RTSP、RTP/RTCP
- android——Fragment实现懒加载
- hdu 2199 Can you solve this equation?
- windows下apache+php+mysql 环境配置方法
- OC之继承、初始化、便利构造器
- object references an unsaved transient instance
- HTTP403(禁止访问)---WampServer 127.0.0.1 禁止访问
- webview 调用js 4.2之前与之后的区别