并查集是集合的一种,它只有两种方法,合并和查找。
合并就是把两个元素所在的集合合并为一个。
查找就是查找某元素所属的集合。
一般并查集用树的父指针数组来存储实现。根节点数组值为负数,负几表示该集合有几个元素。
元素和集合名称对应数组索引。从属关系对应相应数组值。数组值为负数,表示对应索引为树的根,也就是集合名。
初始状态下所有元素都是一颗单独的树,也就是说所有数组值都初始化为-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)); } }