堆
簡單來說堆就是維護乙個資料集合,堆的實質是乙個二叉樹;
堆的性質:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆。
附上圖 嘿嘿~:
今天我們說的小頂堆的堆排列介個問題(我才不會告訴你們我只學了小頂堆~小聲bb)~~
(這裡說一下,因為我們這次是手寫堆的教程,跟stl中堆有所不同,4、5操作在stl中是無法完成的,,,還有就是儲存問題
stl中堆是使用優先佇列進行儲存;
手寫堆是使用乙個一維陣列進行儲存;(嗯,對的 ,乙個一維陣列;)
(一般為了方便會把根節點記為1而不是0)
在陣列中儲存的位置一般就是,第乙個為根節點,接下來是根節點的左兒子,,,
(簡單來說就是我們第x位置存放根節點的話
它的左兒子為 第2x個位置;
右兒子 第2x+1個位置;
)主要就是兩個操作down(x)還有up(x)
所謂 down(x);
就是從上到下進行處理;
舉個栗子~~
若將 1處位置—>4改為10
此時與堆的性質不符,將1處與其左右兒子相比較,找出最小值,交換兩處位置,(因為堆頂為最小值)
同理與2處與其左右兒子相比較,,最總結果為:
同理up(x)操作為從下到上搜尋
例如
將5處9改為—>2;
(與down不同,up只與其父節點比較,,,)
2<8 將3處與5處交換
繼續向上搜尋 2<4 交換1處與3處
結束;
// h[n]儲存堆中的值, h[1]是堆頂,x的左兒子是2x, 右兒子是2x + 1
// ph[k]儲存第k個插入的點在堆中的位置
// hp[k]儲存堆中下標是k的點是第幾個插入的
int h[n]
, ph[n]
, hp[n]
, size;
// 交換兩個點,及其對映關係
void
heap_swap
(int a,
int b)
void
down
(int u)
}voidup(
int u)
}// o(n)建堆
for(
int i = n /
2; i; i --
)down
(i);
好,接下來我們康康主要問題
主要包括以下5個問題
1.插入乙個數x;
插入乙個數從末尾插入:
h[
++size]
=x;
2.求集合中的最小值最小值就是根節點
h[
1]
3.刪除最小值刪除事就是用最末尾元素覆蓋第乙個然後down
h[1]
=h[size]
;size--
;down(1
);
4.刪除任意乙個元素(刪除第x個)刪除也是用末尾元素覆蓋這個元素,,但這個元素需要判斷,,這裡有個簡單的辦法就是down 與up都操作一次,,,主意在執行的時候只會選擇其一
h[x]
=h[size]
;size--
;down
(x);
up(x)
;
5.修改任意乙個元素(第x個改為xx)與第四個差不多;
h[x]
=xx;
down
(x);
up(x)
;
就介個樣子吧
貼個題;
堆排序ac**
#include
#include
using
namespace std;
const
int n=
1e5+6;
int h[n]
;int n,m;
int siz;
void
down
(int u)
}int
main()
return0;
}
第一次寫多多包涵大家都不容易
哦了,拜拜~~
堆的基本操作 手寫模擬堆
解析 這個題比較麻煩的一點就是k。第k個插入的數,不是樹里的序號。經過一系列變換後,第k個插入的數在樹里的序號會發生交換。所以引入兩個陣列 ph i x 表示第i次插入的數,在樹中的序號為x。hp i x 表示樹中的序號i,是第x次插入的數。乍一看,hp似乎並沒有什麼用,每次交換h和ph即可了。別急...
優先佇列 (乾掉手寫堆 嗚嗚嗚 )
優先佇列中的元素會按某種優先順序依次出佇列,即可實現按此優先順序排序,時間複雜度和堆排序差不多 1.priority queueq 預設優先順序從到大到小 priority queue,greater q 優先順序從小到大 2.除此之外我們還可以選擇過載運算子 用於結構體 無法直接定義 includ...
堆排(大頂堆,小頂堆)
分類 資料結構 演算法相關 2009 10 15 12 26 2289人閱讀收藏 舉報汗,別人都說大小頂堆只是改改大於號的問題,可我的 從大頂堆只改動大於號調整為小頂堆竟然越界樂,掣肘!後來幾經更改才發現是傳參的問題 見 看來大頂堆改小頂堆不是 亦或是我rp出點問題?搞笑的是 磚頭 c b 竟然對越...