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 )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章