public class AvlTree {
/*
* 堆结构就是用数组实现的完全二叉树结构
* 完全二叉树中如果每棵子树的最大值都在顶部就是大根堆
* 完全二叉树中如果每棵子树的最小值都在顶部就是小根堆
* 优先级队列结构就是堆结构
*
* 数组实现完全二叉树(大根堆)
* 数组从1开始存储 [null,9,5,6,4,3]
* 父:i 左子节点:2*i 右子节点:2*i+1
*/
int[] arr = new int[10];
//堆大小
int heapSize;
public static void main(String[] args) {
AvlTree tree = new AvlTree();
tree.addHeap(1);
tree.addHeap(2);
tree.addHeap(3);
tree.addHeap(4);
tree.addHeap(5);
tree.addHeap(6);
tree.addHeap(7);
tree.addHeap(8);
tree.addHeap(9);
tree.addHeap(10);
tree.addHeap(11);
tree.addHeap(12);
tree.removeHeap(0);//删除堆中最顶层元素
for(int i =1;i<=tree.heapSize;i++) {
System.out.print("元素:"+tree.arr[i]);
}
}
//往堆中添加元素
public void addHeap(int value) {
this.heapSize++;
if(this.heapSize==arr.length) {
//堆满了进行扩容
copyArr();
}
arr[this.heapSize] = value;
//要保持大根堆 需要不断和和父值比较进行交换数据
int pIndex = this.heapSize>>1;
int curIndex = this.heapSize;
while(pIndex>0) {
if(arr[curIndex]>arr[pIndex]) {
swap(arr,curIndex,pIndex);
curIndex = pIndex;
pIndex = curIndex>>1;
}else {
break;
}
}
}
//根据数组坐标删除某一个堆元素
public int removeHeap(int index) {
if(++index>this.heapSize-1) {
throw new RuntimeException("元素不存在");
}
int value = arr[index];
//将最后一个元素顶替删除的元素
swap(arr,index,this.heapSize--);
int currIndex = index;
int leftIndex = currIndex <<1;
//元素删除需要子上去顶替从而保证大根堆
while(leftIndex <= this.heapSize) {
int rigthIndex = leftIndex | 1;
//当且仅当右侧存在且大于左侧是右侧
int maxIndex = rigthIndex <= this.heapSize && arr[rigthIndex]>arr[leftIndex] ? rigthIndex:leftIndex;
if(arr[currIndex]<arr[maxIndex]) {
swap(arr,currIndex,maxIndex);
currIndex = maxIndex;
leftIndex = currIndex <<1;
}else {
break;
}
}
return value;
}
private void copyArr() {
int newSize = arr.length+(arr.length>>1);
this.arr = Arrays.copyOf(this.arr, newSize);
}
private void swap(int[]arr,int x,int y) {
arr[x] = arr[x] ^ arr[y];
arr[y] = arr[x] ^ arr[y];
arr[x] = arr[x] ^ arr[y];
}
03-22
592
01-18
303
12-10
346