路徑壓縮優化並查集的時間複雜度

2021-09-09 05:15:57 字數 1760 閱讀 9653

路徑壓縮優化並查集大家一定很熟練了,那麼它的複雜度是多少呢?o(m

α(n)

)o(m\alpha(n))

o(mα(n

))?的確,很多人都是這麼說的,但是事實上它的複雜度是o(m

log⁡1+

m/nn

)o(m\log_n)

o(mlog1+

m/n​

n)的,並且能找到一種方法卡到這樣的複雜度。

要卡並查集,首先要構造一種樹——二項樹。這種二項樹還與普通的不太一樣。

定義:在給定j

jj的情況下,二項樹t

kt_k

tk​定義如下:

這棵樹非常有意思,我們可以展開tk−

jt_tk−j

​,接著展開tk−

2jt_tk

−2j​

……另外,也可以展開tk−

1t_tk−1

​,接著展開tk−

容易發現,圖5看起來像圖4的路徑壓縮之後的結果,但是不完全一樣。

如果首先按照圖5的方式展開j

jj棵子樹,再按圖4展開,可以得到

此時,如果在根節點上再加乙個點,j

jj次訪問t

1t_1

t1​到t

jt_j

tj​,那麼路徑壓縮後可以得到圖5外加乙個點作為根的兒子。

也就是說,這棵二項樹路徑壓縮後約等於沒有路徑壓縮……只是將原來作為根結點父親的那個點變成了兒子。

至於t

kt_k

tk​的點數,通過數學歸納法可以發現不會超過(j+

1)k/

j−1(j+1)^

(j+1)k

/j−1

個。假設m≥n

m\geq n

m≥n,令j=m

n,i=

log⁡j+

1n2+

1,k=

ijj=\frac,i=\log_\frac+1,k=ij

j=nm​,

i=logj+1

​2n​

+1,k

=ij,那麼t

kt_k

tk​的點數不超過n

2\frac

2n​。接下來做n

2\frac

2n​組操作,每次加入乙個點作為根結點的父親,然後對t

1t_1

t1​到t

jt_j

tj​逐個查詢,每次查詢的長度是i+1

i+1i+

1,同時查詢的次數顯然不超過m

mm。因此總操作次數為n2j

(i+1

)\fracj(i+1)

2n​j(i

+1),即o(m

log⁡1+

m/nn

)o(m\log_n)

o(mlog1+

m/n​

n)。取自**計畫#4 快速構造支配樹的lengauer-tarjan演算法。

路徑壓縮 並查集路徑壓縮

如何描述乙個複雜的連線關係?如圖,很容易判斷緊鄰的2個人關係,但中間的連線很多很亂,怎麼判斷出兩個人的關係呢?並查集就是一種結構,通過儲存節點以及節點上的標籤,來判斷這兩個節點是否連線在一起。當兩個節點繫結時,可以任選其中乙個節點的標籤,指定另乙個節點。當判斷兩個節點是不是連線時,可以上溯節點的祖宗...

並查集 壓縮路徑

並查集 union findsets 一種簡單的用途廣泛的集合.並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數等。最完美的應用當屬 實現kruskar演算法求最小生成樹。並查集的精髓 即它的三種操作,結合實現 模板進行理解 1 make s...

並查集路徑壓縮

使用並查集查詢時,如果查詢次數很多,那麼使用樸素版的查詢方式肯定要超時。比如,有一百萬個元素,每次都從第一百萬個開始找,這樣一次運算就是10 6,如果程式要求查詢個一千萬次,這樣下來就是10 13,肯定要出問題的。這是樸素查詢的 適合資料量不大的情況 int findx int x 下面是採用路徑壓...