本篇内容为6月2号学习内容,因疏忽未及时上传至博客,见谅。
根据学校名称(或者赛事类别)查找对应的团队信息可以使用归并排序(Merge Sort)进行处理,因为归并排序对于大的数据集来说非常高效,时间复杂度为O(n log n),并且它是稳定的排序算法,这意味着相同的元素在排序后会保持原有的顺序。以按照学校名称查找为例,我们可以通过归并排序来按照赛事类别进行排序,这样就可以清晰地看出同一个学校每个赛事类别的参赛队伍数量了。
归并排序(Merge Sort)是一种分而治之的排序算法。它的基本思路是将待排序的序列划分为若干个子序列,使得每个子序列的长度尽可能相等,然后对每个子序列进行排序,最后将排序后的子序列合并为最终的排序序列。
以下是归并排序的基本步骤:
(1)分解:将待排序的n元素序列分解成两个n/2元素的子序列。每次分解,子序列的长度都会减半,直到子序列的长度为1或0。
(2)递归排序:递归地将两个子序列排序。首先对左半部分的子序列进行递归排序,然后对右半部分的子序列进行递归排序。这个过程将持续到所有的子序列都被排序。
(3)合并:将两个排序后的子序列合并为一个排序序列。在合并过程中,需要维护序列的有序性。具体的做法是,建立一个临时的数组,每次从两个子序列的头部取出较小的元素放入临时数组,然后移动相应序列的头指针,直到两个子序列都被完全放入临时数组。最后,将临时数组的内容复制回原数组即可得到最后排序后的数组。
可见,尽管归并排序需要额外的空间来存储临时数组,但是其稳定的排序性能使得它在许多场景下都是非常实用的排序算法。
下面是对应部分的代码:
/**
* 归并排序
* @param teams 要排序的参赛队伍信息
* @return 排序后的参赛队伍信息
*/
private static List<Team> mergeSort(List<Team> teams) {
// 如果列表为空或者只有一个元素,则直接返回
if (teams.size() < 2) {
return teams;
}
// 将列表分为两部分
int midIndex = teams.size() / 2;
// 左边的列表
List<Team> left = new ArrayList<>(teams.subList(0, midIndex));
// 右边的列表
List<Team> right = new ArrayList<>(teams.subList(midIndex, teams.size()));
// 调用递归函数,分别对左右两边的列表进行排序
return merge(mergeSort(left), mergeSort(right));
}
/**
* 合并两个有序列表
* @param left 左边的列表
* @param right 右边的列表
* @return 合并后的列表
*/
private static List<Team> merge(List<Team> left, List<Team> right) {
// 合并后的列表
List<Team> merged = new ArrayList<>();
// 初始化左右两个列表的索引
int leftIndex = 0, rightIndex = 0;
// 循环比较两个列表的元素
while (leftIndex < left.size() && rightIndex < right.size()) {
// 如果左边的元素小于等于右边的元素,则将左边的元素添加到合并后的列表中
if (left.get(leftIndex).getEventCategory().compareTo(right.get(rightIndex).getEventCategory()) <= 0) {
merged.add(left.get(leftIndex++));
} else {
// 否则将右边的元素添加到合并后的列表中
merged.add(right.get(rightIndex++));
}
}
// 将剩余的元素添加到合并后的列表中
while (leftIndex < left.size()) {
merged.add(left.get(leftIndex++));
}
// 将剩余的元素添加到合并后的列表中
while (rightIndex < right.size()) {
merged.add(right.get(rightIndex++));
}
// 返回合并后的列表
return merged;
}
最后调用上述归并排序的方法,在查询到所有的同一学校的队伍信息后,调用 mergeSort 根据赛事类别进行排序后打印队伍信息即可。
对应部分的代码如下:
/**
* 根据参赛队伍名称查看参赛队伍信息
* @param schoolName 要查看的学校名称
*/
@Override
public void searchTeamsBySchoolName(String schoolName) {
// 声名一个新的数组,用于存放查找到的参赛队伍信息
List<Team> schoolTeams = new ArrayList<>();
// 遍历列表查找要查看的参赛队伍信息
for (Team team : TeamRepository.teamList) {
// 如果属于同一个学校,则将其添加到新的数组中
if (team.getSchoolName().trim().equals(schoolName.trim())) {
schoolTeams.add(team);
}
}
// 未找到对应的团队
if (schoolTeams.isEmpty()) {
System.out.println("没有找到对应的团队");
return;
}
// 对 schoolTeams 按 eventCategory 归并排序
schoolTeams = mergeSort(schoolTeams);
// 输出团队基本信息
System.out.println("--------------------- 查询结果 --------------------");
PrintUtil.printTeamList(schoolTeams);
}