並查集學習(2)

2021-04-29 04:22:17 字數 592 閱讀 7379

實現這個資料結構主要有三個函式:如下:

void ufset()   //初始化

return i;

}void union(int r1,int r2)   //將兩個不同集合的元素進行合併,使兩個集合中任兩個元素都連通

else

}在find函式中如果僅僅靠乙個迴圈來直接得到節點的所屬集合根結點的話。通過多次的union操作就會有很多節點在樹的比較深層次中,再find起來就會很費時。通過加乙個while迴圈(壓縮路徑)每次都把從i到集合根結點的路過結點的雙親直接設為集合的根結點。雖然這增加了時間,但以後的find會快。平均效能而言,這是個高效方法。

兩個集合並時,任一方可做為另一方的孩子。怎樣來處理呢,現在一般採用加權合併,把兩個集合中元素個數少的做為個數多的孩子。有什麼優勢呢?直觀上看,可以減少集合樹的深層元素的個數,減少find時間。

如從0開始到n不斷合併i和i+1結點會怎樣呢?

這樣find任一節點所屬集合的時間複雜度幾乎都是o(1)!!

不用加權規則就會得到

這就是典型的退化樹現象,再find起來就會很費時(如找n-1節點看看)。

以下是讀入等價對後的parent[n]查詢合併過程狀態:

並查集學習筆記2

第一是鍊錶表示的並查集的加權合併的啟發式策略,說白了就是維護乙個表長資訊,在合併兩個集合時將表長短的鍊錶鏈結到表長長的鍊錶上面。以此來減少修改指向代表的指標的次數,從而提高時間複雜度。第二就是森林表示的三種優化策略。優化的思想就是儘量減少找根的時間,盡量降低樹的高度。第乙個策略就是 按秩合併 維護乙...

並查集 學習

yx th000 cherish yimi 昨天和今天學習了並查集和 trie 樹,並練習了三道入門題目,理解更為深刻,覺得有必要總結一下,這其中的內容定義之類的是取自網路,操作的說明解釋及程式的注釋部分為個人理解。並查集學習 l 並查集 union find sets 一種簡單的用途廣泛的集合.並...

並查集 並查集

本文參考了 挑戰程式設計競賽 和jennica的github題解 陣列版 int parent max n int rank max n void init int n int find int x else void union int x,int y else 結構體版 struct node ...