C 手寫堆的實現(LuoguP3378模板)

2021-08-03 23:32:20 字數 2052 閱讀 5519

二叉堆有兩種形式,分別為大根堆和小根堆。

大根堆有兩個性質:

1.根節點點權為所有節點點權中的最大值;

2.任意節點的點權都大於它的子節點.

同樣地,小根堆也具有兩個性質,並且與大根堆相反:

1.根節點點權為所有點權中的最小值;

2.任意節點的點權都小於它的子節點.

在此僅展示小根堆的實現方法,大根堆與其同理,稍作修改即可。

題目描述

如題,初始小根堆為空,我們需要支援以下3種操作:

操作1: 1 x 表示將x插入到堆中

操作2: 2 輸出該小根堆內的最小數

操作3: 3 刪除該小根堆內的最小數

輸入輸出格式

輸入格式:

第一行包含乙個整數n,表示操作的個數

接下來n行,每行包含1個或2個正整數,表示三種操作,格式如下:

操作1: 1 x

操作2: 2

操作3: 3

輸出格式

包含若干行正整數,每行依次對應乙個操作2的結果。

輸入輸出樣例

輸入樣例#1:

5 1 2

1 5

2 3

2 輸出樣例#1:

2 5

說明

時空限制:1000ms,128m

資料規模:

對於30%的資料:n<=15

對於70%的資料:n<=10000

對於100%的資料:n<=1000000

思路

1.建立小根堆

首先,如圖所示,由於二叉堆的性質,左兒子的編號一定是其父節點編號的2倍,右兒子的編號一定是其父節點編號的2倍再加1,所以我們可以利用這個性質來建立乙個小根堆。

2.對於小根堆的維護

由於**和注釋都已經寫的很清楚了,這裡就不再詳述。

a.插入元素(insert)

由於小根堆的性質,我們要對新插入的元素位置進行調整,使插入後的堆仍為乙個小根堆。

b.刪除元素(del)

首先要記住乙個問題:c++中delete為固定的操作符(本身帶有),所以函式的命名不能用delete(delete大概是可以的)。

對於堆中最小值,即根節點的刪除操作,我們可以通過縮小堆的空間來實現。將根節點的值與堆中編號最大的值交換,再把堆的空間減1即可。但是還要注意的是,由於小根堆的性質,刪除前堆中編號最大的節點的值一定是大於原根節點中的子節點的,所以我們需要對其進行維護。

**實現

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

int n,m,y,ans,t;

int tree[2000003];

void change(int a,int b)

void insert(int x)

else f=1;//新節點大於根節點則不發生改變

x=x/2;//繼續查詢下乙個根節點(大概是爺爺節點吧(霧)是否小於該新節點,不是則繼續查詢,直到下乙個根節點值小於該新節點

}}void del(int x)//將tree[n]放在tree[1]不滿足小根堆的性質,所以要進行調整

if(tree[x]>tree[x*2+1]&&tree[x*2+1]2]&&x*2+1

<=t)

if(x!=d)

else f=1;

} }int main()

if(m==2)

if(m==3)

}return

0;}

Luogu P1334 瑞瑞的木板(手寫堆)

其實這個題完全不需要用手寫堆,只需要一遍遍sort就行了 但是!為了練習手寫堆,還是用手寫堆做了。在做本題之前,如果你沒有什麼思路的話,建議先做luogu的合併果子。好,假設你已經做過了合併果子了。那麼正式開始本題 ac include include include include include...

C 堆的實現

堆是乙個完全二叉樹。堆根據元素的排列方式,可以分為最大堆 max heap 和最小堆 min heap 其中 堆並不歸屬於stl庫容器元件,而是作為優先佇列 priority queue 的底層實現。堆是一種完全二叉樹,整棵二叉樹除了最底層的葉子節點之外是填滿的,而最底層的葉子節點由左至右是沒有空隙...

左傾堆的C 實現

在下小白乙個 如有錯誤請指正 上 using system 資料結構 namespace datastructure public leftistnoderightnode public t key public int npl public leftistnode leftistnodeleftn...