二叉堆 優先佇列 待更新

2021-10-19 15:16:40 字數 2614 閱讀 4472

視覺化

堆是一種特殊的二叉樹,堆只按照堆屬性來進行排序,相較於普通的樹,推的優點在於其省略了大量的『額外的資訊』(有時候很重要,不得不用樹來實現)所以其實現比樹更為簡單。

堆是按照其屬性進行排序。

乙個堆只需要滿足一下乙個特點即可

在最大堆中,只需要保證其父節點大於所有子節點。

在最小堆中則相反。

以下所有的演示均為最大堆演示,最小堆相反即可。

建立堆

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 刪除最小者 它的...