Java集合随笔之一--PriorityQueue

8月20日,终于判了,但有失公正,社会可以不公平但不能不公正--写在正文前的废话。

 

PriorityQueue这个东西叫啥,随便反正我不会翻译她,我只想把我N年前看过的目前还记得的东西拿出来凉凉,以免发霉了,再则也可以给自己的生活添点佐料。

一、PriorityQueue的数据结构

PriorityQueue类定义里明确指出“based on a priority heap”,堆结构,再简单一点说就是一棵完全二叉树。啥是完全二叉树,还好大学时期学的那点东西还没就饭吃,即除了树的叶子所在的层外,其余层节点都被填满。她的可以使用数组来实现。这里的PriorityQueue只不过是在构造队列时就已经实现的一个堆排序而已。

二、核心操作offer

offer中的核心方法是siftUp,而siftUp的核心方法是siftUpUsingComparator和siftUpComparable,这里我们以siftUpComparable方法为例:

 

private void siftUpComparable(int k, E x) {
        Comparable<? super E> key = (Comparable<? super E>) x;
        while (k > 0) {
            int parent = (k - 1) >>> 1;(1)
            Object e = queue[parent];
            if (key.compareTo((E) e) >= 0)
                break;
            queue[k] = e;
            k = parent;
        }
        queue[k] = key;
    }

标号(1)处,这里是堆的一个基本操作:给出节点存储的位置找到其父节点所在的位置。这里用了堆的一个特性,父节点所在的位置=子节点所在位置除以2并向下取整。这个方法的核心就是解决有序堆中新增元素的问题。有序堆中新增元素的核心就是考虑新增元素和其父节点的大小关系问题。

三、核心操作poll

poll中的核心方法是siftDown,而siftDown的核心方法是siftDownUsingComparator和siftDownComparable,我们以siftDownComparable方法为例:

 

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;(1)
            Object c = queue[child];
            int right = child + 1;(2)
            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;
    }

 这个方法核心解决一个问题,堆的根节点被删除后,如何从堆中选出新的根节点。

(1)处是获取要删除节点的左孩子

(2)处是获取要删除节点的右孩子,后续只要按照堆删除操作要求的考虑将移动节点的子节点同其兄弟节点之间的关系即可

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值