前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PriorityBlockingQueue优先队列的二叉堆实现

PriorityBlockingQueue优先队列的二叉堆实现

作者头像
sanmutongzi
发布2020-03-05 10:47:33
4740
发布2020-03-05 10:47:33
举报
文章被收录于专栏:stream processstream process

转载请注明原创地址http://www.cnblogs.com/dongxiao-yang/p/6293807.html

java.util.concurrent.PriorityBlockingQueue内部用二叉堆实现了一个优先队列,所有插入的元素必须实现java.lang.Comparable接口。由于完全二叉树可以用数组来表示,所以队列内部元素存放在可变长度数组queue里。

private transient Object[] queue; //用于存放元素的数组

一 插入元素入队

代码语言:javascript
复制
    public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        final ReentrantLock lock = this.lock;
        lock.lock();
        int n, cap;
        Object[] array;
        while ((n = size) >= (cap = (array = queue).length))
            tryGrow(array, cap);
        try {
            Comparator<? super E> cmp = comparator;
            if (cmp == null)
                siftUpComparable(n, e, array);
            else
                siftUpUsingComparator(n, e, array, cmp);
            size = n + 1;
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
        return true;
    } 


代码语言:javascript
复制
//新元素堆内上浮实现

一 弹出元素出队

代码语言:javascript
复制
    public E poll() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return dequeue();
        } finally {
            lock.unlock();
        }
    }

    private E dequeue() {
        int n = size - 1;
        if (n < 0)
            return null;
        else {
            Object[] array = queue;
            E result = (E) array[0];
            E x = (E) array[n];
            array[n] = null;
            Comparator<? super E> cmp = comparator;
            if (cmp == null)
                siftDownComparable(0, x, array, n);//堆顶的最小值被弹出了,堆顶变成了空节点,空节点开始下浮到合适位置后用数组最后子节点填充。
            else
                siftDownUsingComparator(0, x, array, n, cmp);
            size = n;
            return result;
        }
    }
代码语言:javascript
复制
//空元素堆内下沉实现
    private static <T> void siftDownComparable(int k, T x, Object[] array, int n) {
        if (n > 0) {
            Comparable<? super T> key = (Comparable<? super T>) x;
            int half = n >>> 1; // loop while a non-leaf  half最后一个有子节点的父节点下标
            while (k < half) { 
                int child = (k << 1) + 1; // assume left child is least
                Object c = array[child];
                int right = child + 1;
                if (right < n
                        && ((Comparable<? super T>) c)
                                .compareTo((T) array[right]) > 0)
                    c = array[child = right];  //比较出左右子节点更小的那个子节点
                if (key.compareTo((T) c) <= 0) //如果左右子节点的最小值大于数组末尾的值,那么数组末尾的值直接放到父节点,空节点下沉结束
                    break;
                array[k] = c; // 如果子节点最小值小于数据末尾的值,子节点上浮到父空节点
                k = child; //空节点下滑到最小子节点的位置
            }
            array[k] = key; // 最后空节点填充数组最后的值
        }
    }

参考资料:数据结构之优先队列--二叉堆(Java实现)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-01-17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档