不相交ADT的基本資料結構

2021-10-05 22:39:31 字數 3254 閱讀 3047

由於該系列文章標題為資料結構,故書中的第七章排序就不再此分析了。直接跳到第八章的不相交adt:這種資料結構實現例程僅需要幾行**。

1、等價關係。

在集合s上定義運算r(relation),對於a, b∈s,運算arb返回型別為布林型變數,即僅有 true 和 false 。當arb = true 時,則稱a、b有關係。

對於定義的該運算,有三條性質:(其中 arb 則直接代表 arb = true)

1、自反性:對所有的a∈s,均有ara;

2、對稱性:arb的充要條件為bra。

3、傳遞性:若arb, brc,則arc。

例:抽象的運算: 電氣連線(electrical connectivity)是等價關係,其中的所有連線通過金屬導線完成。

2、動態等價性問題。

假設存在一種等價關係運算子 ~ 滿足上文的等價關係,則會出現問題:對任意 a 、b,是否 a~b。

解決問題的方法是宣告乙個二維布林陣列,類似於**,其儲存著每兩個元素之間 ~ 關係。但是這種方法有著定義不明顯且隱秘的缺點。

因此,出現了第二種解決問題的方法:鑑於滿足等價關係 ~ 的元素有 傳遞性的性質, 那麼對於 arb , arc,則能推出brc。這一點是十分重要的,由於這個性質,在s中所有能夠與 a 等價的元素均可以被規劃在一起,形成乙個等價類( equivalence class) ,即在這個等價類中,所有的元素均等價,而在這個類外的元素均不與該類中的元素等價。

則問題 a與b是否等價就變成了a與b是否在同乙個等價類中。

分析輸入資料最初是由 n 個集合(數學術語)組成的集合(將這些若干小集合放在一起,原文為 collection)時的問題。在前提每個集合含有乙個元素,而同時這些小集合的元素之間關係均為 false ,則會得到si∩sj =ø,其中si和sj分別代表不同的小集合。 進一步分析則會得到這些集合不相交(disjoint)的結果。 

對於這些集合,存在著兩種運算:

find: 返回包含給定元素的類;

新增關係 a~b:在新增之前,先通過find a 和find b,並且判斷二者是否已經處於乙個等價類中。若處於則不進行操作,相反。則進行union操作。

union操作:把含有 a 和 b 的兩個等價類合併為乙個新的等價類。即新建立乙個集合sk = si∪sj 並刪除掉原來的集合 si 和 sj。

這項工作被稱作 :union / find 演算法。以下對該演算法做一介紹。

由於無論是大集合還是小集合,都可能因為union演算法發生改變,因此演算法是動態的(dynamic)

同時,這個演算法也是聯機的(on-line)。因為當find執行時給出答案才能進行union操作。

在此,再說明一種離線(off-line)演算法,以便於區分:該演算法(離線)觀察所有的union和find序列。它對每個find給出的答案必須和所有執行到該find例程的union一致。答案就相當於演算法返回的結果,即在執行該演算法後新得到的大集合。

由上面的操作,可以注意到:我們不會進行元素的值的比較,而只會知道其所在的等價類的名字。而對於僅當兩個元素屬於同乙個等價類的情況下,作用在這兩個元素的find例程會返回相同的名字:即尋找a、b兩個元素所屬的等價類,則a、b屬於同乙個等價類的情況下,有:find(a) =find(b)。

解決動態等價問題有兩種方法:

一(這種方法能夠讓find例程最壞以常數執行時間執行)、

首先,在乙個陣列中儲存每乙個等價類的名字,此時find就是簡單的o(1)查詢。然而,對於union(a,b)則不會那麼簡單:假設 a 在等價類 i 中而 b 在等價類 j 中。然後掃瞄該陣列,將所有的 i 變為 j 。其中掃瞄花費時間 θ(n)的時間,其中n為所有元素的數量。在最壞的情況下,即所有的元素中包含兩個類,其中n-1個元素在等價類i中,另外乙個在 j 中,那麼則會連續進行n-1次union操作。花費的時間就為θ(n²)。若存在ω(n²)次find運算,則效能會很好,反之則所耗時間特別多。

二、將同乙個等價類中的元素放在同乙個鍊錶中。

3、基本資料結構

現在討論用 樹 的形式實現該不相交adt,則每一棵樹則能表達乙個等價類,同時用樹的集合,即森林儲存不同的等價類。而集合的名字則由根處的節點給出。同時,類似於鍊錶的游標實現,我們也將此處的樹儲存在陣列中,並有:陣列中的每個成員p[ i ] 表示儲存的元素為 i 的父親。

下圖給出了較為形象的例子。(來自:

但應當注意的是:下圖中根節點儲存的是樹的深度。除了根之外,其他節點儲存的其父親的陣列下標。

因為圖中給出的是一種更為高階的方法,並不符合當前基本資料結構的描述。因此我們先假設根節點並沒有儲存樹的深度,並對其進行簡單的實現。

先考慮 find 例程:對於特定元素x的find例程,find(x)返回包含樹的根而完成,這表示find例程執行的時間與x節點的深度成正比。

再考慮union 例程:union(a,b)合併兩棵樹,在例程中通過將乙個接待你的根指向另一棵樹的根節點來完成。

以下為c語言實現:、

#define numsets 100

typedef int disjset[numsets + 1];

typedef int settype;

typedef int elementtype;

/*disjset 是 the disjoint set 即 不相交adt 的英文縮寫

settype是根節點的陣列下標,而elementtype可以代表所有元素的陣列下標,即settype屬於elementtype

注意: 對於元素(或者稱作陣列下標)x,s[x]儲存著它的父親的元素(或者說父親的下標)

即我們可以把s[x]在此處看作求父節點下標的運算

*/void initialize(disjset s)

void setunion(disjset s, settype root1, settype root2)

settype find(elementtype x, disjset s)

使用不相交adt時,時刻要弄清楚陣列下標和陣列下標儲存的元素之間的關係,千萬不要混淆概念。

即:對於元素,或者陣列下標x,s[x]儲存的是其父節點的陣列下標,或者當x為根節點時,儲存的是0。

資料結構 不相交集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屬...

不相交資料結構

摘要 1 不相交資料結構是一種非常有用的資料結構,它類似於一種集合,高效的支援某兩個元素是否在同乙個元素中的查詢操作,也支援合併兩個集合,在集合中刪除某個元素等操作.基本資料結構 不相交資料結構常用的一種形式是由樹的構成的.樹被儲存在乙個陣列中 非顯式的儲存 集合的名字由樹的根給出.假如該陣列元素的...

不相交集合ADT 資料結構(C語言實現)

讀資料結構與演算法分析 等價關係 滿足三個性質 基本資料結構 基本思路 使用乙個陣列,下標表示該集合,內容表示指向的父親實現 型別宣告 typedef int disjset numsets 1 typedef int settype typedef int elementstype void in...