1. 程式人生 > >《演算法筆記》10. 並查集、圖相關演算法、看完這篇不能再說不會了。

《演算法筆記》10. 並查集、圖相關演算法、看完這篇不能再說不會了。

[TOC] # 1 並查集、圖相關演算法 > 轉載註明出處,原始碼地址: https://github.com/Dairongpeng/algorithm-note ,歡迎star ## 1.1 並查集 ### 1.1.1 並查集基本結構和操作 1、有若干個樣本a、b、c、d...型別假設是V 2、在並查集中一開始認為每個樣本都在單獨的集合裡 3、使用者可以在任何時候呼叫如下兩個方法: boolean isSameSet(V x, V y):查詢樣本x和樣本y是否屬於一個集合 void union(V x, V y):把x和y各自所在集合的所有樣本合併成一個集合 4、isSameSet和union方法的代價越低越好,最好O(1) > 思路:isSameSet方法,我們設計為每個元素有一個指向自己的指標,成為代表點。判斷兩個元素是否在一個集合中,分別呼叫這兩個元素的向上指標,兩個元素最上方的指標如果記憶體地址相同,那麼兩個元素在一個集合中,反之不在 > 思路:union方法,例如將a所在的集合和e所在的集合合併成一個大的集合union(a,e)。a的代表點指標是a,e的代表點指標是e,我們拿較小的集合掛在大的集合下面,比如e小,那麼e放在a的下面。連結的方式為小集合e頭結點本來指向自己的代表節點,現在要指向a節點 > 並查集的優化點主要有兩個,一個是合併的時候小的集合掛在大的集合下面,第二個優化是找某節點最上方的代表節點,把沿途節點全部拍平,下次再找該沿途節點,都變為O(1)。兩種優化的目的都是為了更少的遍歷節點。 > 由於我們加入了優化,如果N個節點,我們呼叫findFather越頻繁,我們的時間複雜度越低,因為第一次呼叫我們加入了優化。如果findFather呼叫接近N次或者遠遠超過N次,我們並查集的時間複雜度就是O(1)。該複雜度只需要記住結論,證明無須掌握。該證明從1964年一直研究到1989年,整整25年才得出證明!演算法導論23章,英文版接近50頁的證明。 ```Java package class10; import java.util.HashMap; import java.util.List; import java.util.Stack; public class Code01_UnionFind { // 並查集結構中的節點型別 public static cl