PriorityQueue详解

来源:互联网 发布:linux系统无法启动 编辑:程序博客网 时间:2024/06/04 21:02


PriorityQueue优先队列本质上就是一个最小堆,它的每个父节点都比两个子节点要小,但是整个数组又不是完全顺序的。不是线程安全的。优先级队列不允许 null 元素,此队列按照在构造时所指定的顺序对元素排序,既可以根据元素的自然顺序来指定排序(参阅 Comparable),也可以根据 Comparator 来指定,这取决于使用哪种构造方法。




此队列的头是按指定排序方式的最小元素。

private transient Object[] queue;    private static final int DEFAULT_INITIAL_CAPACITY = 11;//它默认的长度为11

add(E e)和offer(E e)的语义相同,都是向优先队列中插入元素,只是Queue接口规定二者对插入失败时的处理不同,前者在插入失败时抛出异常,后则则会返回false;

element()和peek()的语义完全相同,都是获取但不删除队首元素,也就是队列中权值最小的那个元素,二者唯一的区别是当方法失败时前者抛出异常,后者返回null。

remove()和poll()方法的语义也完全相同,都是获取并删除队首元素,区别是当方法失败时前者抛出异常,后者返回null。由于删除操作会改变队列的结构,为维护小顶堆的性质,需要进行必要的调整。

方法iterator()中提供的迭代器可能只是对整个数组的依次遍历。也就只能保证数组的第一个元素是最小的
扩展:

 堆里面的数组长度不是固定不变的,如果不断往里面添加新元素的时候,也会面临数组空间不够的情形,所以也需要对数组长度进行扩展。这个扩展方法的源头就是由插入元素引起的。和ArrayList的内部实现代码基本相同,都是先找到合适的数组长度,然后将元素从旧的数组拷贝到新的数组。

扩展代码

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 static int hugeCapacity(int minCapacity) {          if (minCapacity < 0) // overflow              throw new OutOfMemoryError();          return (minCapacity > MAX_ARRAY_SIZE) ?              Integer.MAX_VALUE :              MAX_ARRAY_SIZE;      } 

元素添加:

 每次添加新的元素进来实际上是在数组的最后位置增加。在增加这个元素的时候就有了判断数组长度和调整的一系列动作。等这些动作调整完之后就要进行siftUp方法调整。这样做是为了保证堆原来的性质。

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;      }  

转载参考:

http://shmilyaw-hotmail-com.iteye.com/blog/1827136

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