1、问题定义
参赛队信息管理
2、问题分析
能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项(参见大赛官网jsjds.blcu.edu.cn);包括增加、删除、修改参赛队伍的信息。
从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
3、概要设计
参赛队伍信息的数据结构
类——Contestant用于存储各个参赛队的详细信息,如队伍编号、参赛作品名称、参赛学校、赛事类别、参赛者及指导教师等。
public class Contestant {
String id;//编号
String name;//参赛作品名称
String school;//参赛学校
String category;//赛事类别
String player;//参赛者
String teacher;//指导教师
}
哈希表——numberMap、schoolMap
HashMap<String, Contestant> numberMap = new HashMap<>();//以参赛队编号为key的HashMap
HashMap<String, Map<String, Contestant>> schoolMap = new HashMap<>();//以参赛学校名称为键的嵌套HashMap
二叉排序树节点的数据结构
类——Node用于存储队伍编号、左子树及右子树节点。该类还提供了相应的add()、search()方法
class Node {
int num;//队号
Node left;//左子树
Node right;//右子树
Node(int n) {
this.num = n;
}
void add(Node node) {
if (node == null) {
return;
}
if (node.num < this.num) {//小于向左子树添加
floor++;//没有找到非空节点,要向其子树找,所以层数++
if (this.left == null) {
this.left = node;//找到空节点,添加
sum += floor;//层数累加,便于后续计算ASL
} else {//非空 递归添加
this.left.add(node);
}
} else {//大于向右子树添加
floor++;
if (this.right == null) {
this.right = node;
sum += floor;
} else {
this.right.add(node);
}
}
}
Node search(int n) {
if (this.num == n) {
return this;
} else if (n < this.num) {
if (this.left == null) return null;
return this.left.search(n);
} else {
if (this.right == null) return null;
return this.right.search(n);
}
}
}
列表——ArrayList用于按序存放参赛队伍编号,便于后续建立二叉排序树
ArrayList<String> list=new ArrayList<>();//存放参赛队伍编号的列表,用于建立二叉排序树
构建二叉排序树方法:creatBiTree()定义在主类CompetitionSystem中,便于后续读取文件后进行构建二叉排序树。
private void creatBiTree() {//创建二叉排序树
root = new Node(Integer.parseInt(number.get(0)));
for (int i = 1; i < numberMap.size(); i++) {
if (number.get(i) == null) continue;//遇到空时跳过
floor = 1;//每次添加新节点时设置其层数为1
root.add(new Node(Integer.parseInt(number.get(i))));//添加节点
}
}
team.txt文件数据读取
void readtxt() {//读取数据
System.out.println("······读取数据中······");
String line;
//读取txt文件并解析每行数据,将数据保存到numberMap和schoolMap中
try (BufferedReader br = new BufferedReader(new FileReader("src/System/team.txt"))) {
int i = 0;
while ((line = br.readLine()) != null) {
//分割数据
String[] fields = line.split("#");
Contestant c = new Contestant();
//添加数据
c.id = fields[0].trim();
c.name = fields[1].trim();
c.school = fields[2].trim();
c.category = fields[3].trim();
c.player = fields[4].trim();
c.teacher = fields[5].trim();
//将参赛者信息加入到以参赛队编号为键的HashMap中
numberMap.put(c.id, c);
//添加参赛队编号到数组中
number.put(i++, c.id);
//判断是否已经有该学校的参赛队伍
if (!schoolMap.containsKey(c.school)) schoolMap.put(c.school, new HashMap<>());
//将参赛者信息加入到以参赛学校名称为键的HashMap中
schoolMap.get(c.school).put(c.id, c);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
System.out.println("======数据读取完成======");
}
team.txt文件数据写出
private void writetxt() {
try {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("src/System/team.txt"));
for (Map.Entry<String, Contestant> entry : numberMap.entrySet()) {
Contestant c = entry.getValue();
String line = c.id + "\t#\t" + c.name + "\t#\t" + c.school + "\t#\t" + c.category + "\t#\t" + c.player + "\t#\t" + c.teacher;
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}