Java实现并查集算法(WeightedQuickUnionUF)
并查集算法说明:
写的时候遇到的一点问题
还是java基础不过关,键盘录入一对一对数字对的时候麻爪了,参考了网络上一个例子才解决。参考例子也放在代码中了,这就当第一份代码博客,算法博客,希望能一直坚持下去。
代码部分
package com.lx.unionfind;
import java.util.Scanner;
/**
* Simple to Introduction
* @ProjectName: [MyAlgorithm]
* @Package: [com.lx.unionfind]
* @ClassName: [UF]
* @Description: 并查集算法,维护三个变量,一个是连通分支数量,一个是节点标识数组,一个是分支深度数组
* @Author: [刘翔]
* @CreateDate: [2017年11月11日 下午8:13:27]
* @UpdateUser: [刘翔]
* @UpdateDate: [2017年11月11日 下午8:13:27]
* @UpdateRemark: [说明本次修改内容]
* @Version: [v1.0]
*
*/
public class WeightedQuickUnionUF {
private int[] id;//节点标识数组
private int count;//连通分支数量
private int[] sz;//连通分支的深度
public WeightedQuickUnionUF(int N) {
count = N;
id = new int[N];
for (int i = 0; i < N; i++) {
id[i] = i;
}
sz = new int[N];
for (int i = 0; i < N; i++) {
sz[i] = 1;
}
}
public int count() {
return count;
}
public boolean connected(int p,int q) {
return find(p)==find(q);
}
/**
* @Title: find
* @Description: TODO(查找并返回该连通分支的根节点)
* @param @param p
* @param @return
*/
public int find(int p) {
while (p != id[p]) {
p = id[p];
}
return p;
}
/**
* @Title: union
* @Description: TODO(连通pq两点所在的连通分支)
* @throws
*/
public void union(int p,int q) {
int i = find(p);
int j = find(q);
if (i == j) {
return;
}
if (sz[i] < sz[j]) {
id[i] = j; //id[i]是i的父节点
sz[j] += sz[i];
}else {
id[j] = i;
sz[i] += sz[j];
}
count--;
}
public static void main(String[] args) {
int N;
int index = 1;
Scanner sc1 =new Scanner(System.in);
System.out.println("请输入网络中节点总数");
N = sc1.nextInt();
WeightedQuickUnionUF uf = new WeightedQuickUnionUF(N);
System.out.println("请按照“节点-节点”格式输入网络中相连接的节点对");
// while (true) {
// int p = sc.nextInt();
// int q = sc.nextInt();
// if (uf.connected(p, q)) {
// continue;
// }
// uf.union(p, q);
// System.out.println(p+"-"+q);
// }
while (true) {
System.out.println("请开始输入第"+index+"个节点对");
Scanner sc2 = new Scanner(System.in);
String str = sc2.nextLine();
if (str.equals("end")) {
System.out.println("已完成所有节点对的录入");
break;
}
String[] info = str.split("-");
int p = Integer.parseInt(info[0]);
int q = Integer.parseInt(info[1]);
if (uf.connected(p, q)) {
continue;
}else {
uf.union(p, q);
}
System.out.println(p+"-"+q);
index++;
}
System.out.println("网络中一共有" + uf.count + "个连通分支");
}
}
/**
* 参考代码
*
import java.util.ArrayList;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();//定义一个学生类
Scanner input = new Scanner(System.in);//创建一个扫描器对象,用于读取从控制台输入
int index = 1;//顺序号
System.out.println("------------说明------------");
System.out.println("1:输入格式:name,age 例如:tom,18");// 注意逗号是半角
System.out.println("2:输入#号则结束输入");
System.out.println("---------------------------");
while (true) {
System.out.println("请输入第" + index + "个学生信息 ");
String str = input.nextLine();//从控制台读取一行
if (str.equals("#")) {//如果输入的是#号,
System.out.println("提示: 已经结束了学生信息的输入");
break;//跳出循环,结束输出
}
String[] info = str.split(",");//用逗号进行切割
String name = info[0];
int age = Integer.parseInt(info[1]);//从字符串转换成整数
list.add(new Student(name, age));//创建个学生对象添加到list里
index++;
}
System.out.println("刚刚成功输入的学生信息");
for (Student student : list) {
System.out.println(student);//输出学生信息
}
}
}
*/