視覺化
堆是一種特殊的二叉樹,堆只按照堆屬性來進行排序,相較於普通的樹,推的優點在於其省略了大量的『額外的資訊』(有時候很重要,不得不用樹來實現)所以其實現比樹更為簡單。堆是按照其屬性進行排序。
乙個堆只需要滿足一下乙個特點即可
在最大堆中,只需要保證其父節點大於所有子節點。
在最小堆中則相反。
以下所有的演示均為最大堆演示,最小堆相反即可。
建立堆
struct greater_heap
;int size =0;
};
堆只需要乙個陣列來實現,其他所有的資料都是不必要的。
例如 (這是乙個已經排好的資料)
[34,33,25,23,19,7,5,2]
那麼我們只需要如下的儲存方式
由圖我們不難發現有如下的表示方式
另某乙個節點為第 i 個節點
f a(
i)=⌊
i2⌋fa(i) = \lfloor\frac2\rfloor
fa(i)=
⌊2i⌋ls
on=i
×2lson=i\times2
lson=i
×2r so
n=i×
2+1rson=i\times2+1
rson=i
×2+1
**
// 存在則返回大於0 的數 否則返回 0
intlson
(const
int&i)
const
intrson
(const
int&i)
const
intfather
(const
int&i)
const
注意最大節點並沒有父節點,以及有最下層的節點可能沒有葉子了,因此要判斷範圍是否正確有這個公式我們可以知道,我們可以話費o(1
)o(1)
o(1)
的時間複雜度找到它的子節點和父節點。
只要考慮a[1] 是否存在即可
若沒有的話則需要返回乙個不存在的值來說明是否存在。
但建議在使用的時候先進行資料大小的查詢
int
size()
inttop()
既然我們已經儲存了上面的堆,那麼堆怎麼進行插入呢。
加入我們插入乙個40
建立最下左端的子節點。
建立 9 號子節點。
子節點與父節點比較,若比父節點大則交換,一直到無法交換為止
由於其他堆已經做好比較了,所以交換並不會改變原有的結構。
具體可以到頁首提供的鏈結看一看。
while
(i >
1&& a[i /2]
< a[i]
)swap
(a[i]
, a[i /2]
), i/=2
;
那麼插入的操作可以為
void
swap
(int
&a ,
int&b)
void
insert
(const
int&k)
在堆中,將最大數彈出後,那麼將會產生乙個空穴。因此我們需要將此空穴變換才可以進行別的操作。那麼我們為了保持堆的屬性,我們不妨將最右端的子葉填充到頂堆。那麼我們就可以對這個進行重新交換的操作。
**
void
pop(
)}
在c++ 中使用模板代替 int , 使用 vector 代替陣列。
目前的**(待更新)
struct greater_heap
;int size =0;
intsize()
inttop()
intlson
(const
int&i)
const
intrson
(const
int&i)
const
intfather
(const
int&i)
const
void
swap
(int
&a ,
int&b)
void
insert
(const
int&k)
void
pop()}
};
優先佇列 二叉堆
優先佇列 二叉堆 二叉堆是一棵完全二叉樹,最大堆 最小堆 中,所有根節點的鍵值都要比對應的子樹要大 小 由於是完全二叉樹,所以儲存結構可以採用陣列。最大堆的建立 include include include include include include define inf 0x3f3f3f3f...
二叉堆 優先佇列
堆 堆常見的二叉堆,這種資料結構有大根堆和小根堆。對於大根堆來說,每個父節點是大於他的兩個孩子節點的。也就是最大值在根節點。小根堆與之相反。如果堆用陣列實現的話,如果從1開始計數 因為0的位置可以在上慮或者下慮的時候做個暫存的位置 那麼乙個孩子的父節點是i 2 如果知道了父節點,而左孩子的節點位置為...
二叉堆(優先佇列)
0.1 本文總結於 資料結構與演算法分析,但源 均為原創 旨在理清二叉堆 優先佇列 堆的其他操作及其應用,以便讓朋友些知道為什麼要學習優先佇列 二叉堆 1.0 優先佇列定義 優先佇列是允許至少下列兩種操作的資料結構,insert 插入 它的工作時顯而易見的,以及 deletemin 刪除最小者 它的...