并查集(两个版本)
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 }
下面这个版本适用于预先不知道有多少个元素,使用的是泛型:
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 }
以上是关于并查集(两个版本)的主要内容,如果未能解决你的问题,请参考以下文章