并查集说白了就是找边缘值去连接,按着我的思路来走,就是一步一步去连起来
-------------------------------------------------------------------------------------------------------------------------------
现在我们拥有一些点,我们把这些点存储到一个数组中
事先声明 : 这个数组存的是每个数的父结点(注意!!不是根)
第一步:
我们规定一开始每个结点的父亲都是他自己,写一个函数init(),来初始化
第二步:
连接函数union,我们在连接两个点之前需要明白,我们是要怎么连接:
如果两个结点的根结点不一样,那么我们就需要去连接,否则不需要
(其实这个画图更好理解)
一开始1的根是1,2的根是2,两个结点根不同,相连接,那么2的根就变成了1
再拿<1,2> 去跟 3 的根比,不同,连接......
第三步:
那么我们的问题来了,如果我的<1,2>已经连起来了,我们拿2去跟3比,我们需要找到2的根,所以我们需要一个函数find,来负责找到当前结点的根,(典型的递归问题)
根节点的父就是根
public static int find(int num){
if(set[num] == num)
return num;
return find(set[num]);
}
public class 并查集 {
public static void main(String[] args) {
}
static int[] set = new int[8];
//初始化,每个结点的父都是自己
static void init() {
for(int i = 0 ;i<set.length;i++) {
set[i] = i;
}
}
//连接
static void union(int a , int b) {
//如果两个结点的根相等,则不用再连接
if(find(a) == find(b)) {
return;
}
//证明两个结点的根不相等
//我们需要把这两个结点连接起来
set[find(a)] = find(b);
}
static int find(int num) {
//到了传入的结点的最后的根的父是自己,则证明这个位置(动态变化的num)为该位置(初始的num)的根节点
if(set[num] == num)
return num;
return find(set[num]);
}
}