堆的數據結構-shift_down操作

堆的數據結構

1 MaxHeap 數據結構定義

第一個是 存放數據的數組 data 表示,
第二是 數據數量用 count 表示,
第三個 記錄堆最大容量 用 capacity 表示

template<typename Item>
class MaxHeap {


private:
    Item *data;  // 定義一個數組存放堆,從下標 1 開始
    int count;  // 記錄當前堆的元素的個數
    int capacity; // 記錄堆的最大容量, 這裏的堆是不可擴展的堆,初始化後 最大容量就已經確定了。
}

1 接口定義

說明 這裏堆 的定義 數據從 小標爲1 的地方開始 ,0號位置不用的。

1.size(),返回堆中的元素個數

2.isEmpty() 判斷是否爲空隊列

3.push(item) 將item 放入到堆裏面,使之保持成大頂堆,入堆操作

4.shift_up(int k) 將位置爲k 的元素,調整成一個大頂堆的形式。使從 [1,k] 的元素 是一個大頂堆。

5.pop() 彈出堆頂的元素,返回堆頂元素。改變堆的結構,堆的size 要減1 ,出堆操作。

6.getTop() 獲取堆頂元素,不改變堆的結構 。

7.printHeap() 打印堆的形狀

2 shift_down 詳解

pop操作:
取出堆中的元素,直接 將 最後一個元素和 堆頂交換位置,把堆的size-- , 然後 把最後一個元素 往下 調整,使變成一個大頂堆。

只要比較 當前的 結點 孩子結點的較大值 ,查看 是否大於當前結點 ,如果大於就交換,並且 更新 當前結點到 較大值孩子結點的索引 繼續這樣的操作,

否則 就完成了shift_down 操作。

看下 下面的圖片演示

shift_down-01.png
以下面的堆爲例演示

shift_down-01.png

shift_down-02

shift_down-03

shift_down-04

shift_down-05

shift_down-06

3 代碼

出堆操作

    Item pop() {
        /*
         *   Pop the largest item off the heap, maintaining the heap invariant.
         *   出堆
         *  從最大堆中取出堆頂元素, 即堆中所存儲的最大數據
        */

        Item largestItem = data[1];

        swap(data[1], data[count]);
        this->count--;

        shiftDown(1);
        return largestItem;

    }

shiftDown 操作


    void shiftDown(int k) {
        /*
        * 下移 元素把 元素調整成大頂堆 ,嘗試調整 k 索引對應的元素,調整成 大頂堆
        * */
        // 首先要判斷有沒有做孩子,有左孩子 就說明 還沒有到堆的最後一層
        while (2 * k <= count) {

            // 初始化 任務左孩子
            int j = 2 * k;//此輪 循環 是要找到 data[k]節點應該和 j的位置 互換

            if (j + 1 <= count && data[j + 1] > data[j]) {
                j = j + 1;  // 尋找較大的兒子結點
            }

            if (data[j] <= data[k]) {
                // 說明 已經 是大頂堆了,不用繼續尋找下去了。
                break;
            }
            swap(data[j], data[k]);
            // 更新k
            k = j;
        }
    }

完整代碼 main.cpp
運行結果如下:

shift_down-07

完整的代碼
Shift-Down

分享快樂,留住感動. '2020-02-02 16:50:18' --frank
發佈了112 篇原創文章 · 獲贊 65 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章