并查集是集合的一种,它只有两种方法,合并和查找。
合并就是把两个元素所在的集合合并为一个。
查找就是查找某元素所属的集合。
一般并查集用树的父指针数组来存储实现。根节点数组值为负数,负几表示该集合有几个元素。
元素和集合名称对应数组索引。从属关系对应相应数组值。数组值为负数,表示对应索引为树的根,也就是集合名。
初始状态下所有元素都是一颗单独的树,也就是说所有数组值都初始化为-1.
某种意义上并查集的数组实现也可看成一种散列。
由于并查集只有两种操作,所以重要的不是元素之间的父子关系,而是元素的从属关系。
所以最优并查树的深度应为2。一般优化并查树,也是往这个方向优化。
并查树合并O(1), 查找O(logn)。
并查集是划分等价类的最佳选择。
下面给出代码实现:
package com.company;
/**
* UnionFindSet is a set to tackle only Union and Find operations in set.
* Created by qiguo on 2017/3/21.
*/
public class MyUnionFindSet {
private int[] array;
private int storageSize;
public MyUnionFindSet(){
this.storageSize = 10;
this.array = new int[this.storageSize];
for (int i = 0; i < this.storageSize; i++) {
array[i] = -1;
}
}
/**
* merge two element into one set
* @param s1 element s1
* @param s2 element s2
* @return union set element num
*/
public int union(int s1, int s2){
int set1 = find(s1);
int set2 = find(s2);
if (set1 == set2){
return -1;
}
if (array[set1] <= array[set2]){
array[set1] += array[set2];
array[set2] = set1;
return array[set1];
}else {
array[set2] += array[set1];
array[set1] = set2;
return array[set2];
}
}
/**
* find the set that element belongs to
* @param element
* @return set number
*/
public int find(int element){
int tmp = element;
while (array[tmp] > 0){
tmp = array[tmp];
}
return tmp;
}
/**
* collapse the branch while find, to optimize the structure of the tree.
* @param element
* @return the set number that element belongs to
*/
public int collapsingFind(int element){
int tmp = element;
while (array[tmp] > 0){
tmp = array[tmp];
}
while (array[element] > 0){
int parent = array[element];
array[element] = tmp;
element = parent;
}
return tmp;
}
public void print(){
for (int element: array) {
System.out.printf(element + " ");
}
System.out.println();
}
public static void main(String[] args){
MyUnionFindSet myUnionFindSet = new MyUnionFindSet();
myUnionFindSet.union(1,2);
myUnionFindSet.union(2,3);
myUnionFindSet.union(1,5);
myUnionFindSet.union(4,6);
myUnionFindSet.union(7,9);
myUnionFindSet.union(1,6);
myUnionFindSet.union(1,6);
myUnionFindSet.print();
myUnionFindSet.collapsingFind(6);
myUnionFindSet.print();
System.out.println(myUnionFindSet.find(6));
System.out.println(myUnionFindSet.find(1));
}
}
浙公网安备 33010602011771号