你們好,今天提供不相交集合的筆記(即union/find). 不相交集合有實現簡單,證實困難的特色,如有想證實的能夠自行查閱相關文獻。我就不作贅述啦!java
不相交集類解決動態等價類問題,即:git
數據結構須要良好支持union和find操做,union操做相對簡單,咱們關注find操做。github
find操做只要求當且僅當兩個元素屬於同一個集合時,做用在這兩個元素上的find返回相同的集合名稱。 由此天然想到樹: 由於樹的每個元素都有相同的根,因此等價類能夠用樹表示,不相交集則以森林表示。樹的根存儲集合名稱。 依照上述假設: find操做實質從指定節點向上找到根,因此只須要保存父鏈算法
因爲只需保存父鏈,不相交集類(森林)中的等價類(樹)能夠被非顯示的存儲在數組中,數組中元素有以下約定:數組
下圖是隱示的森林示意圖,上邊是隱示森林數組,下邊是依據該數組展示實際的森林。 數據結構
任意合併會出現過深的樹,因此採用按秩求並,它保證樹的深度不超過O(logN)3d
/** * 採用按秩求並 * @param root1 不相交集合1的根 * @param root2 不相交集合2的根 */ public void union(int root1, int root2) { if(s[root2]<s[root1]){ s[root1]=root2; }else{ if(s[root1]==s[root2]){ s[root1]--; } s[root2]=root1; } }
不進行路徑壓縮,M次操做,容易出現最差狀況O(MlogN),其中N爲節點個數code
/** * 查找方式 :路徑壓縮 * @param x 要尋找的元素 * @return x屬於的集合 */ public int find(int x) { if (s[x] < 0) { return x; } else { return s[x] = find(s[x]); } }
M次union和find的運行時間爲:blog
O(Mlog*N)
什麼你以爲太簡單了,建議你試着證實! 什麼代碼沒有難度,能夠實現各迷宮試試啊!get