并查集

并查集

并查集(Java实现) - GoldArowana - 博客园

TODO:补充概念等知识

模板

class DSU {
    /**
     * initialSize : 初始化集合个数
     * currentSize : 当前集合个数
     * nodeFathers : 父节点
     * nodeCounts  : 集合中节点个数
     */
    private int initialSize;
    private int currentSize;
    private int[] nodeFathers;
    private int[] nodeCounts;

    public DSU(int initialSize) {
        this.initialSize = initialSize;
        this.currentSize = initialSize;
        nodeFathers = new int[initialSize];
        nodeCounts = new int[initialSize];
        for (int i = 0; i < initialSize; ++i) {
            nodeFathers[i] = i;
            nodeCounts[i] = 1;
        }
    }

    public int getInitialSize() {
        return initialSize;
    }

    public int getCurrentSize() {
        return currentSize;
    }

    public int getNodeCount(int id) {
        return nodeCounts[find(id)];
    }

    public int[] getNodeFathers() {
        return nodeFathers;
    }

    public int[] getNodeCounts() {
        return nodeCounts;
    }

    /**
     * 判断 id 是否符合要求
     *
     * @param id id
     * @return 是否符合要求
     */
    private boolean nonstandardId(int id) {
        return id < 0 || id >= initialSize;
    }

    /**
     * 查找元素所属集合根节点编号
     *
     * @param id 待查找元素
     * @return 所属集合的根节点编号
     */
    public int find(int id) {
        if (nonstandardId(id)) {
            return -1;
        }
        if (nodeFathers[id] == id) {
            return id;
        }
        nodeFathers[id] = find(nodeFathers[id]);
        return nodeFathers[id];
    }

    /**
     * 判断两个元素是否属于同一个集合
     *
     * @param x 元素1
     * @param y 元素2
     * @return 是否属于同一个集合
     */
    public boolean same(int x, int y) {
        return find(x) == find(y);
    }

    /**
     * 合并两个集合,并返回是否合并成功
     *
     * @param x 集合1
     * @param y 集合2
     * @return 是否合并成功
     */
    public boolean merge(int x, int y) {
        if (nonstandardId(x) || nonstandardId(y)) {
            return false;
        }
        int fx = find(x), fy = find(y);
        if (fx == fy) {
            return false;
        }
        // 如果fx的节点个数小于fy,则将fx合并到fy中,否则将fy合并到fx中
        if (nodeCounts[fx] < nodeCounts[fy]) {
            nodeFathers[fx] = fy;
            nodeCounts[fy] += nodeCounts[fx];
        } else {
            nodeFathers[fy] = fx;
            nodeCounts[fx] += nodeCounts[fy];
        }
        --currentSize;
        return true;
    }
}
posted @ 2023-01-29 19:14  Cattle_Horse  阅读(34)  评论(0编辑  收藏  举报