堆的數據結構
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 操作。
看下 下面的圖片演示
以下面的堆爲例演示
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