JAVA数据结构之MaxHeap

最大堆的数组实现
博客介绍了最大堆的实现,最大堆中父节点大于子节点,因其为平衡树、最大深度相差不超过1,所以可以用数组实现,且根结点从0开始计算。

最大堆的实现

  • 最大堆,父节点大于子节点
  • 因为堆必定为平衡树,最大深度相差不超过1,所以可以用数组实现
  • 根结点从0开始计算
public class MaxHeap<E extends Comparable<E>>{
    private Array<E> data;

    public MaxHeap(int capacity){
        data = new Array<>(capacity);
    }

    publi MaxHeap(E[] arr){
    //Array的构造函数
        data = new Array<E>(arr);
        for(int i =parent(arr.length - 1);i>=0;i--){
            siftDown(i);
        }
    }

     //返回堆中的元素个数
    public int size(){
        return size;
    }

    //返回一个boolean值,判断堆是否为空
    public boolean isEmpty(){
        return size==0;
    }

     //返回完全二叉树的数组表示中,一个索引所表示的元素的父亲节点的索引 
    private int parent (int index){
        if(index == 0){
            throw new IllegalArgumentException("Index-0 doesn't hava parent");
        }
        return (index - 1)/2;
    }

    // 返回完全二叉树的数组表示中,一个索引所表示的元素的左孩子节点的索引 
    private int leftChild(int index){
        return index*2+1;
    }
     // 返回完全二叉树的数组表示中,一个索引所表示的元素的右孩子节点的索引 
    private int rightChild(int index){
        return index*2+2;
    }
    //向堆中添加新的元素
    public void add(E e){
        data.addLast(e);
        siftUp(data.getSize()-1);
    }

    //元素上浮
    private void siftUp(int k){
        while(k > 0 && data.get(parent(k).cpmpareTo(data.get(k)))<0){
            data.swap(k,parent(k));
            k = parent(k);
        }
    }

    public E findMax(){
        if(data.getSize()==0){
            throw new IllegalArgumentException("Can not findMax when heap is empty");
        }
        return data.get(0);
    }

    //取出堆中最大元素

    public E extractMax(){
        E ret = findeMax();

        data.swap(0,data.getSize()-1);
        data.removeLast();
        siftDown(0);

        return ret;
    }

    private void siftDown(int k){        
    //判断条件,K左孩子不能越界
        while(leftChild(k)<data.getSize()){

            int j = leftChild(k);

            if(j+1<data.getSize()&&data.get(j+1).compareTo(data.get(j)>0){
                            //data[j] 是 leftChild 和 rightChild中的最大值

                j = rightChild(k);
            }
            //如果满足堆性质
            if (data.get(k).compareTo(data.get(j)) >= 0) {
                break;
            }
            data.swap(k, j);
            k = j;
        }
        //取出堆顶元素,并且替换成元素
        public E replace(E e){
            E ret = findMax();
            data.set(0,e);
            siftDown(0);
            return ret;
        }
    }
}
//add和extractMax时间复杂度都是o(logn )
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值