PriorityQueue详解


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值