並查集(不相交集)

並查集一般以樹形結構存儲,多棵樹構成一個森林,每棵樹構成一個集合,樹中的每個節點就是該集合的元素,

找一個代表元素作爲該樹(集合)的祖先。

 

並查集支持以下三種操作:

1、Make_Set(x) 把每一個元素初始化爲一個集合

    初始化後每一個元素的父親節點是它本身,每一個元素的祖先節點也是它本身。

2、Find_Set(x) 查找一個元素所在的集合

    查找一個元素所在的集合,只要找到這個元素所在集合的祖先即可。判斷兩個元素是否屬於同一集合,只要看他們所在集合的祖先是否相同即可。

3、Union(x,y) 合併x,y所在的兩個集合

    合併兩個不相交集合操作很簡單:首先設置一個數組Father[x],表示x的"父親"的編號。那麼,合併兩個不相交集合的方法就是,找到其中一個集       合的祖先,將另外一個集合的祖先指向它。

Union(x,y)

 

並查集的優化

1、Find_Set(x)時 路徑壓縮

尋找祖先時我們一般採用遞歸查找,但是當元素很多亦或是整棵樹變爲一條鏈時,每次Find_Set(x)都是O(n)的複雜度,有沒有辦法減小這個複雜度呢?

答案是肯定的,這就是路徑壓縮,即當我們經過"遞推"找到祖先節點後,"迴歸"的時候順便將它的子孫節點都直接指向祖先,這樣以後再次Find_Set(x)時複雜度就變成O(1)了。

路徑壓縮

 

2、Union(x,y)時 按秩合併

即合併的時候將元素少的集合合併到元素多的集合中,這樣合併之後樹的高度會相對較小。

 

主要代碼實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章