PriorityQueue-数组(二叉堆)

来源:互联网 发布:mysql 格式化时间戳 编辑:程序博客网 时间:2024/06/05 08:50

field

    //默认初始化大小    private static final int DEFAULT_INITIAL_CAPACITY = 11;    //队列内置为数组,实际为数据结构中的二叉堆    transient Object[] queue; // non-private to simplify nested class access    //容量大小    private int size = 0;    //比较器    private final Comparator<? super E> comparator;    //操作数    transient int modCount = 0; // non-private to simplify nested class access

construct

    //构造方法,传入初始化容量与比较器。    public PriorityQueue(int initialCapacity,                         Comparator<? super E> comparator) {        // Note: This restriction of at least one is not actually needed,        // but continues for 1.5 compatibility        if (initialCapacity < 1)            throw new IllegalArgumentException();        this.queue = new Object[initialCapacity];        this.comparator = comparator;  //比较器    }

method

heapify

 private void heapify() {        //下滤操作,将每个父节点看成重新插入的元素下滤,达到二叉堆结构要求        for (int i = (size >>> 1) - 1; i >= 0; i--)            siftDown(i, (E) queue[i]);    }

siftDownUsingComparator(下滤)

 //下滤指定位置的节点    //k为数组数组索引,对应二叉堆为 k+1个节点位置    //左节点 (2k+1) 右节点 (2k + 2)    private void siftDownUsingComparator(int k, E x) {        int half = size >>> 1;        //如果是初始化一个非sorted结合则需要循环下滤        //下滤,只用从非叶子节点开始下滤即可,即size/2        while (k < half) {            int child = (k << 1) + 1;   //左节点            Object c = queue[child];            int right = child + 1;   //右节点            if (right < size &&                comparator.compare((E) c, (E) queue[right]) > 0)                //如果左节点大于右节点,取右节点                c = queue[child = right];            //将右节点与父节点数据比较,如果父节点大于子节点则下滤,否则不变            if (comparator.compare(x, (E) c) <= 0)                break;            //将x下滤,将c赋值到父节点位置            queue[k] = c;            k = child;        }        //最后的k位置,即为x的索引坐标        queue[k] = x;    }

offer

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;    }

siftUpUsingComparator

private void siftUpUsingComparator(int k, E x) {        while (k > 0) {            int parent = (k - 1) >>> 1;  //父节点            Object e = queue[parent];            //与父节点判断大小,需要满足父节点大于所有子节点            if (comparator.compare(x, (E) e) >= 0)                break;            queue[k] = e;            k = parent;        }        queue[k] = x;    }

removeAt

 private E removeAt(int i) {        // assert i >= 0 && i < size;        modCount++;        int s = --size;        if (s == i) // removed last element            queue[i] = null;        else {            E moved = (E) queue[s];            queue[s] = null;            //首先下滤,将尾部元素取出重新排位            siftDown(i, moved);            //如果尾部元素取代 i 位置元素,则需要上滤判断            //可能尾部元素比父元素要小            if (queue[i] == moved) {                siftUp(i, moved);                if (queue[i] != moved)                    return moved;            }        }        return null;    }
原创粉丝点击