并查集算法

本文介绍了如何使用Java实现WeightedQuickUnionUF并查集算法,作者在编写过程中遇到了键盘录入数字对的问题,通过参考网络示例得以解决。博客旨在分享算法知识,鼓励持续学习。
摘要由CSDN通过智能技术生成

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);//输出学生信息
                    }
                }
            }   
            */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值