欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PriorityQueue详解

程序员文章站 2024-02-15 09:57:34
...


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


PriorityQueue详解


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

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