用java写数据结构作业——7.2堆并查集哈夫曼树二

简介: 用java写数据结构作业——7.2堆并查集哈夫曼树二

数据结构第9周作业——堆并查集哈夫曼树二


7-2 并查集【模板】 (60分)

给出一个并查集,请完成合并和查询操作。

输入格式:

第一行包含两个整数N、M,表示共有N个元素和M个操作。

接下来M行,每行包含三个整数Zi、Xi、Yi。

当Zi=1时,将Xi与Yi所在的集合合并。

当Zi=2时,输出Xi与Yi是否在同一集合内,是的话输出Y;否则的话输出N。

输出格式:

对于每一个Zi=2的操作,对应一行输出,每行包含一个大写字母,为Y或者N。

输入样例:

4 7

2 1 2

1 1 2

2 1 2

1 3 4

2 1 4

1 2 3

2 1 4


输出样例:

N

Y

N

Y


数据规模:

对于30%的数据,N<=10,M<=20;

对于70%的数据,N<=100,M<=1000;

对于100%的数据,N<=10000,M<=200000。


解决思路:通过审题可以发现题目要求对多个集合进行合并和查询,开始我想到的是用为每个数建立一个set,如要合并就将其中一个set中的值加入集合并将其销毁,但是考虑到题目中测试数据过于庞大,创建多个对象显然会耗费许多内存。抓住开始单个元素便是一个集合的特点,于是初期先用一个数组来存储数据,等有操作命令时再来创建set集合,而这些set集合由一个list来维护。


这时候我们需要有两个方法findTwo(查询)和merge(合并)以及一个私有方法findOne(查找数所在的集合)


Object FindOne(int a)

1.首先在数组中查找,找到则说明不在一起

2.若未找到则到list中遍历查找,返回所在集合(若在数组中则返回null)

注意:不必遍历,因为每个数组的下标即为它的值


Void findTwo(int a,int b)

1.调用findOne查找a所在集合

2.在集合中查找是否存在b

3.若有则输出打印Y,没有则N


Void merge(int a ,int b)

1.用私有方法findOne查询a,b所在集合

2.合并


import java.util.*;
public class Main {
    //初始数组
    public static int[] array;
    //维护set集合的list
    public static List<Set<Integer>> setArray=new ArrayList<>();
    public static void main(String[] args) {
        //提前声明,避免在循环中声明占内存
        int z,a,b;
        //创建一个文本扫描器检测键盘输入
        Scanner scanner=new Scanner(System.in);
        //N个元素
        int N=scanner.nextInt();
        //M个操作
        int M=scanner.nextInt();
        //初始化array,确保下标即为对应的值
        array=new int[N+1];
        for (int i=0;i<N+1;i++){
            array[i]=i;
        }
        //循环操作
        for (int i=0;i<M;i++){
            z=scanner.nextInt();
            a=scanner.nextInt();
            b=scanner.nextInt();
            if (z==1){
                merge(a,b);
            }else if (z==2){
                findTwo(a,b);
            }
        }
    }
    /**
     * 1.首先在数组中查找,找到则说明不在一起
     * 2.若未找到则到list中遍历查找,返回所在集合(若在数组中则返回null)
     * 注意:不必遍历,因为每个数组的下标即为它的值
     * @param a
     * @return
     */
    private static Set<Integer> findOne(int a){
        if (array[a]!=0){
            return null;
        }
        //在维护set集合的数组中遍历
        for (Set<Integer> set:setArray){
            //调用contain方法,若存在则返回该集合
            if (set.contains(a)){
                return set;
            }
        }
        //这道题不可能执行到这步,除非系统想搞我们!当然我们也不怕
        return null;
    }
    /**
     * 1.调用findOne查找a所在集合
     * 2.在集合中查找是否存在b
     * 3.若有则输出打印Y,没有则N
     * @param a
     * @param b
     */
    public static void findTwo(int a,int b){
        Set<Integer>set=findOne(a);
        if (set==null){
            //集合为空时,即a在数组中时输出N
            System.out.println("N");
        }else if (set.contains(b)){
            System.out.println("Y");
        }else{
            //不包含时输出N
            System.out.println("N");
        }
    }
    /**
     * 1.用私有方法findOne查询a,b所在集合
     * 2.合并
     * @param a
     * @param b
     */
    public static void merge(int a,int b){
        Set<Integer> set1=findOne(a);
        Set<Integer> set2=findOne(b);
        //分别讨论几种情况
        if (set1==null&&set2!=null){
            set2.add(a);
            //原来数组的值清0
            array[a]=0;
        }else if (set1!=null&&set2==null){
            set1.add(b);
            array[b]=0;
        }else if (set1==null&&set2==null){
            //此时需要创建一个set集合,并清0
            Set<Integer> set=new HashSet<Integer>();
            set.add(a);
            set.add(b);
            //别忘了加入list集合,粗心的我就忘了!汗。。。
            setArray.add(set);
            array[a]=0;
            array[b]=0;
        }else {
            //判断两个集合是否相等
            if (set1!=set2){
                //确保小的集合加入大的集合
                if (set1.size()<set2.size()){
                    set2.addAll(set1);
                    //把多余的set集合清出list,粗心的我又忘了......
                    setArray.remove(set1);
                }else {
                    set1.addAll(set2);
                    setArray.remove(set2);
                }
            }
        }
    }
}


记录点滴,乐于分享,转载请注明出处


以梦为马,不负人生韶华,我们追梦在路上!


愿与君共勉!


相关文章
|
2月前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
50 1
|
2月前
|
存储 Java
告别混乱!用Java Map优雅管理你的数据结构
【10月更文挑战第17天】在软件开发中,随着项目复杂度增加,数据结构的组织和管理至关重要。Java中的Map接口提供了一种优雅的解决方案,帮助我们高效、清晰地管理数据。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,有效提升了代码质量和维护性。
94 2
|
9天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
30 5
|
1月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
49 6
|
1月前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
2月前
|
存储 算法 Java
Java 中常用的数据结构
【10月更文挑战第20天】这些数据结构在 Java 编程中都有着广泛的应用,掌握它们的特点和用法对于提高编程能力和解决实际问题非常重要。
33 6
|
2月前
|
存储 Java 开发者
Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效
【10月更文挑战第19天】在软件开发中,随着项目复杂度的增加,数据结构的组织和管理变得至关重要。Java中的Map接口提供了一种优雅的方式来管理数据结构,使代码更加清晰、高效。本文通过在线购物平台的案例,展示了Map在商品管理、用户管理和订单管理中的具体应用,帮助开发者告别混乱,提升代码质量。
32 1
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
181 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
32 1
|
23天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
44 5
下一篇
DataWorks