江科大数据结构课程设计预习报告(二)

1、问题定义

①参赛队伍信息的找(按参赛队编号查找、按参赛学校查找)

2、问题分析

从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。

②能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。

3、概要设计

数据结构、文件读写方法请查看:预习报告(一)

1、菜单

    private void menu() {
        //进入菜单时建立二叉排序树
        creatTree();
        System.out.println("\n======请选择操作======");
        System.out.println("=======1-查询系统=======");
        System.out.println("=======2-修改系统=======");
        System.out.println("=======3-叫号系统=======");
        System.out.println("=======4-导航系统=======");
        System.out.println("=======0-退出系统=======");
        int choose;
        while (true) {
            choose = sc.nextInt();
            if (choose == 1 || choose == 2 || choose == 3 || choose == 4 || choose == 0) break;
            else System.out.println("输入错误,请重新输入!");
        }
        switch (choose) {
            case 1 -> find();
            case 2 -> change();
            case 0 -> {
                System.out.println("欢迎再次使用本系统!");
                write();//将数据重新写回文件中
                System.exit(0);
            }
        }
    }

2、信息输出

当遇到查询或者需要输出参赛队信息时,将参赛队对象传递到该方法并拼接输出

    private void print(Contestant c) {
        System.out.println(c.id + "\t#\t" + c.name + "\t#\t" + c.school + "\t#\t" + c.category + "\t#\t" + c.player + "\t#\t" + c.teacher);
    }

3、查询系统

    private void find() {
        System.out.println("\n=======信息查询端口=======");
        System.out.println("1-按参赛队编号进行查询");
        System.out.println("2-按参赛学校名进行查询");
        System.out.println("0-返回主菜单");
        int choose;
        while (true) {
            choose = sc.nextInt();
            if (choose == 1 || choose == 2 || choose == 0) break;
            else System.out.println("输入错误,请重新输入!");
        }
        switch (choose) {
            case 1 -> findNum();
            case 2 -> findSchool();
            case 0 -> menu();
        }
    }

3.1、按参赛队编号进行查询

按参赛队编号查询实际上很简单,但课设要求其基于二叉排序树查询,因此在读取文件时,将每个参赛队伍的参赛队编号存入了list中,用于建立二叉排序树,进入到菜单界面时就利用list来建立二叉排序树,查找时也是对二叉排序树来查找,在二叉树中找到了所查询的编号节点,再输出成功信息,实际是用以参赛队编号为key的哈希表来查询其信息的。

    private void findNum() {
        while (true) {
            System.out.print("输入查询的参赛队编号:");
            String num = sc.next();
            Node node = root.search(Integer.parseInt(num));//基于二叉排序树查找
            if (node == null) {//在二叉排序树中找不到节点
                System.out.println("查找失败!输入1继续查询,输入其他则返回上层菜单");
                int choose = sc.nextInt();
                if (choose != 1) find();//返回查询系统
            } else {//找到节点
                System.out.println("查找成功!");
                Contestant cnum = numberMap.get(num);//获取到该队信息对象
                System.out.println("参赛队编号\t#\t参赛作品名称\t#\t参赛学校\t#\t赛事类别\t#\t参赛者\t#\t指导教师");
                print(cnum);//信息输出
                System.out.println("查找成功时的平均查找长度ASL:" + sum / (double) (numberMap.size()));
                System.out.println("输入1继续查询,输入其他则返回上层菜单");
                int choose = sc.nextInt();
                if (choose != 1) find();//返回查询系统
            }
        }
    }

3.2、按参赛学校名进行查询

对于参赛学校名查询,为了方便,定义一个新的数据结构——双层哈希表,以校名为key,value是该校所有参赛队的哈希表,在读取文件时也一并将信息存入了。

找到某学校的参赛队伍时,按归并排序算法进行输出,选择归并算法排序的原因是其较为稳定、速度较快,牺牲空间换时间,但因为数据量不大因此可以接受。

HashMap<String, Map<String, Contestant>> schoolMap = new HashMap<>();//以参赛学校名称为键的嵌套HashMap
    private void findSchool() {
        while (true) {
            System.out.println("输入查询的参赛学校:");
            String school = sc.next();
            if (schoolMap.containsKey(school)) {
                System.out.println("查找成功!");
                HashMap<String, Contestant> innerMap = schoolMap.get(school);//获取该学校参赛队的哈希表
                System.out.println("参赛队编号\t#\t参赛作品名称\t#\t参赛学校\t#\t赛事类别\t#\t参赛者\t#\t指导教师");
                List<Contestant> contestants = new ArrayList<>();
                Iterator<HashMap.Entry<String, Contestant>> iterator = innerMap.entrySet().iterator();
                while (iterator.hasNext()) {//用迭代器遍历该学校对应的内部哈希表
                    HashMap.Entry<String, Contestant> entry = iterator.next();
                    Contestant c = entry.getValue();//获取该校每个参赛队伍
                    contestants.add(c);//添加至列表中
                }

                Contestant sortCategory = new Contestant();
                sortCategory.mergeSort(contestants, 0, contestants.size() - 1);//排序

                for (Contestant c : contestants) {//输出数据
                    print(c);
                }
                System.out.println("输入1重新查询,输入其他返回上层菜单");
                int choose = sc.nextInt();
                if (choose != 1) find();
            } else {
                System.out.println("查找失败,无该校的参赛队伍!输入1重新查询,输入其他返回上层菜单");
                int choose = sc.nextInt();
                if (choose != 1) find();
            }
        }
    }

以下是Contestant类中的排序方法,用的是归并排序

 

    public  void mergeSort(List<Contestant> list, int left, int right) {
        if (left >= right) {
            return;
        }
        int mid = (left + right) / 2;
        mergeSort(list, left, mid);
        mergeSort(list, mid + 1, right);
        merge(list, left, mid, right);
    }

    public  void merge(List<Contestant> list, int left, int mid, int right) {
        List<Contestant> temp = new ArrayList<>();
        int i = left;
        int j = mid + 1;
        while (i <= mid && j <= right) {
            if (list.get(i).category.compareTo(list.get(j).category) <= 0) {
                temp.add(list.get(i));
                i++;
            } else {
                temp.add(list.get(j));
                j++;
            }
        }
        while (i <= mid) {
            temp.add(list.get(i));
            i++;
        }
        while (j <= right) {
            temp.add(list.get(j));
            j++;
        }
        for (int k = 0; k < temp.size(); k++) {
            list.set(left + k, temp.get(k));
        }
    }

4、测试

测试信息:

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值