JAVA并查集实现(节点连片)

/**
 * 并查集实现
 * 时间: 2026/7/27 16:13
 */
public class UFCollection {
    public static void main(String[] args) {
        int[] nodes = new int[]{10, 20, 30, 40, 50}; //5个节点
        int[][] edges = new int[][]{{1, 2}, {2, 3}, {4, 5}}; // 3条边

        // 找根节点
        int[] parent = calculateParent(nodes, edges);

        // 分组多个连通块(同根节点为一块)
        Map<Integer, List<Integer>> group = new HashMap<>();
        for (int i = 1; i <= nodes.length; i++) {
            // 找根节点
            int root = find(parent, i);
            // 按根节点分组,添加自己
            group.computeIfAbsent(root, (key) -> new ArrayList<>()).add(nodes[i - 1]);
        }

        System.out.println(group);

    }

    /**
     * 计算父节点
     *
     * @param nodes 节点集合[10,20,30,40,50]
     * @param edges 边集合[{1,2},{2,3},{4,5}]
     * @return
     */
    public static int[] calculateParent(int[] nodes, int[][] edges) {
        int n = nodes.length;
        // 构造parent[] 记录所有节点的根节点(默认根节点是自己)
        int[] parent = new int[n + 1]; // 0位置占位符不用,便于理解
        int[] size = new int[n + 1]; // 每棵树的节点数量(默认都是1)
        // 初始化
        for (int i = 1; i <= n; i++) {
            parent[i] = i;
            size[i] = 1;
        }

        // 边并入集合
        for (int[] edge : edges) {
            int u = edge[0];
            int v = edge[1];
            union(parent, size, u, v);
        }

        return parent;
    }

    public static void union(int[] parent, int[] size, int u, int v) {
        int rU = find(parent, u); // 找根节点
        int rV = find(parent, v);
        if (rU == rV) {
            // 根节点一样(同在一棵树下,无需合并),退出
            return;
        }
        if (size[rU] < size[rV]) {  // 找到大树(节点数量大的),进行交换
            // 交换后,保证rU是大树(前边点始终保持大树)
            int temp = rU;
            rU = rV;
            rV = temp;
        }
        // 小树根节点指向为大树
        parent[rV] = rU;
        // 大树节点数量增加
        size[rU] += size[rV];
    }

    // 查找父节点
    public static int find(int[] parent, int x) {
        while (parent[x] != x) { //根节点不是自己,继续循环
            parent[x] = parent[parent[x]];
            x = parent[x];
        }
        // 根节点是自己,退出循环,说明找到根了
        return x;
    }

}

 

posted @ 2026-07-27 17:18  追极  阅读(6)  评论(0)    收藏  举报