并查集 看起来可以解决一些关于无向图的问题
看看这一篇博客 并查集的理解和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;
}
}