您的位置:首页 > 理论基础 > 数据结构算法

数据结构实现之并查集(使用按秩合并和路径压缩)

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");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: