5.25 訓練日誌

  今天的比賽沒有參加,很是遺憾。今天總結一下並查集
      並查集:(union-find sets)

一種簡單的用途廣泛的集合. 並查集是若干個不相交集合,能夠實現較快的合併和判斷元素所在集合的操作,應用很多,如其求無向圖的連通分量個數等。最完美的應用當屬:實現Kruskar算法求最小生成樹。
並查集的精髓(即它的三種操作,結合實現代碼模板進行理解):
1.Make_Set(x) 把每一個元素初始化爲一個集合
初始化後每一個元素的父親節點是它本身,每一個元素的祖先節點也是它本身(也可以根據情況而變)。
2.Find_Set(x) 查找一個元素所在的集合
查找一個元素所在的集合,其精髓是找到這個元素所在集合的祖先!這個纔是並查集判斷和合並的最終依據。
判斷兩個元素是否屬於同一集合,只要看他們所在集合的祖先是否相同即可。
合併兩個集合,也是使一個集合的祖先成爲另一個集合的祖先。
3.Union(x,y) 合併x,y所在的兩個集合
合併兩個不相交集合操作很簡單:
利用Find_Set找到其中兩個集合的祖先,將一個集合的祖先指向另一個集合的祖先
並查集的優化
1、Find_Set(x)時 路徑壓縮
尋找祖先時我們一般採用遞歸查找,但是當元素很多亦或是整棵樹變爲一條鏈時,每次Find_Set(x)都是O(n)的複雜度,有沒有辦法減小這個複雜度呢?
答案是肯定的,這就是路徑壓縮,即當我們經過"遞推"找到祖先節點後,"回溯"的時候順便將它的子孫節點都直接指向祖先,這樣以後再次Find_Set(x)時複雜度就變成O(1)了,如下圖所示;可見,路徑壓縮方便了以後的查找。
2.Union(x,y)時 按秩合併
即合併的時候將元素少的集合合併到元素多的集合中,這樣合併之後樹的高度會相對較小。

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