1. 程式人生 > >實現堆的插入和刪除操作

實現堆的插入和刪除操作

最大堆的插入

//向最大堆中插入元素, 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);