堆(heap)
概念:
- 堆逻辑上是一棵完全二叉树
- 堆物理上是保存在数组中
- 满足任意结点的值都大于其子树中结点的值,叫做大堆,或者大根堆,或者最大堆
下标关系:
已知双亲(parent)的下标,则:
左孩子(left)下标 = 2 * parent + 1;
右孩子(right)下标 = 2 * parent + 2;
已知孩子(不区分左右)(child)下标,则:
双亲(parent)下标 = (child - 1) / 2;
下面以小堆为例完成建堆
//左右已经为堆
public void shiftDownSmall(int[] array, int size, int index) {
int lef t= index * 2 + 1;
while(left < size){
int min = left;
int right = index * 2 + 2;
if(right < size && array[right] < array[left]){
min=right;
}
if(array[index] < array[min]){
break;
}
//将更小的值 调上
int tmp = array[index];
array[index] = array[min];
array[min] = tmp;
//更新 index left
index = min;
left = index * 2 + 1;
}
}
//左右不为堆
//先从最小的树开始 保证子结构也为堆
public static void createHeapSmall(int[] array, int size) {
for (int i = (size - 2) / 2; i >= 0; i--) {
//最小的树即最后一个叶子的根,它的坐标为(size - 1) 其父亲结点坐标为(size - 1 - 1) / 2
//i=0时左右子树已经为堆 从根开始调整
shiftDownSmall(array, size, i);
}
}