并查集1

并查集:主要用来判断两个数据是否在同一组,并能对两个不同的树进行合并成一组的一种数据结构

其实现的核心方式就是:两个在同一组的节点有着相同的祖先节点。

 

代码实现及解析:

 1 public class UnionFind {
 2     public int[] fa;//用来存储每个节点的祖先(相同组的成员具有相同的祖先)
 3     public int[] rank;//用来记录当前节点所在的层级(用于优化)
 4     
 5     public UnionFind(int n) {//将具有n个结点的并查集初始化
 6         fa = new int[n];
 7         for (int i = 0; i < n; i++) {
 8             this.fa[i] = i;//初始状态下并查集的祖先即为自己
 9             this.rank[i] = 1;//刚开始都在第一层
10         }
11     }
12     
13     public int find(int p) {//查找结点p的祖先(所在组别)
14         if (fa[p] != p) {
15             fa[p] = find(fa[p]);//直接把它的父亲调整为祖先节点
16         }
17         return fa[p];
18     }
19     
20     public boolean union(int a,int b) {//将a和b数据合并为一组
21         int rootA = find(a), rootB = find(b);
22         if (rootA == rootB) {//a,b已在同一组,无需合并
23             return false;
24         }
25         if (rank[rootA] >= rank[rootB]) {//谁在更高层就让谁做父节点
26             fa[rootB] = rootA;
27             if (rank[rootA] == rank[rootB]) {
28                 rank[rootA]++;//因为A做父亲,所以要让他等级比B高
29             }
30         }
31         else {
32             fa[rootA] = rootB;
33         }
34         return true;//表示成功执行合并操作(两个数据原先不在同一组)
35     }
36     
37     public boolean isSame(int a,int b) {//判断两者是否在同一个集合
38         return find(a) == find(b);
39     }
40 }

 

特殊结构的并查集实现(非整型数)

此处用图的点来进行举例(用于Kruskal算法)

 1 public class UnionFind {
 2         public HashMap<Node,Node> fatherMap;//记录边的父亲(所在分组)
 3         public HashMap<Node,Integer> rankMap;//记录边所在的层级
 4         
 5         public UnionFind(Graph g) {
 6             for (Node node : g.nodeis) {
 7                 fatherMap.put(node, node);//一开始把自己做为祖先
 8                 rankMap.put(node, 1);
 9             }
10         }
11         
12         public Node find(Node e) {
13             if (e != fatherMap.get(e)) {
14                 fatherMap.put(e, find(e));
15             }
16             return fatherMap.get(e);
17         }
18         
19         public boolean Union(Node a,Node b) {
20             Node rootA = find(a);
21             Node rootB = find(b);
22             if (rootA == rootB) {
23                 return false;
24             }
25             if (rankMap.get(rootA) < rankMap.get(rootB)) {
26                 fatherMap.put(a, rootB);
27             }
28             else {
29                 fatherMap.put(b, rootA);
30                 if (rankMap.get(rootA) == rankMap.get(rootB)) {
31                     rankMap.put(rootA, rankMap.get(rootA) + 1);
32                 }
33             }
34             return true;
35         }
36         
37         public boolean isSame(Node a,Node b) {
38             return find(a) == find(b);
39         }
40     }

 

posted @ 2022-04-17 19:52  jue1e0  阅读(42)  评论(0)    收藏  举报