JAVA数据结构之MaxHeap

最大堆的实现

  • 最大堆,父节点大于子节点
  • 因为堆必定为平衡树,最大深度相差不超过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 )

猜你喜欢

转载自blog.csdn.net/weixin_41263632/article/details/82049636
今日推荐