堆的瞭解

堆的定義

  • 堆是一個完全二叉樹,這樣的堆也被稱爲二叉堆。(之前瞭解過相關知識,但是現在大部分忘記了。後續博客上會補充上去)

  • 子節點大於如果大於節點,這樣的堆稱爲小頂堆。子節點小於節點的堆稱爲大頂堆。

    堆的基本操作有插入、刪除堆頂元素。

堆的操作圖解

  • 堆化。將堆中的元素重新按照堆的結構插入,類似於排序。

IMG_DC4BB8DB8C61-1

  • 刪除堆頂元素。將堆頂的元素刪除,再將堆進行堆化。(其中,如果出現了數組空洞,可以將最後一個元素覆蓋堆頂元素,再執行堆化)

    IMG_A1368FA8ADD6-1

在平時代碼中的應用

可能是因爲我瞭解的太少,感覺用處不是很大,因爲基礎的工具對於這些數據的操作大部分都已經封裝好了,只需要知道怎麼調用就可以了。但是作爲程序員來說,知道其內部原理還是比較好的。

因爲很長時間沒有學習數據結構了,所以這個寫着相當費力,後面陸續會寫相關博客,但是可能不是很多。。。

代碼在下面。註釋中對於代碼的解釋已經很詳細了。

package arraytrain;

/**
 * HeapTrain.java
 * Description: 堆的練習
 *
 * @author Peng Shiquan
 * @date 2020/5/2
 */
public class HeapTrain {

    private int[] arr;
    /**
     * 堆內當前堆元素
     */
    private int n;
    /**
     * 堆內最大堆元素
     */
    private int capacity;

    /**
     * Description:初始化
     *
     * @param count
     * @return
     * @Author: Peng Shiquan
     * @Date: 2020/5/2
     */
    public HeapTrain(int count) {
        capacity = count;
        arr = new int[capacity + 1];
        n = 0;
    }

    public void heapPrint() {
        for (int i = 0; i < n + 1; i++) {
            System.err.print("[" + arr[i] + "]");
        }
    }

    /**
     * Description: 換位方法
     *
     * @param a
     * @param b
     * @return void
     * @Author: Peng Shiquan
     * @Date: 2020/5/2
     */
    public void swap(int a, int b) {
        int swap = arr[a];
        arr[a] = arr[b];
        arr[b] = swap;
    }

    /**
     * Description:向堆中插入元素
     *
     * @param value
     * @return void
     * @Author: Peng Shiquan
     * @Date: 2020/5/2
     */
    public void insert(int value) {
        if (n >= capacity) {
            return;
        }
        n++;
        arr[n] = value;
        int i = n;
        /**
         * 兩個判斷條件,一個是i是不是標號最小的元素、節點是不是大於子節點
         */
        while (i / 2 > 0 && arr[i / 2] < arr[i]) {
            swap(i / 2, i);
            i = i / 2;
        }
    }

    /**
     * Description:刪除堆頂元素
     *
     * @param
     * @return void
     * @Author: Peng Shiquan
     * @Date: 2020/5/2
     */
    public void deleteMax() {
        if (n == 0) {
        }
        int tmp = arr[1];
        /**
         * 堆內可以放負數,如果arr[1]=0,負數就沒法比較
         */
        int count = n;
        /**
         * 將最後的元素放到跟節點,防止數組空洞。同時將兩步堆化合併爲一步
         */
        arr[1] = arr[count];
        n--;
        heaply(1, n);
    }

    /**
     * Description: 堆化處理
     *
     * @param index
     * @param n
     * @return void
     * @Author: Peng Shiquan
     * @Date: 2020/5/2
     */
    public void heaply(int index, int n) {
        while (true) {
            /**
             * 默認當前節點是最大節點
             */
            int maxValueIndex = index;
            /**
             *  先計算左節點
             */
            if (maxValueIndex * 2 <= n && arr[maxValueIndex] < arr[maxValueIndex * 2]) {
                maxValueIndex = maxValueIndex * 2;
            }
            /**
             * 計算右節點
             */
            if (maxValueIndex * 2 + 1 <= n && arr[maxValueIndex] < arr[maxValueIndex * 2 + 1]) {
                maxValueIndex = maxValueIndex * 2 + 1;
            }
            /**
             * 經過比較確實是最大節點
             */
            if (maxValueIndex == index) {
                break;
            }
            swap(index, maxValueIndex);
            /**
             * 把最大節點給到當前節點的子節點
             */
            index = maxValueIndex;
        }
    }

    public static void main(String[] args) {
        HeapTrain heapTrain = new HeapTrain(10);
        heapTrain.insert(3);
        heapTrain.insert(1);
        heapTrain.insert(9);
        heapTrain.heapPrint();
        System.err.println();
        heapTrain.deleteMax();
        heapTrain.heapPrint();

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章