堆是一種特殊的資料結構,相當於陣列實現的一顆二叉樹,但是和一般的二叉搜尋樹不同
1.堆分為最大堆(父結點的值必大於其孩子結點的值)和最小堆(父結點的值必小於其孩子結點的值),
而二叉搜尋樹中左孩子結點的值小於父節點的值,右孩子結點的值大於父節點的值。
2.堆採用陣列形式儲存,相較於二叉樹的鍊錶結構減少記憶體消耗
3.堆排序的時間複雜度可以穩定在o(nlogn),而當二叉樹為非平衡狀態時,相應操作的時間複雜度不能穩定
優先佇列的使用場景十分之廣,比如此時此刻你的計算機作業系統正在處理很多的程序,程序與程序之間存在著優先執行關係,對應的每個程序都有乙個優先順序。
舉個更簡單的例子:雲頂之弈中,很多英雄的技能會優先攻擊血量最少的敵方英雄。lol中也存在著類似的技能機制。實質上就是乙個動態的優先佇列。
堆中的內容經過heapify後交換了位置,從而形成最大堆或者最小堆。對簡單的資料內容進行交換空間、時間消耗還不大,但是若對於上述提到的程序、英雄單位這些物件,操作起來則會比較麻煩並且很多情況下我們並不想改變元素的位置。
索引堆就是為了解決這個問題,對於原陣列中的元素不進行交換,而是額外創造乙個對應於原陣列的索引陣列(int),索引陣列中每個元素記錄原陣列中每個元素的索引,在索引陣列中進行heapify交換索引位置,讓索引生成最大堆或者是最小堆,從而對於原陣列沒有改變。
索引堆運用在優先佇列、圖的最小生成樹等演算法當中。
根據最大堆、最小堆堆頂元素的性質,從而可以實現堆排序,具體實現如下。
根結點以1開始
template
<
typename t>
class
maxheap
}void
shiftdown
(int index)
}public
:maxheap
(int n)
maxheap
(int n,
int*arr)
capacity=n;
count = n;
for(
int i = n/
2; i >0;
--i)
//n/2表示第乙個非葉子結點的結點
}void
insert
(t x)
t extractmax()
};
根結點從0開始:
#include
"iostream"
#include
"assert.h"
using
namespace std;
template
<
typename item>
class
minheap
}void
shiftdown
(int k)
}public
:minheap
(int n)
void
add(item x)
item extractmin()
bool
empty()
~minheap()
};
template
<
typename t>
void
shiftdown
(t arr,
int n,
int index)
}template
<
typename t>
void
heapsort
(t arr,
int n)
}
n=50000 測試範圍0~50000
測試隨機生成以及完全有序兩種情況
最大堆 最小堆 堆排序
最 大 小堆的性質 1 是一顆完全二叉樹,遵循完全二叉樹的所有性質。2 父節點的鍵值 大於 小於等於子節點的鍵值 3 在堆排序中我們通常用的是最大堆,最小堆通常用在優先佇列中 尚未找到恰當的例子 堆排序 陣列 a 10 可以利用建堆的方式對其進行排序。因為堆是一顆完全二叉樹,根據完全二叉樹的性質可以...
C Heap 堆的實現(最小堆 最大堆)
堆也叫優先佇列,堆是一種特殊的完全二叉樹資料結 堆分為兩種,最大堆,最小堆。最大堆 根節點大於左右兩個子節點的完全二叉樹 最小堆 根節點小於左右兩個子節點的完全二叉樹 堆可以用陣列來儲存,a i 處存根節點,a 2 i 存左子樹的根節點 a 2 i 1 存右子樹的根節點。i從1開始 元素下沉 voi...
堆的基本實現以及堆排序
heap.h pragma once include include include include include includetypedef int hpdatatype typedef struct heap heap void heapcreat heap hp,hpdatatype a,...