最近總有新手要問堆怎麼寫,我是這麼想的
既然都學c++了,堆這種東西怎麼能手寫呢,太對不起stl了
(當然能手寫的都是的大神了,這只是我懶得手打的理由)
正好之前機房有位大神將他學習的堆教給了我
我就以他講的寫一篇blog來幫助其他人吧
這裡先介紹一下vector
vector是乙個動態陣列
當你需要多少空間時就會自動分配多少空間給你
極大的省了許多空間(通常我是拿來存圖的),宣告方法如下
先加標頭檔案 #include
宣告: vector《引數》 變數名 然後要什麼型別就在引數裡寫什麼型別
這裡我們只需要用int就行
vector a
這樣我們就有乙個可以存放數字的動態陣列a了,
接著學習幾個基本操作
加入資料 : a.push_back(num)
刪除最後乙個資料 : a.pop_back()
隊尾+1的位置 : a.end() 注意:a.end()是乙個迭代器,我也不知道是什麼,反正只要減去陣列的名字就可以得到末尾往後的位置的下標
隊首的位置 : a.begin() 這也是乙個迭代器
然後就是開始了
用for迴圈讀入資料
1 2
3 4
5 6
for(int i=1;i<=n;i++)
然後開始建堆
用algorithm中的三個函式就可以搞定了
先加#include
裡面有乙個函式為make_heap()
現在我們要把a陣列變為乙個堆,就這麼寫
1 make_heap(a.begin(),a.end(),cmp)
注意,cmp是自己新增的乙個函式,返回值應該是bool
而這裡的cmp很特殊
小根堆的cmp是這麼寫的
1 2
3 4
bool cmp(int x,int y)
注意,我並沒有寫錯,就是大於號,所以才說它特殊
往後如果再推入元素需要進行維護
如果建堆的時候寫了cmp這個引數,那每次都要再傳入一遍
再推入的時候是這樣的
先加入a陣列裡
a.push_back(num)
再用乙個函式維護一下
push_heap(a.begin(),b.end(),cmp)
此時,a這個動態陣列又變成堆了
而堆我們通常是取第乙個元素,而vector的第乙個元素和陣列一樣
直接取a[0]即可
取完a[0]以後,你可能要刪掉這個堆頂的元素
刪除剛好和加入相反
同樣有乙個函式是用來刪除堆的元素的
pop_heap(a.begin(),a.end(),cmp)
注意這裡還沒完,它的功能只是將第乙個元素放到最後,然後忽略最後乙個元素的情況下再維護一遍堆
所以我們還得用a.pop_back()把最後乙個元素推掉
這樣堆的建立插入和刪除操作就講完了
#include
#include
#include
#include
bool cmp(int x,int y)
int main()
make_heap(a.begin(),a.end(),cmp);
scanf("%d",&num);
a.push_back(num);
push_heap(a.begin(),a.end(),cmp);
cout
<0]0; }
也可以用priority_queue來建;
大根堆:priority_queue heap
小根堆:priority_queue
STL中的堆操作
堆在我們做演算法時應該有映像吧,分為大根堆,小根堆。stl中的其實是對堆有實現的,使得我們可以直接拿來用。相關的函式是make heap push heap pop heap sort heap make heap make heap first,end,cmp 引數有3個,第乙個為堆建立堆的第乙個...
c 的STL中堆的運用
stl中的建立的隊預設是最大堆,要想用最小堆的話,必須要在push heap,pop heap,make heap等每乙個函式後面加第三個引數greater 括號不能省略 make heap first,last,comp 預設是建立最大堆的。對int型別,可以在第三個引數傳入greater 得到最...
建立二叉堆 STL練習
算是對stl的一道練習題 思想 1.建立向量a,輸入測試資料 2.基於陣列下標,判斷當前堆頂是否已滿足要求 code include include include include using namespace std 傳入陣列a和下標i,i的左右子樹都滿足最大堆的性質,函式將a整體調整為最大堆 ...