优先级队列底层默认是一个小根堆
1、(建大堆)向下调整
//建大堆
public class HeapDemo {
public int[] elem;
public int usedSize;
public HeapDemo(){
this.elem = new int[10];
}
/*
* */
public void adjustDown(int parent,int len){
int child = 2*parent + 1;
while(child < len){//说明有左孩子
//child+1 < len 代表判断当前是否有右孩子
if(child+1 < len && this.elem[child] < this.elem[child+1]){
child++;
}//child小标一定是左右孩子的最大值下标
if(this.elem[child] > this.elem[parent]){
int tmp = this.elem[parent];
this.elem[parent] = this.elem[child];
this.elem[child] = tmp;
parent = child;
child = 2*parent + 1;
}else{
break;
}
}
}
public void creatBigHeap(int[] array){
for(int i= 0;i<this.elem.length;i++){
this.elem[i] = array[i];
this.usedSize++;
}
for(int i = (this.usedSize-1-1)/2;i >= 0;i--){
//从最后一个节点的父亲节点调整
adjustDown(i,this.usedSize);
}
}
向下调整时间复杂度:logn
建大根堆或者小根堆时间复杂度:O(n) * logn 约为O(n)
2、(入队)向上调整(加入一个数,使数组仍然保持大根堆)。
public void adjustUp(int child){
int parent = (child-1)/2;
while (parent >= 0){
if (this.elem[child] > this.elem[parent]) {
int tmp = this.elem[parent];
this.elem[parent] = this.elem[child];
this.elem[child] = tmp;
child = parent;
parent = (child-1)/2;
}else {
break;
}
}
}
public void push(int val){
if(isFull()){
this.elem =
Arrays.copyOf(this.elem,2*this.elem.length);
}
this.elem[this.usedSize] = val;
this.usedSize++;
adjustUp(this.usedSize-1);
}
public boolean isFull(){
return this.usedSize == this.elem.length;
}
3、出队
//第一个和最后一个换,换完之后,向下调整0这棵树
public int poll(){
if(isEmpty()){
throw new RuntimeException("队列为空") ;
}
int ret = this.elem[0];
//删除
int tmp = this.elem[0];
this.elem[0] = this.elem[this.usedSize-1];
this.elem[usedSize-1] = tmp;
this.usedSize--;
adjustDown(0,this.usedSize);
return ret;
}
public boolean isEmpty(){
return this.usedSize == 0;
}