数据结构实现之并查集(使用按秩合并和路径压缩)
2016-01-23 00:35
316 查看
并查集可解决动态连通性问题
网络,判断网络中的两个结点是否相同,连接两个结点,社交网络中的人与人之间是否存在关系
变量名等价性,编程语言中一个对象可以有多个引用,如何判断两个给定的变量名是否等价(即是否引用一个对象)
把所有输入整数看成不同的集合,如何判断两个整数属于同一个集合,并如果归并两个集合
网络,判断网络中的两个结点是否相同,连接两个结点,社交网络中的人与人之间是否存在关系
变量名等价性,编程语言中一个对象可以有多个引用,如何判断两个给定的变量名是否等价(即是否引用一个对象)
把所有输入整数看成不同的集合,如何判断两个整数属于同一个集合,并如果归并两个集合
package xwq.dt; import xwq.util.StdIn; import xwq.util.StdOut; /***************************************************************** **************** 并查集API **************** * UnionFind(int N); 以整数标识(0到N-1)初始化N个触点 * void union(int p,int q);在p和q之间添加一条连接 * int find(int p); p(0到N-1)所在的分量的标识符 * boolean connected(int p,int q);如果p和q存在于同一个分量中则返回true * int count();连通分量的数量 ******************************************************************/ public class UnionFind { private int[] parent;//父链接数组 private int[] rank;//秩数组 private int count;//连通分量个数 //以整数标识(0到N-1)初始化N个触点 public UnionFind(int n) { parent = new int ; rank = new int ; for (int i = 0; i < n; i++) { parent[i] = i; rank[i] = 1; } count = n; } //在p和q之间添加一条连接 public void union(int p, int q) { int fp = find(p), fq = find(q); if (fp == fq) return; //按秩大小合并,将小树的根节点连接到大树的根节点 if (rank[fp] > rank[fq]) { rank[fp]+=rank[fq]; parent[fq] = fp; } else { rank[fq]+=rank[fp]; parent[fp] = fq; } count--; } //p(0到N-1)所在的分量的标识符 public int find(int p) { if (parent[p] != p) parent[p] = find(parent[p]);//使用路径压缩 return parent[p]; } //如果p和q存在于同一个分量中则返回true public boolean connected(int p, int q) { return find(p) == find(q); } //连通分量的数量 public int count() { return count; } public static void main(String[] args) { int N = StdIn.readInt(); UnionFind uf = new UnionFind(N); while (!StdIn.isEmpty()) { int p = StdIn.readInt(); int q = StdIn.readInt(); if (uf.connected(p, q)) continue; uf.union(p, q); StdOut.println(p + " " + q); } StdOut.println(uf.count() + " components"); } }