并查集的实现

题目描述:

给定一个没有重复值的整型数组arr,初始时认为arr中每一个数各自都是一个单独的集合,请设计一种叫UnionFind的结构,并提供以下两个操作。

(1)boolean isSameSet(int a,int b):查询a和b这两个数是否属于一个集合。

(2)void union(int a,int b):把a所在的集合与b所在的集合合并在一起,原本两个集合各自的元素以后都算作同一个集合。

要求:

如果调用isSameSet和union的总次数逼近或超过O(N),请做到单词调用isSameSet或union方法的平均时间复杂度为O(1)。

解答:

符合题目功能要求的结构就是并查集。

 1 class Element<V> {
 2     public V value;
 3     public Element(V value) {
 4         this.value=value;
 5     }
 6 }
 7 public class UnionFindSet<V> {
 8     public HashMap<V,Element<V>> elementMap;
 9     public HashMap<Element<V>,Element<V>> fatherMap;
10     public HashMap<Element<V>,Integer> rankMap;
11 
12     public UnionFindSet(List<V> list) {
13         elementMap=new HashMap<>();
14         fatherMap =new HashMap<>();
15         rankMap=new HashMap<>();
16         for (V value : list) {
17             Element<V> element=new Element<V>(value);
18             elementMap.put(value,element);
19             fatherMap.put(element,element);
20             rankMap.put(element,1);
21             
22         }
23     }
24     private Element<V> findHead(Element<V> element) {
25         Stack<Element<V>> path=new Stack<>();
26         while(element!=fatherMap.get(element)) {
27             path.push(element);
28             element=fatherMap.get(element);
29         }
30         while (!path.isEmpty()) {
31             fatherMap.put(path.pop(),element);
32         }
33         return element;
34     }
35 
36     public boolean isSameSet(V a,V b) {
37         if (elementMap.containsKey(a)&&elementMap.containsKey(b)) {
38             return findHead(elementMap.get(a))==findHead(elementMap.get(b));
39         }
40         return false;
41     }
42     public void union(V a,V b) {
43         if (elementMap.containsKey(a)&&elementMap.containsKey(b)) {
44             Element<V> aF=findHead(elementMap.get(a));
45             Element<V> bF=findHead(elementMap.get(b));
46             if (aF!=bF) {
47                 Element<V> big=rankMap.get(aF)>rankMap.get(bF)?aF:bF;
48                 Element<V> small=big==aF?bF:aF;
49                 fatherMap.put(small,big);
50                 rankMap.put(big,rankMap.get(aF)+rankMap.get(bF));
51                 rankMap.remove(small);
52             }
53         }
54     }
55 }

欢迎评论,共同进步!!

原文地址:https://www.cnblogs.com/hengzhezou/p/11062858.html