並查集(disjoint set或者union-find set)是一種樹型的資料結構,常用於處理一些不相交集合(disjoint sets)的合併及查詢問題。在使用中常常以森林來表示。
並查集主要有三個操作,分別為:初始化、查詢以及合併。
1.初始化:
包括對所有單個的資料建立乙個單獨的集合(即根據題目的意思自己建立的最多可能有的集合,為下面的合併查詢操作提供操作物件)
在每乙個單個的集合裡面,有三個東西:
1. 集合所代表的資料。
2. 這個集合的層次通常用rank表示(本文**使用按高度合併,rank表示該節點的高度的負數,故初始化時rank都初始化為-1)。
3. 這個集合的類別parent(即代表元素,代表元素相同代表屬於同乙個集合,本文使用根節點元素作為代表元素)。
注意:
2.查詢:
就是找到輸入元素所在集合內的代表元素,用於判斷是否與其他元素屬於等價關係。
優化:為了方便以後查詢,可以使用路徑壓縮的方式進行優化。
路徑壓縮:查詢時,查詢時經過的節點的父節點全部變為根節點,這樣方便以後查詢。並且由於查詢時採用遞迴,故並未增加額外開銷。
3.合併:
將兩個樹進行合併。最簡單的做法是直接讓一棵樹成為另一顆樹的根節點。不過這樣構造出來的樹並不理想,可能形成一條直線的樹。故有按大小合併和按高度合併。
按大小合併是指將較小的樹合併到較大的樹上(大小指樹的大小),使用此種方式在初始化時需要將rank初始化為-1,rank的值為其父節點的位置(非根節點)或該樹的大小的負值(根節點);
* 並查集(不相交集)
*/public
class
disjsets
private disjsetsnode s;//儲存並查集每乙個元素
/** * 構造並查集
**@param t 並查集的元素
*/public
disjsets(string t)
}/**
* 查詢傳入元素的代表元素
**@param element 需要查詢的元素
*@return 返回代表元素 返回為null代表沒有該元素
*/public string find(string element)
return find(index).element;
}/**
* 合併方法
**@param ele1
*@param ele2
*/public
void
union(string ele1, string ele2)
if (root1.element.equals(root2.element))
if (root1.rank < root2.rank) else
if (root1.rank == root2.rank) else
}/**
* 查詢方法(使用路徑壓縮)
**@param x 需要查詢的下標
*@return
*/public disjsetsnode find(int x) else
}/**
* 查詢該元素的下標
**@param element
*@return
*/private
intfindindex(string element) else
}return -1;
}/**
* 測試方法
**@param args
*/public
static
void
main(string args)
system.out.println("操作前的陣列**********");
for (int i = 0; i < is.length; i++)
system.out.println();
disjsets disjsets = new disjsets(is);
system.out.println("並查集內的元素*****");
for (int i = 0; i < is.length; i++)
system.out.println();
system.out.println("並操作之前查詢:" + disjsets.find("170"));
disjsets.union("10", "20");
disjsets.union("30", "40");
disjsets.union("10", "30");
disjsets.union("50", "60");
disjsets.union("70", "80");
disjsets.union("50", "80");
disjsets.union("60", "10");
disjsets.union("110", "120");
disjsets.union("130", "140");
disjsets.union("110", "130");
disjsets.union("150", "160");
disjsets.union("170", "180");
disjsets.union("150", "180");
disjsets.union("160", "110");
disjsets.union("10", "110");
system.out.println("並操作之後查詢:" + disjsets.find("170"));
system.out.println("並查集內的元素*****");
for (int i = 0; i < is.length; i++)
system.out.println();
disjsets.find("180");
system.out.println("路徑壓縮查詢之後查詢:" + disjsets.find("170"));
system.out.println("並查集內的元素*****");
for (int i = 0; i < is.length; i++)
system.out.println();}}
並查集(不相交集合)
早上早早起來看kruscal的mst演算法,原來要用到不相交集合來實現。拿起 演算法導論 看完不相交集合這章,頓然茅塞頓開,終於完成並查集的基礎知識的學習。演算法導論 真是牛 不相交集合有兩種不同的實現,鍊錶表示和帶路徑壓縮的按秩合併策略。看到大家都比較喜歡用帶路徑壓縮的按秩合併策略,那麼我只認真研...
並查集(不相交集)ADT
等價關係 需要同時滿足下列三個性質的關係r 等價集合 如果乙個元素a 屬於集合s,則元素a的等價集合是集合s的乙個子集,它包含所有與元素a有等價關係的元素。輸入資料最初是n個元素 元素也是乙個集合 的集合,其中每個集合只含有乙個元素,且互不相同,也不存在等價關係,使得這些集合互不相交,此時只能進行兩...
資料結構 9 並查集(不相交集)
並查集 disjoint sets 直譯即不相交集。離散數學中對等價關係的定義 滿足自反性 對稱性和傳遞性的關係。集合a,a,b a,b a,滿足arb,則稱r為a上的關係,若r滿足以上三種性質,則為等價關係。數學上的定義不必過多解釋,只需知道,等價關係是用來對集合中的元素分類,以達到簡化問題的目的...