并查集

并查集解决的问题

1) 查询两个元素是否属于同一个集合。

2) 将两个集合合并。

特点:

1) 初始化时每个node 都属于一个集合的, 他的父亲node 也是他自己。  自个就是某个集合的代表。size = 1;

2) 查找是否属于同一个集合时, 都是去找他们集合的代表节点。  看是否是一样的。

3)   优化在查找他的结合代表节点。  查找路径变小。

4) 将集合元素少的  set   挂到集合元素大的 set中。    f1 -->  f2.

    public static class UnionFindSet{
        
    
        public HashMap<Node,Node> fatherMap;
        public HashMap<Node, Integer> sizeMap;
        
        public   UnionFindSet() {
            fatherMap = new HashMap<>();
            sizeMap = new HashMap<>();
        }
        public void init(List<Node> nodes) {
            fatherMap.clear();
            sizeMap.clear();
            for (Node node : nodes) {
                fatherMap.put(node, node);
                sizeMap.put(node, 1);
            }
        }
        
        
        public Node findHead(Node node) {
            
            Node father = fatherMap.get(node);            
            if (father != node ) {
                father = findHead(father);
            }
            fatherMap.put(node, father);
            return father;
        }
        
        
        public boolean isSet(Node node1, Node node2) {
            return findHead(node1) == findHead(node2);            
        }
        
        public void  unionSet(Node node1, Node node2) {
            
            if (node1 == null || node2 == null) {
                return ;
            }
            
            Node f1 = findHead(node1);
            Node f2 = findHead(node2);
            
            if ( f1 != f2 ) {
                int s1 = sizeMap.get(f1);
                int s2 = sizeMap.get(f2);
                
                if (s1 <= s2 ) {
                    fatherMap.put(f1, f2);
                    sizeMap.put(f2, s1+s2);
                }else {
                    fatherMap.put(f2, f1);
                    sizeMap.put(f1, s1+s2);
                }
                
            }    
        }
            
    }
原文地址:https://www.cnblogs.com/lijins/p/10164771.html