堆
1.堆本质上是一个二叉树,满足这几个条件
1)完全二叉树
2)对于树中的任意节点,满足根节点小于左右子树的值(小堆),满足根节点大于左右子树的值(大堆),,一个堆如果是小堆,就不可能是大堆
3)堆通常就是通过数组的形式来存储的
4)堆最大的用处就是让我们快速找到一个树中的最大值或者最小值(根节点)
向下调整
//size指的是数组中哪部分内容是堆
//index指的是从当前下标开始
public static void shiftDown(int[] array,int size,int index){
int parent=index;
int child=parent*2+1;
//这个条件的含义是看看parent有没有子节点
while(child<size){
while(child+1<size&&array[child+1]<array[child]){
//比较左右子树,找到最小值
child=child+1;
}
if(array[child]<array[parent]){
int t=array[child];
array[child]=array[parent];
array[parent]=t;
}else{
//调整完毕
break;
}
parent=child;
child=parent*2+1;
}
}
//大堆的向下调整
public static void shiftDown1(int[] array,int size,int index) {
int parent = index;
int child = parent * 2 + 1;
while (child < size) {
while (child + 1 < size && array[child + 1] > array[child]) {
child = child + 1;
}
if (array[parent] < array[child]) {
int t = array[parent];
array[parent] = array[child];
array[child] = t;
} else {
break;
}
parent = child;
child = parent * 2 + 1;
}
}
public static void createHeap(int[] array,int size){
//向下调整,从后往前遍历数组
for(int i=(size-1-1)/2;i>=0;i--){
shiftDown1(array,size,i);
}
}
向上调整
private static void shiftUp(int[] array,int index) {
int child = index;
int parent = (child - 1) / 2;
while (child > 0) {
if (array[parent] < array[child]) {
int tmp=array[parent];
array[parent]=array[child];
array[child]=tmp;
}else{
break;
}
child=parent;
parent=(child-1)/2;
}
}
优先级队列
入队列
public void offer(int x){
array[size]=x;
size++;
//把新加的元素进行向上调整
shiftUp(array,size-1);
}
出队列
public int poll(){
//将下标为0的元素删掉
int oldValue=array[0];
array[0]=array[size-1];
size--;
shiftDown(array,size,0);
return oldValue;
}
TOPK问题的求解