并查集(两个版本)

Posted black-fish

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并查集(两个版本)相关的知识,希望对你有一定的参考价值。

技术分享图片
 1    import java.util.*;
 2                                       
 3     public class DisjointUnionSets1{
 4     int[] rank, parent,size;
 5     int n;
 6 
 7         public DisjointUnionSets1(int n){
 8         rank = new int[n];
 9         parent = new int[n];
10         size = new int[n];
11         this.n = n;
12         makeSet();
13         }
14 
15       void makeSet(){
16       for (int i=0; i<n; i++){
17       parent[i] = i;
18       size[i]=1;
19  
20       }
21      }
22 
23      
24       
25       public int find(int x){                        // Returns representative of x‘s set//
26         if (parent[x]!=x)
27         parent[x] = find(parent[x]);
28  
29         return parent[x];
30       }
31  
32     
33 
34      public void unite(int x, int y){    
35         int xRoot = find(x), yRoot = find(y); 
36         if (xRoot == yRoot)
37             return;
38  
39         if(rank[xRoot] < rank[yRoot]){
40            parent[xRoot] = yRoot;
41            size[yRoot]+=size[xRoot];
42       
43            }
44         else if(rank[yRoot] < rank[xRoot]){
45            parent[yRoot] = xRoot;
46            size[xRoot]+=size[yRoot];
47          
48            }
49 
50         else{
51             parent[yRoot] = xRoot;
52             rank[xRoot] = rank[xRoot] + 1;
53             size[xRoot]+=size[yRoot];
54          
55             
56         }
57      }
58 
59 
60     public boolean sameSet(int x,int y){
61     return find(x)==find(y);
62     }
63 
64 
65  
66     public boolean isRoot(int x){
67     return find(x)==x;
68     }
69     
70 
71      public int getSize(int x){
72      return size[x];
73      }
74     
75 
76 
77     public static void main(String[] args){
78      DisjointUnionSets1 dus=new DisjointUnionSets1(6);
79      dus.unite(0,2);
80      dus.unite(2,4);
81      dus.unite(1,3);
82 System.out.println(dus.sameSet(0,4));
83 System.out.println(dus.sameSet(3,1));
84 System.out.println(dus.sameSet(1,5));
85 System.out.println(dus.sameSet(2,3));
86 System.out.println(dus.sameSet(5,3));
87 System.out.println(dus.sameSet(2,0));
88 for(int i=0;i<6;i++)
89 System.out.println(i+":   is root?  "+dus.isRoot(i)+"     size? "+dus.getSize(i));
90 }
91 
92 
93 }
View Code

 

 

下面这个版本适用于预先不知道有多少个元素,使用的是泛型:

  1  public class DisJointUnionSets2<E>{                                                 
  2     HashMap<E,Node<E>> map=new HashMap<>();
  3    
  4    
  5         public DisJointUnionSets2(){  
  6         }
  7 
  8 
  9        public void unite(E e1,E e2){
 10        Node<E> n1;
 11        Node<E> n2;
 12        if(!map.containsKey(e1)&& !map.containsKey(e2)){
 13        n1=new Node<>(e1);
 14         n2=new Node<>(e2);
 15         n2.parent=n1;
 16         n1.rank++;
 17         n1.size+=n2.size;
 18         map.put(e1,n1);
 19         map.put(e2,n2);
 20        }
 21 
 22     else if(!map.containsKey(e1)){
 23      n1=new Node<>(e1); 
 24      n2=getRoot(e2);     
 25       n1.parent=n2;
 26       n2.size+=n1.size;
 27       map.put(e1,n1); 
 28       }
 29 
 30       else if(!map.containsKey(e2)){
 31       n2=new Node<>(e2); 
 32       n1=getRoot(e1);      
 33       n2.parent=n1;
 34       n1.size+=n2.size;
 35       map.put(e2,n2);
 36       }
 37     
 38     else{
 39       n1=getRoot(e1);
 40       n2=getRoot(e2);
 41        if(n1.rank>n2.rank){
 42        n2.parent=n1;
 43        n1.rank=Math.max(n1.rank, 1+n2.rank);
 44        n1.size+=n2.size;
 45       }
 46       else if(n1.rank<n2.rank){
 47        n1.parent=n2;
 48        n2.rank=Math.max(n2.rank, 1+n1.rank);
 49         n2.size+=n1.size;
 50       }
 51       else if(n1.rank==n2.rank && n1!=n2){
 52       n2.parent=n1;
 53       n1.rank=Math.max(n1.rank, 1+n2.rank);
 54        n1.size+=n2.size;
 55       }
 56      
 57     }
 58  }
 59 
 60   
 61 
 62 public Node<E> getRoot( E e){
 63 if(!map.containsKey(e))
 64 return new Node<>(e);
 65 
 66 Node<E> n=map.get(e);
 67 while(n.parent!=null){
 68 n=n.parent;
 69 }
 70 return n;
 71 }
 72  
 73 
 74   public boolean sameSet(E x,E y){
 75     return getRoot(x)==getRoot(y);
 76     }
 77 
 78 
 79 
 80     public boolean isRoot(E e){
 81         if(map.containsKey(e) && map.get(e).parent!=null)
 82             return false;
 83         else
 84             return true;
 85     }
 86     
 87     
 88     public int getSize(E e){
 89         if(map.containsKey(e))
 90             return map.get(e).size;    
 91         else
 92         return 1; 
 93     }
 94     
 95 
 96  class Node<E>{    
 97  E element;
 98  Node<E> parent;
 99  int rank;
100  int size=1;
101  
102  public Node(E e){
103  element=e;
104 }     
105 }                      
106 
107 }

 

以上是关于并查集(两个版本)的主要内容,如果未能解决你的问题,请参考以下文章

可持久化并查集

笔记并查集---无向图处理代码模板及类型题

半可持久化并查集

并查集小结

关于并查集的一切全在这里了

14 并查集