1.堆的概念
堆在逻辑上是一颗完全二棵树。
堆在物理上是保存在数组中。
满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆,反之,则是
堆,或者小根堆,或者最小堆。我们可以用PriorityQueue来表示
那我们再了解堆的使用方法之前,先来自己实现一个堆
2.
public class TestHeap {
public int[] elem;
public int usedSize;
public TestHeap(){
this.elem=new int[10];
}
/*
parent代表树的根节点
len代表每棵树的结束位置
*/
public void shiftDown(int parent,int len){
int child = 2 * parent + 1;
//1.child < len表示最起码是有左孩子的,至少有一个孩子
while (child < len){
if(child+1 < len && elem[child] < elem[child+1]){
child++;//保证当前左右孩子最大值下标
}
if(elem[child] > elem[parent]){
int tmp = elem[parent];
elem[parent] = elem[child];
elem[child] = tmp;
//防止parent--之后,下面还有不是大根堆的节点,还需要再向下遍历
parent = child;
child = 2 * parent + 1;
}else{
break;
}
}
}
public void createHeap(int[] array){
for (int i = 0; i < array.length; i++) {
elem[i] = array[i];
usedSize++;
}
for (int parent =(usedSize-1-1)/2 ; parent >= 0; parent--) {
shiftDown(parent,usedSize);
}
}
}
3.时间复杂度
我们都知道堆的时间复杂度 = 每一层结点的个数 * 每个节点调整的高度
因此堆的时间复杂度为O(n).
4.java中的优先级队列
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();