《演算法筆記》10. 並查集、圖相關演算法、看完這篇不能再說不會了。
阿新 • • 發佈:2020-08-06
[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