可並堆 左偏樹實現

2021-10-08 02:47:49 字數 1495 閱讀 9372

堆是優先佇列的一種實現方式,堆中父節點大於等於(或小於等於)兩子節點,每次的刪除,查詢,插入都是 o(l

og2n

)o(log_2n)

o(log2

​n) 的複雜度

左兒子的dis值大於等於右兒子的dis值

- 定義結束,我們可能要問如何建一棵左偏樹?這裡我要說,左偏樹和傳統的堆不同,沒有pushup操作,左偏樹唯一的操作就是合併merge。 >也就是說,我們建立左偏樹,是將每個節點都看成一棵左偏樹,然後一步一步合併起來的,所以我們要先明確什麼是合併操作。對左偏樹最核心的合併操作,是這樣的(假設數越小優先順序越大):

如此遞迴操作即可在 o(l

og2(

m+n)

)o(log_2(m + n))

o(log2

​(m+

n)) 內完成兩個左偏樹的合併

其他操作建立在合併之上,下面是常見的幾種。

模板題 洛谷p3377

**:

#include

#include

#include

#include

using

namespace std;

int n, m;

struct ab

aa[200005];

voidsw(

int& a,

int& b)

bool bk[

100005]=

;int

merge

(int x,

int y)if(

!y)if

(aa[x]

.v > aa[y]

.v ||

(aa[x]

.v == aa[y]

.v && x > y)

) aa[x]

.rs =

merge

(aa[x]

.rs, y)

; aa[aa[x]

.rs]

.fa = x;

if(aa[x]

.ls)

if(aa[aa[x]

.ls]

.dis < aa[aa[x]

.rs]

.dis)if(

!aa[x]

.rs)

else

return x;

}intmn(

int x)

return aa[x]

.fa;

}int

main()

for(

int i =

1; i <= m;

++i)

merge(mn

(xx),mn

(yy));

}else

else}}

return0;

}

總之,沒有完美的資料結構。但左偏樹確實好寫,不想用堆了(直接用平板電視更容易)

左偏樹(可並堆)

左偏樹其實是一種可並堆,它可以 o log2 n o l og2n 合併兩個堆。那左偏?也就是說他左邊肯定有什麼東西比右邊大 別著急,在左偏樹上有乙個叫距離的東西 個點的距離,被定義為它子樹中離他最近的外節點到這個節點的距離 這與樹的深度不同 其中我們定義乙個節點為外節點,當且僅當這個節點的左子樹和...

可並堆 左偏樹

題目描述 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 ...

可並堆 左偏樹 斜堆

經典的二叉堆已經可以在 o log n 的複雜度的情況下維護堆這樣的資料結構,也有d 堆可以維護成 o log d n 雖然pop操作的複雜度是 o d log d n 然而這兩種堆不能滿足 o log n 的合併操作,它們的經常是 o n log n 即每次將乙個堆中的堆頂拿出來放到另乙個堆裡。雖...