演算法模板之堆 優先佇列

2021-08-13 07:07:01 字數 2542 閱讀 1899

堆的定義

堆結構是一種陣列物件,可以被視為一顆完全二叉樹。

樹中的每個節點與陣列中存放該節點中值的那個元素相對應。

由上圖不難看出 fa

ther

(i)=

⌊i/2

⌋ le

ftch

ild(

i)=i

∗2 r

ight

chil

d(i)

=i∗2

+1當然也可以用位運算來加快速度 fa

ther

(i)=

⌊i>>1⌋

leftchi

ld(i

)=i<<1

由於i*2一定為偶數(i∈n+),所以i<<1|1等價於i*2+1. ri

ghtc

hild

(i)=

i<<1|

1 堆的性質

n個關鍵字序列l[1…n]稱為堆,當且僅當該序列滿足:

1. l(i)<=l(2i)且l(i)<=l(2i+1)或

2. l(i)>=l(2i)且l(i)>=l(2i+1)

滿足第乙個條件的成為小根堆(即每個結點值小於它的左右孩子結點值),滿足第二個新增的成為大根堆(即每個結點值大於它的左右孩子結點值)。

堆的操作
1.向堆中加入乙個元素(push),並保持堆的有序

2.從隊中刪除乙個元素(pop),並保持堆的有序

3.查詢最小/最大值(top).

演算法分析
插入乙個元素:1.在堆尾加入乙個元素,把這個節點設定為當前結點

2.維護——

比較當前結點和它的父結點的大小,小於父結點的話就交換它們的值,一直交換直到當前結點大於等於它的父結點(小根堆),大根堆相反。

刪除乙個元素

1.把堆的最後乙個結點(heap[size])放到根的位置上(將根結點覆蓋),pa指向根結點,size–。

2.根結點沒有兒子就return;否則,取兒子中最小的乙個與其比較,比子結點大就交換它們的值,pa指向子結點。(小根堆,大根堆則是取兒子中最大的比較,比子結點小就交換)

查詢最小、最大值

就是堆頂元素

具體實現

插入操作

void push(int d)//向堆heap中插入d

}//或者是使用stl裡面堆的維護操作:

void put(int d)

刪除操作

void pop()

}//使用stl:

void pop(int d)

查詢

int

get()

當然以上操作也可以使用優先佇列容器(priority_queue)

洛谷上關於小根堆的測試

手寫堆:

#include#include#includeusing namespace std;

const

int n=1000000+121;

int size,n,heap[n];

void swap(int &a,int &b)

void put(int d)

}void pop()

}int

get()

int main()

else

if(a==2)

printf("%d\n",get());

else pop();}}

優先佇列容器:

#include

#include

#include//要用stl的佇列或者優先佇列的話不要忘了這個標頭檔案

#include

using

namespace

std;

//定義乙個優先佇列h,greater<>表示為小根堆

//vector<>是向量,動態陣列的一種,所佔記憶體隨插入元素的增加而增加

priority_queue

,greater >h;

int main()

else

if(a==2)

printf("%d\n",h.top());//堆頂元素

else h.pop();//彈出}}

堆的經典例題:

洛谷:p1090 合併果子

洛谷:p1631 序列合併

洛谷:p3378 【模板】小根堆

openjudge: 3.7 集合問題

利用堆之優先佇列

利用上一節的最大堆,中間省略了很多該刪和修改的東西,總是時學習演算法嗎 懶了一些啊,o o include include struct heap int paraent int i int leftchild int i int rightchild int i void max heap int...

優先佇列《堆》

1.模型 兩個基本操作 insert等價enqueue deletemin刪除最小者 dequeue 2.簡單的實現 1 簡單鍊錶 遍歷刪除min或者排序刪除min 2 使用二叉查詢樹。反覆除去min會使得樹不平衡,並且bst還支援許多不需要的操作。3.二叉堆 優先佇列的實現普遍使用二叉堆,堆有兩個...

優先佇列 堆

印表機列印作業一般是放在佇列中的。如果按照先來先列印的順序,有乙個100頁的列印任務,那麼會讓後面短小的任務等待很長時間。更合理的做法也許是最後處理最耗時的列印任務,不管它是不是最後提交上來的。在多使用者作業系統中,作業系統讓哪個程式使用cpu,是需要決定從佇列裡面選擇的。一般做法是從隊頭獲得程式,...