堆的特点
PriorityQueue的实现
堆的操作
关于堆的操作,主要就是两个。siftUp和siftDown,一个是向上调整堆,一个是向下调整堆。调整的时候java有一个使用comparator的调整,一个没有comparator的调整,调整方法基本相似,区别只是比较的时候是否使用comparator,下面主要说不是用comparator的。调整的目的是满足堆的特点。
调整的代码比较简单,加的注释已经可以疏通逻辑了。
private void siftUpComparable(int k, E x) {
//k就是元素的位置,x就是数组中k位置上的元素
Comparable<? super E> key = (Comparable<? super E>) x;
//由于是向上调整,堆顶是没有上的,所以条件就是k>0
while (k > 0) {
//在数组中,下标(k-1)/2就是父节点的位置
int parent = (k - 1) >>> 1;
Object e = queue[parent];
//java的实现是小顶堆,所以这里判断是父元素小于比较元素就表示堆调整完成
if (key.compareTo((E) e) >= 0)
break;
//交换
queue[k] = e;
//原来的树已经满足,被交换的节点,都满足比父节点小,比子节点大,
//由于元素交换了,说明现在的元素比较小
//得继续调整,如果还能被调整,调整换下来的元素还是比较大的
k = parent;
}
queue[k] = key;
}
private void siftDownComparable(int k, E x) {
Comparable<? super E> key = (Comparable<? super E>)x;
int half = size >>> 1;
//由于是向下调整,所以最后一个有子节点的节点是(len-1)/2,没有子节点的就不用调整
while (k < half) {
int child = (k << 1) + 1;
Object c = queue[child];
int right = child + 1;
//找出两个子节点中最小的比较,因为是小顶堆
if (right < size &&((Comparable<? super E>) c).compareTo((E) queue[righ