并查集的基础java实现

并查集的基本定义

import java.util.HashMap;
import java.util.List;
import java.util.Stack;

public class UnionFind {

    public static class Element<V> {
        public V value;

        public Element(V value) {
            this.value = value;
        }
    }

    public static class UnionFindSet<V> {
        //元素的map,获取节点内部包裹内容
        public HashMap<V, Element<V>> elementMap;
        // key 某个元素    value 元素的父
        public HashMap<Element<V>, Element<V>> fatherMap;
        // key 某个集合的代表元素    value 该集合的元素个数
        public HashMap<Element<V>, Integer> sizeMap;

        public UnionFindSet(List<V> list) {
            elementMap = new HashMap<>();
            fatherMap = new HashMap<>();
            sizeMap = new HashMap<>();

            for (V value :
                    list) {
                Element<V> element = new Element<>(value);
                elementMap.put(value, element);
                fatherMap.put(element, element); //刚开始自身成一个圈
                sizeMap.put(element, 1);
            }
        }

寻找代表元素方法


        //给定一个element 向上一直找 找到代表元素
        private Element<V> findHead(Element<V> element) {
            Stack<Element<V>> stack = new Stack<>();

            while (element != fatherMap.get(element)) {
                stack.push(element);
                element = fatherMap.get(element);
            }

            //将整个数据结构扁平化 变成一个高为2 的 多叉树
            while (!stack.isEmpty()) {
                fatherMap.put(stack.pop(), element);
            }

            return element;
        }

判断两个元素是不是一个集合

        //查询两个元素是不是一个集合
        public Boolean isSameSet(V a, V b) {
            if (elementMap.containsKey(a) && elementMap.containsValue(b)) {
                return findHead(elementMap.get(a)) == findHead(elementMap.get(b));
            }
            return false;
        }

并查集合并方法


        public void union(V a, V b) {
            if (elementMap.containsKey(a) && elementMap.containsValue(b)) {
                Element<V> afather = findHead(elementMap.get(a));
                Element<V> bfather = findHead(elementMap.get(b));

                if (afather != bfather) {
                    Element<V> big = sizeMap.get(afather) >= sizeMap.get(bfather) ? afather : bfather;
                    Element<V> small = big == afather ? bfather : afather;
                    fatherMap.put(small,big);
                    sizeMap.put(big,sizeMap.get(afather)+sizeMap.get(bfather));
                }
            }
        }
    }


}

猜你喜欢

转载自blog.csdn.net/Wantbebetter/article/details/121609804