整理了一道并查集的问题

并查集 看起来可以解决一些关于无向图的问题
看看这一篇博客 并查集的理解和Java实现我在博主的基础上实现了输出每个集合节点的功能(从小到大排列) 并作了一些注释

package Aut;

import java.util.*;

/**
 * 并查集的思路解决
 */
public class meituan3 {
    //parent[1]=0表示1的父节点是0 若出现parent[2]=2,表示2是根节点
    public static int[] parent=new int[1000];

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        //订单数量
        int n=scanner.nextInt();
        //关系数量
        int m=scanner.nextInt();
        //保存关系
        List<int[]> list = new ArrayList<>();
        for(int i=0;i<m;i++){
            int a1=scanner.nextInt();
            int a2=scanner.nextInt();
            list.add(new int[]{a1,a2});
        }
        findCircle(list,n);
    }

    /**
     * 初始化并查集 所有节点都指向自己
     * @param n
     */
    public static void init(int n){
        for(int i=0;i<=n;i++){
            parent[i]=i;
        }
    }

    /**
     * 查找某一结点的根节点 通过两个节点的根节点是否一致来判断是否属于同一阵营
     * @param target
     * @param parent
     * @return
     */
    public static int find(int target,int[] parent){
        //当某个节点的值等于下标时,说明找到根节点
        int index=target;
        //循环结束时 找到target对应的根节点
        while(parent[index]!=index){
            index=parent[index];
        }

        //路径压缩 把target的父节点的上级修改为根节点 避免长距离的寻找
        int i=target;
        while (i != index){
            //找到target的父节点
            i = parent[i];
            //把i的父节点直接赋值为根节点
            parent[i]=index;
        }
        return index;
    }

    /**
     * 合并两棵树 分别找到两个节点的根节点 把其中一个赋值为另外一个的父节点即可
     * @param target1
     * @param target2
     */
    public static void union(int target1,int target2){
        int root1=find(target1,parent);
        int root2=find(target2,parent);
        if(root1!=root2) parent[root1]=root2;
    }

    /**
     * 找到集合数量
     * @param list
     * @param n
     * @return
     */
    public static int findCircle(List<int[]> list,int n){
        List<ArrayList<Integer>> lists=new ArrayList<>();
        if(n==0) return 0;
        //初始化n个节点
        init(n);
        //生成parent数组
        for(int i=0;i<list.size();i++){
            int[] a=list.get(i);
            union(a[0],a[1]);
        }
        int res=0;
        for(int j=1;j<=n;j++){
            //根节点为自己说明一个集合的存在
            if(parent[j]==j){
                res++;
                ArrayList<Integer> list1=new ArrayList<>();
                for(int k=1;k<=n;k++){
                    if(find(k,parent)==j) list1.add(k);
                }
                Collections.sort(list1);
                lists.add(list1);
            }
        }
        System.out.println(res);
        for(ArrayList numsList:lists){
            for(int i=0;i<numsList.size();i++){
                System.out.print(numsList.get(i));
            }
            System.out.println(" ");
        }

        return res;
    }

}

你可能感兴趣的:(面试,算法与数据结构)