堆
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問題的求解