数组实现完全二叉树(大根堆)

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];
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值