一,兩個重要操作:(1)找出給定元素所屬的集合
(2)合併兩個集合
二,原理:保持一組不相交的動態集合s=。每個集合通過乙個代表來識別,代表即集合中的某個元素
三,操作
(1)make-set(x):建立乙個新的集合,其唯一成員就是x(因各集合是不相交的,故要求x沒有在其他集合**現過)
(2)union(x,y):將包含x和y的動態集合合併為乙個新的集合
(3)find-set(x):返回乙個指標,指向包含x的唯一集合代表
四,不相交集合森林
(1)用有根樹來表示集合,樹中的每個節點都包含集合的乙個成員,每個樹表示乙個集合。
(2)每個成員僅指向其父節點。每個樹的根包含了代表,並且是他自己的父節點。
(3)改進方法:
a)按秩合併:使包含較少節點的樹的根指向包含較多節點樹的根
對每個結點,用秩表示節點高度的乙個上界(即根節點到其某一後代葉子節點的最長路徑上變得數目)
b)路徑壓縮: 是查詢路徑上的每個節點都指向根節點。(簡單,有效)不改變節點的秩。
五,偽**
p[x]表示x的父節點 rank[x]存放x節點的秩
make-set(x) //建立乙個單元素集合,並初始秩為0
p[x]<-x
rank[x]<-0
union(x,y) //合併兩個集合
link(find-set(x),find-set(y))
link(x,y) //按秩合併
if rank[x]>rank[y]
then p[y]<-x
else p[x]<-y
if rank[x]=rank[y]
then rank[y]=rank[y]+1
find-set(x)//find-set是一種兩趟方法:一趟沿查詢路徑上公升直至找到根 另一趟沿查詢路徑下降,以便更新每個節點,使之指向根·
if x!=p[x]
then p[x]<-find-set(p[x])
return p[x]
六用c++語言實現
int pre[maxn];
int rank[maxn];
int findset(int x) //帶路徑壓縮
void link(int x,int y) //按秩的連線演算法
else
}void makeset(int x)
void union(int x,int y)
不相交集合的資料結構 並查集
在介紹操作之前,我得先說說實現這些操作的背景。對於並查集中的每乙個集合,都有乙個代表,這個代表就是集合中的乙個元素,其表示了整個集合。打個比喻吧,最近召開了19大,各個代表都召集到了人民大會堂,假設每個代表都代表著某個省份的人去參加會議,比如我是江西的,江西省的人大代表就代表了江西人民參加會議進行投...
用於不相交集合的資料操作 並查集
假定有一組詞彙,其中有一些詞是同義詞,可以把意思不同的詞分別放到不同的集合中,構成一組不相交的集合,每個集合內部都是同義詞。最開始我們不知到哪些詞可以歸併到相同的組中,因此開始的時候它們每個詞為一組。然後我們再一一給出哪些詞是同義詞,據此將初始的組進行合併 直到最後同義詞都被合併到各自應該歸屬的組裡...
並查集(不相交集合)
早上早早起來看kruscal的mst演算法,原來要用到不相交集合來實現。拿起 演算法導論 看完不相交集合這章,頓然茅塞頓開,終於完成並查集的基礎知識的學習。演算法導論 真是牛 不相交集合有兩種不同的實現,鍊錶表示和帶路徑壓縮的按秩合併策略。看到大家都比較喜歡用帶路徑壓縮的按秩合併策略,那麼我只認真研...