實現堆的插入和刪除操做

最大堆的插入

//向最大堆中插入元素, heap:存放堆元素的數組
    public static void insert(List<Integer> heap, int value) { 
       //在數組的尾部添加
        if(heap.size()==0)
          heap.add(0);//數組下標爲0的位置不放元素
        heap.add(value); 
        //開始上升操做 
       // heapUp2(heap, heap.size() - 1); 
        heapUp(heap, heap.size() - 1); 
 
    } 
 
    //上升,讓插入的數和父節點的數值比較,當大於父節點的時候就和父節點的值相交換 
    public static void heapUp(List<Integer> heap, int index) { 
 
        //注意因爲數值是從下標爲1開始,當index = 1的時候,已是根節點了 
        if (index > 1) { 
            //求出父親的節點 
            int parent = index / 2; 
 
            //獲取相應位置的數值 
            int parentValue = (Integer) heap.get(parent); 
            int indexValue = (Integer) heap.get(index); 
            //若是父親節點比index的數值小,就交換兩者的數值 
            if (parentValue < indexValue) { 
                //交換數值 
                swap(heap, parent, index); 
                //遞歸調用 
                heapUp(heap, parent); 
            } 
 
        } 
    }

最大堆的刪除

/**
     * 刪除堆中位置是index處的節點
     * 操做原理是:當刪除節點的數值時,原來的位置就會出現一個孔
     * 填充這個孔的方法就是,把最後的葉子的值賦給該孔,最後把該葉子刪除
     * @param heap 
     */ 
    public static void delete(List<Integer> heap,int index) { 
        //把最後的一個葉子的數值賦值給index位置 
        heap.set(index, heap.get(heap.size() - 1)); 
        //下沉操做 
        //heapDown2(heap, index); 
        heapDown(heap, index); 
        //把最後一個位置的數字刪除 
        heap.remove(heap.size() - 1); 
    } 
    /**
     * 遞歸實現
     * 刪除堆中一個數據的時候,根據堆的性質,應該把相應的位置下移,才能保持住堆性質不變
     * @param heap 保持堆元素的數組
     * @param index 被刪除的那個節點的位置
     */ 
    public static void heapDown(List<Integer> heap, int index) { 
        //由於第一個位置存儲的是空值,不在考慮以內 
        int n = heap.size() - 2; 
 
        //記錄最大的那個兒子節點的位置 
        int child = -1; 
 
        //2*index>n說明該節點沒有左右兒子節點了,那麼就返回 
        if (2 * index > n) { 
            return; 
        } //若是左右兒子都存在 
        else if (2 * index < n) { 
 
            //定義左兒子節點 
            child = 2 * index; 
            //若是左兒子小於右兒子的數值,取右兒子的下標 
            if ((Integer) heap.get(child) < (Integer) heap.get(child + 1)) { 
                child++; 
            } 
 
        }//若是隻有一個兒子(左兒子節點) 
        else if (2 * index == n) { 
            child = 2 * index; 
        } 
 
        if ((Integer) heap.get(child) > (Integer) heap.get(index)) { 
            //交換堆中的child,和index位置的值 
            swap(heap, child, index); 
 
            //完成交換後遞歸調用,繼續降低 
            heapDown(heap, child); 
        } 
    }
相關文章
相關標籤/搜索