比如要把 2 这个结点删除掉 由于2是数组第一个元素 9为数组最后一个元素
则将2与9 进行交换 让删除的元素放在数组最后面
然后 引入一个变量tail 记录数组末尾的索引 此时将tail-1 即是将最后的2删除了
由于9在数组第一个元素 破坏了有序性 所以要与两个孩子比较 与最小的孩子交换 保持父结点始终小于两个孩子结点
第一次下沉
第二次下沉
上浮
下沉
package com.qbsea.arithmetic.binarytree;
//二叉堆
public class BinaryHeap {
public static class MyQueue{
static int[] array = new int[100];
static int sizeReal = 1;
static int takeValue = -1;
MyQueue(){
for(int i=1;i<array.length;i++) {
array[i]=-1;
}
}
public static void add(int i) {
array[sizeReal] = i;
swim(array,sizeReal);//上浮 递归
// swim1(array,sizeReal);//上浮迭代
sizeReal++;
}
public static void swim(int[] array,int insertNodeIndex) {
if(insertNodeIndex==1) {//第一个数组
return;
}
int parentIndex = insertNodeIndex/2;
if(array[insertNodeIndex]<array[parentIndex]) {//父结点大于子结点了
exchange(array,insertNodeIndex,parentIndex);
swim(array,parentIndex);//递归
}
}
//take 出来的值
public static int take() {
if(sizeReal==1) {
return -1;
}
takeValue = array[1];
exchange(array,1,sizeReal-1); //队首与队尾换一下
//队尾的值 就在逻辑上删除了不要了
sizeReal--;
sink(array,1);//将剩下的值 进行下沉排序
// sink1(array,1);
return takeValue;
}
public static void sink(int[] array,int parentIndex) {
int minNodeIndex = getMinIndex(array,parentIndex);
if(minNodeIndex!=parentIndex) {//最小值的索引不是根结点索引
//进行交换
exchange(array,minNodeIndex,parentIndex);
sink(array,minNodeIndex);
}
}
public static void sink1(int[] array,int parentIndex) {
while(true) {
int minNodeIndex = getMinIndex(array,parentIndex);
if(minNodeIndex==parentIndex) {//最小值的索引 就是根结点的索引
break;
}else {//最小值的索引 不是根结点的索引 将根与最小值交换
exchange(array,minNodeIndex,parentIndex);
parentIndex = minNodeIndex; //以前的根结点下沉到最小值的索引了
}
}
}
public static int getMinIndex(int[] array,int parentIndex) {
int leftIndex = parentIndex*2;
int rightIndex = parentIndex*2+1;
int minTemp = parentIndex;
if(leftIndex<sizeReal && array[leftIndex] < array[parentIndex]) {
minTemp = leftIndex;
}
if(rightIndex<sizeReal && array[rightIndex] <array[minTemp] ) {
minTemp = rightIndex;
}
return minTemp;
}
}
public static void main(String[] args) {
int[] input = new int[]{7,2,4,6,5,9};
//插入元素形成一个二叉堆
for(int i=0;i<input.length;i++) {
MyQueue.add(input[i]);
}
//遍历队列
for(int i=1;i<MyQueue.sizeReal;i++) {
System.out.println(MyQueue.array[i]);
}
System.out.println("-------");
while(true) {
int intVal = MyQueue.take();
if(intVal==-1) {
break;
}
System.out.println(intVal);
}
}
public static void swim1(int[] array,int insertNodeIndex) {
if(insertNodeIndex==1) {//第一个数组
return;
}
int parentIndex = 0;
while(true) {
parentIndex = insertNodeIndex/2;
if(array[parentIndex]<array[insertNodeIndex]) {//正常
break;
}else {//否则 就是父结点大于子结点需要交换
exchange(array,insertNodeIndex,parentIndex);
insertNodeIndex = parentIndex;
}
}
}
public static void exchange(int[] array,int insertNodeIndex,int parentIndex) {
if(insertNodeIndex==parentIndex) {
return;
}
int temp = array[insertNodeIndex];
array[insertNodeIndex] = array[parentIndex];
array[parentIndex]=temp;
}
}