JAVA数据结构之并查集「最终版」

潇汀 2018-08-29

用树实现的并查集

接口

public interface UF{

int getSize();

boolean isConnected(int p,int q);

void unionElements(int p,int q);

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

public class UnionFindV6 implements UF{

//孩子指向父亲

private int[] parent;//parent[i] 表示的第i个元素指向的父节点

private int[] rank;//sz[i]表示以i为根的集合中元素的个数

/**

* 构造函数

*/

public UnionFindV6 (int size) {

parent = new int[size];

rank = new int[size];

for (int i = 0; i < size; i++) {

parent[i] = i;//初始的时候,每一个节点都指向它自己

rank[i] = 1;

}

}

@Override

public int getSize() {

return parent.length;

}

//查找过程,查找元素p所对应的的集合编号

//O(h)复杂度,h为树的高度

//这里用递归,需要返回值的 int

//最后树只有两层

private int find(int p) {

if (p < 0 && p >= parent.length) {

throw new IllegalArgumentException("p is out of bound");

}

//****路径压缩

if (p != parent[p]) {//判断是否是根节点

//直接挂接到根节点

parent[p] = find(parent[p]);

}

return parent[p];

}

@Override

public boolean isConnected(int p, int q) {

return find(p) == find(q);

}

@Override

public void unionElements(int p, int q) {

int pRoot = find(p);

int qRoot = find(q);

if (pRoot == qRoot) {

return;

}

// 根据两个元素所在数的rank不同判断合并方向 【这里的rank指深度】

// 将rank低的集合合并到rank高的集合上

if (rank[pRoot] < rank[qRoot]) {

parent[pRoot] = qRoot;

} else if (rank[pRoot] > rank[qRoot]) {

parent[qRoot] = pRoot;

} else {//rank[pRoot] == rank[qRoot]

parent[qRoot] = pRoot;

rank[pRoot] += 1;

}

}

}

JAVA数据结构之并查集「最终版」

相关推荐