用图示描述下二叉堆(小顶堆)的插入操作,其中插入的时候就是将小的元素不断的“上浮”
图中蓝色箭头是堆初始化的值,绿色箭头是要插入节点时的值;
黑色的数字是初始化时的各个变量的值,绿色的数字是要插入节点时各个变量的值 ;
蓝色方框里面的绿色0就是要插入的值
下面的图是插入分析的图及插入后的结果图
具体二叉堆的实现代码如下:
public class BinaryHeap {
/**
* 插入节点
* 二叉堆的 "上浮" 调整
*
* @param array 待调整的堆
*/
public static void upAdjust(int[] array){
int childIndex = array.length-1;
int parentIndex = (childIndex-1)/2;
//temp用来保存插入的叶子结点值
int temp = array[childIndex];
while(childIndex > 0 && temp < array[parentIndex]){ //当新插入的叶子节点的值小于其父节点的值
array[childIndex] = array[parentIndex]; //"上浮" (值)交换
childIndex = parentIndex; //位置交换:将当前父节点的位置下标赋值给新节点
parentIndex = (parentIndex-1)/2; //根据
}
array[childIndex] = temp;
}
/**
* "下沉" 调整
*/
public static void downAdjust(int array[], int parentIndex,int length){
int temp = array[parentIndex];
int childIndex = 2*parentIndex+1;
while(childIndex<length){
//如果有右孩子,且右孩子小于左孩子的值,则定位到右孩子
if (childIndex + 1 < length && array[childIndex + 1] < array[childIndex]) {
childIndex++;
}
//如果父节点小与左右孩子中的任意一个,则直接跳出
if(temp <= array[childIndex])
break;
array[parentIndex] = array[childIndex];
parentIndex = childIndex;
childIndex = 2*childIndex+1;
}
array[parentIndex] = temp;
}
/**
* 构建堆
*/
public static void buildHeap(int array[]){
//从最后一个非叶子节点开始,一次做"下沉"
for (int i = (array.length-2)/2; i >= 0; i--) {
downAdjust(array,i,array.length);
}
}
public static void main(String[] args) {
int[] array = new int[]{1,3,2,6,5,7,8,9,10,0};
upAdjust(array);
System.out.println(Arrays.toString(array));
array = new int[] {7,1,3,10,5,2,8,9,6};
buildHeap(array);
System.out.println(Arrays.toString(array));
}
}