Java data structure -- PriorityQueue 未完待续

 Priority queue

Priority queue represented as a balanced binary heap: the two children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The priority queue is ordered by comparator, or by the elements' natural ordering, if comparator is null: For each node n in the heap and each descendant d of n, n <= d. The element with the lowest value is in queue[0], assuming the queue is nonempty.

 

public class PriorityQueue<E> extends AbstractQueue<E>
    implements java.io.Serializable {

    private static final long serialVersionUID = -7720805057305804111L;

    private static final int DEFAULT_INITIAL_CAPACITY = 11;

    /**
     * Priority queue represented as a balanced binary heap: the two
     * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
     * priority queue is ordered by comparator, or by the elements'
     * natural ordering, if comparator is null: For each node n in the
     * heap and each descendant d of n, n <= d.  The element with the
     * lowest value is in queue[0], assuming the queue is nonempty.
     */
    transient Object[] queue; // non-private to simplify nested class access

    /**
     * The number of elements in the priority queue.
     */
    private int size = 0;

    /**
     * The comparator, or null if priority queue uses elements'
     * natural ordering.
     */
    private final Comparator<? super E> comparator;

    /**
     * The number of times this priority queue has been
     * <i>structurally modified</i>.  See AbstractList for gory details.
     */
    transient int modCount = 0; // non-private to simplify nested class access
...
}

 

siftUp

  /**
     * Inserts item x at position k, maintaining heap invariant by promoting x up
     * the tree until it is greater than or equal to its parent, or is the root.
     *
     * To simplify and speed up coercions and comparisons. the Comparable and
     * Comparator versions are separated into different methods that are otherwise
     * identical. (Similarly for siftDown.)
     *
     * @param k the position to fill
     * @param x the item to insert
     */
    private void siftUp(int k, E x) {
        if (comparator != null)
            siftUpUsingComparator(k, x);
        else
            siftUpComparable(k, x);
    }

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

    @SuppressWarnings("unchecked")
    private void siftUpUsingComparator(int k, E x) {
        while (k > 0) {
            int parent = (k - 1) >>> 1; // (k-1)除以2获取父节点的index
            Object e = queue[parent];
            if (comparator.compare(x, (E) e) >= 0) // 直到x大于父节点
                break;
            queue[k] = e; // 把父节点的值放入k
            k = parent; // k上移指向父节点
        }
        queue[k] = x; // 最终合适到位置放入x
    }

 

siftDown

 1 /**
 2      * Inserts item x at position k, maintaining heap invariant by
 3      * demoting x down the tree repeatedly until it is less than or
 4      * equal to its children or is a leaf.
 5      *
 6      * @param k the position to fill
 7      * @param x the item to insert
 8      */
 9     private void siftDown(int k, E x) {
10         if (comparator != null)
11             siftDownUsingComparator(k, x);
12         else
13             siftDownComparable(k, x);
14     }
15 
16     @SuppressWarnings("unchecked")
17     private void siftDownComparable(int k, E x) {
18         Comparable<? super E> key = (Comparable<? super E>)x;
19         int half = size >>> 1;        // loop while a non-leaf
20         while (k < half) {
21             int child = (k << 1) + 1; // assume left child is least
22             Object c = queue[child];
23             int right = child + 1;
24             if (right < size &&
25                 ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
26                 c = queue[child = right];
27             if (key.compareTo((E) c) <= 0)
28                 break;
29             queue[k] = c;
30             k = child;
31         }
32         queue[k] = key;
33     }
34 
35     private void siftDownUsingComparator(int k, E x) {
36         int half = size >>> 1;  // 无符号右移 -> 除以2取中间值
37         while (k < half) {  //
38             int child = (k << 1) + 1;  //左移, 乘以2
39             Object c = queue[child];  // c的值是k的某个child的值(左右child中较大的那个)
40             int right = child + 1;  //比较两个child哪个大
41             if (right < size &&
42                 comparator.compare((E) c, (E) queue[right]) > 0)
43                 c = queue[child = right];
44             if (comparator.compare(x, (E) c) <= 0)  //直到x小于某个child
45                 break;
46             queue[k] = c;  //如果x大于两个child中较大的那个,则把较大的child放到本k的位置
47             k = child;  //把k指向较大的child
48         }
49         queue[k] = x;  // 把x放到合适的k的child的节点上,保证此节点的所有父节点都比此节点的值小
50     }

 

removeAt

/**
     * Removes the ith element from queue.
     *
     * Normally this method leaves the elements at up to i-1,
     * inclusive, untouched.  Under these circumstances, it returns
     * null.  Occasionally, in order to maintain the heap invariant,
     * it must swap a later element of the list with one earlier than
     * i.  Under these circumstances, this method returns the element
     * that was previously at the end of the list and is now at some
     * position before i. This fact is used by iterator.remove so as to
     * avoid missing traversing elements.
     */
    @SuppressWarnings("unchecked")
    private E removeAt(int i) {
        // assert i >= 0 && i < size;
        modCount++;
        int s = --size;
        if (s == i) // i是最后一个,直接删除
            queue[i] = null;  // 直接删除
        else {
            E moved = (E) queue[s];  // 把最后一个元素保存到临时变量moved
            queue[s] = null;  // 删除最后一个元素
            siftDown(i, moved);  // 把原最后的元素放入位置i, 并调用siftDown重新调整堆
            if (queue[i] == moved) { // 如果siftDown之后,queue[i] == moved, 表明 moved  小于所有child(表明moved原来也是叶节点?)
                siftUp(i, moved);  // 这时候要尝试做siftUp
                if (queue[i] != moved)  //如果siftUp使堆有变化,则返回moved
                    return moved;
            }
        }
        return null;  // 如果到i-1为止堆元素没有变化,返回null
    }

 

offer

/**
     * Inserts the specified element into this priority queue.
     *
     * @return {@code true} (as specified by {@link Queue#offer})
     * @throws ClassCastException if the specified element cannot be
     *         compared with elements currently in this priority queue
     *         according to the priority queue's ordering
     * @throws NullPointerException if the specified element is null
     */
    public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;  // i等于当前size,即当前最后位置
        if (i >= queue.length)
            grow(i + 1);  //保证queue容量
        size = i + 1;  // 递增size
        if (i == 0)
            queue[0] = e;  //如果是第一个,直接放在heap根
        else
            siftUp(i, e);  //如果不是第一个,放在i之后要siftUp来恢复堆
        return true;
    }

 

heapify

/**
     * Establishes the heap invariant (described above) in the entire tree,
     * assuming nothing about the order of the elements prior to the call.
     */
    @SuppressWarnings("unchecked")
    private void heapify() {
        for (int i = (size >>> 1) - 1; i >= 0; i--)
            siftDown(i, (E) queue[i]);
    }

 

转载于:https://www.cnblogs.com/andychhr/p/9921159.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值