資料結構與演算法分析(四) 不相交集

2022-07-19 05:51:15 字數 2591 閱讀 3364

乙個集合s,集合中乙個元素a。a的等價類是s的乙個子集,該子集包含所有與a有關係的元素。

等價類形成是對s的乙個劃分且s中的每乙個成員恰好出現在乙個等價類中。這樣,判斷a與b是否有關係,

只需要判斷a與b是否在乙個等價類中即可。

對於集合s劃分,取任意兩個等價類,si與sj,如果si∩sj = ∅,則稱這些集合不相交。

對於不相交集,有兩種操作,union/find操作。find操作找包含給定元素的集合(等價類)名字。

union把兩個等價類合併成乙個新的等價類。

union(x, y),將x,y合併成乙個新的等價類,且x做為根。

這樣的構造方法,最壞情況下可以構建一課高度為n-1的樹,即union(7,8), union(6,7), union(5,6)……

這使得find操作在n-1次操作下才能找到樹根,執行時間o(n)

將上述森林用陣列表示,約定陣列1-8個元素對應的值代表其父親,例如元素8對應的值為7,表示其父親為7。

而5對應的值為0,表示5本身就是樹根。

這樣找樹根就是乙個遞迴過程,如:find(8), 父親為7, 執行find(7),父親為5,執行find(5),對應值為0,表示5為樹根,遞迴結束,

這樣即找到8所在等價類的樹根為5。判斷6,8是否有關係,即find(8) == find(6)是否成立。

1 typedef int

settype;

2 typedef int

elementtype;

3 typedef int*disjset;

45 disjset initialize(int

num) 6

1314

void

destroy(disjset s)

15

1819

void

union(disjset s, settype root1, settype root2)

20

2324

settype find(disjset s, elementtype x)

25

3132

intmain()

33

view code

為了避免樹的深度過大,可以每次讓深度大的樹做為新根,這樣減少樹深度增加速率。

那麼就需要記住當前根的深度,而由於我們只採用了乙個陣列,所以,可以讓根的值為負值,代表深度。

這樣,根節點的值為-1,表示深度為-1。

對於上述情形,執行union(4,5)。按照之前的union操作,得到結果為:

優化後結果

對應優化後結果的陣列如下:

對於比較深的樹,find操作還是比較耗時的,要一步一步遞迴直至樹根。

改進思路:執行一次find後,讓該路徑上,所有節點直接指向根,而不需要指向父親,這樣下一次查詢的時候能夠快速找到根,節約時間。

執行一次find(8)操作。由於元素8所在樹的樹根為5,所以執行find後,陣列要變成。

這樣,當進行下一次呼叫find(8)的時候,能夠快速找到8對應的樹根。

1

settype find(disjset s, elementtype x)

2

view code

**:

《資料結構與演算法分析》不相交集

前言 回來到學校,今天又要開始苦逼的工作了,後悔回家玩去了,現在想學習時間又不夠了。就是這麼傻 我的github 不相交集 思想 不相交集是解決等價問題的一種有效的資料結構,之所以稱之為有效是因為,這個資料結構簡單 幾行 乙個簡單陣列就可以搞定 快速 每個操作基本上可以在常數平均時間內搞定 首先我們...

資料結構與演算法分析 不相交集類

不相交集類是解決等價問題的一種有效資料結構,實現簡單,很少,速度快。等價關係 對於任意一對元素a,b s,定義關係 使得a b要麼為true要麼為false 1.自反性 對於所有的a s,a a 2.對稱性 a b當且僅當b a 3.傳遞性 若a b且b c則a c 等價類 對於元素a s,等價類是...

資料結構 不相交集ADT

若對於每一對元素 a,b a b屬於s,arb或者為true或者為false,則稱在集合s上定義關係r。如果arb是true,那麼我們說a與b有關係。等價關係是滿足下列三個性質的關係r 自反性 對於所有的a屬於s,ara 對稱性 arb當且僅當bra 傳遞性 若arb且brc,則arc 乙個元素a屬...