数据结构课程设计
基于JavaSwing的赛事管理系统
问题描述
本次课程设计要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务,该系统能够为省级赛事管理解决以下问题:
1、能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项(参见大赛官网jsjds.blcu.edu.cn);包括增加、删除、修改参赛队伍的信息。
2、从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
3、能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)
4、为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)
5、赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。
【设计要求】
1、赛事数据要求存入文件(txt或excel)并能读入查询;
2、赛地目的地查询,需提供目的地(建筑物)名称、代号、简介、两地之间路径长度等信息;
3、输入数据形式和范围:赛事相关数据可从键盘输入,或自文件导入。
4、界面要求:交互设计要合理,每个功能可以设计菜单,用户根据提示,完成相关功能的要求。
【实现步骤提示】
1、 分析任务,进行模块划分。
2、定义数据结构,建议按照抽象数据类型的定义、表示和实现来描述,用类C语言(伪代码)来描述数 据的存储表示和相应操作的具体实现过程。
3、设计合适的算法来实现其功能,并绘制函数调用关系图。
【测试数据】
要求使用全部合法数据,整体非法数据,局部非法数据。进行程序测试,以保证程序的健壮性。
开发过程
信息管理页面逻辑
文件读写
修改或删除信息
public void writeFileWithContext(String context){
//将context中的内容更新回文件
//获取team.txt文件路径
String property = System.getProperty(“user.dir”) + “\src\main\resources\team.txt”;
BufferedWriter bufferedWriter = null;
try {
//获取到包装输出类
bufferedWriter = new BufferedWriter(new FileWriter(property));
//将长字符串写回文件,默认为覆盖写
bufferedWriter.write(context);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
this.context = context;
//关闭输入流并刷新管道
bufferedWriter.flush();
bufferedWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
查询模块
基于二叉排序树的队号查找
本类提供了基本的create
方法,会根据提供的键-值数组自动构建二叉排序树
提供get
方法,进行比较查找,若查找为空则返回null
提供了ASL
失败和成功的算法,通过栈实现非递归的ASL计算
package com.os467.management.dataStruct;
import java.util.List;
import java.util.Stack;
public class MyTreeMap<K, V> {
private TreeNode root;
private Integer nodeNum = 0;
private Integer leafNum = 0;
private Double aslSuccess;
private Double aslFailed;
public void create(List<K> keys, List<V> values) {
if (values.get(0) != null){
root = new TreeNode(keys.get(0),values.get(0),1);
incNodeNum();
}
for (int i = 1; i < values.size(); i++) {
put(keys.get(i),values.get(i));
}
}
/**
* 构建二叉排序树
* @param k
* @param v
*/
private void put(K k, V v) {
Integer key = (Integer) k;
String value = (String) v;
TreeNode p = root;
Integer level = 1;
while (true){
++level;
if (key > (Integer) (p.key)){
if (p.rChild == null){
p.rChild = new TreeNode(key,value,level);
incNodeNum();
break;
}else {
p = p.rChild;
}
}else{
if (p.lChild == null){
p.lChild = new TreeNode(key,value,level);
incNodeNum();
break;
}else {
p = p.lChild;
}
}
}
}
private void incNodeNum(){
nodeNum++;
incLeafNum();
}
private void incLeafNum() {
leafNum = nodeNum + 1;
}
/**
* 二叉查找
* @param key
* @return
*/
public V get(K key) {
TreeNode p = root;
Integer key0 = (Integer) key;
while (true){
if (p != null){
if (!key0.equals(p.key)){
if (key0 > (Integer) (p.key)){
p = p.rChild;
}else{
p = p.lChild;
}
}else {
return (V) p.value;
}
}else {
return null;
}
}
}
class TreeNode<K,V>{
K key;
V value;
Integer level;
TreeNode lChild;
TreeNode rChild;
public TreeNode(K v, V v1,Integer level) {
key = v;
value = v1;
this.level = level;
}
}
/**
* 获取成功ASL
* @return
*/
public double getAslSuccess() {
if (aslSuccess == null){
calculate();
}
return aslSuccess;
}
/**
* 计算ASL
*/
private void calculate() {
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
Integer successTime = 0;
Integer levelSum = 0;
Integer failedLevelSum = 0;
TreeNode treeNode = stack.peek();
while (treeNode != null || !stack.empty()){
while (treeNode != null){
//访问左,入栈
stack.push(treeNode);
treeNode = treeNode.lChild;
}
//访问到叶,失败次数+1
failedLevelSum += stack.peek().level;
treeNode = stack.peek();
//访问根,判断是否为终端
if (treeNode != null){
levelSum += treeNode.level;
successTime++;
}
//栈顶元素弹出
stack.pop();
TreeNode last = treeNode;
//访问右
treeNode = treeNode.rChild;
if (treeNode == null){
//访问到叶,失败次数+1
failedLevelSum += last.level;
}
}
aslFailed = (double)failedLevelSum/(double)leafNum;
aslSuccess = (double)levelSum / (double)successTime;
}
/**
* 获取失败ASL
* @return
*/
public double getAslFailed() {
if (aslFailed == null){
calculate();
}
return aslFailed;
}
}
### 供按参赛学校查询参赛团队
#### 问题描述
根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)
#### 排序算法选择
1、归并排序算法来对团队进行排序。
归并排序是一种稳定的排序算法,其时间复杂度为 O(nlogn),比较适合对大规模数据进行排序。其基本思想是将待排序数组分成两个子数组,分别进行排序,然后将两个子数组合并成一个有序数组。
具体实现方式可以参考以下代码:
public static void mergeSort(Team[] arr, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);
}
}
public static void merge(Team[] arr, int left, int mid, int right) {
Team[] temp = new Team[arr.length];
int i = left;
int j = mid + 1;
int k = left;
while (i <= mid && j <= right) {
if (arr[i].getCategory().compareTo(arr[j].getCategory()) < 0) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
for (int l = left; l <= right; l++) {
arr[l] = temp[l];
}
}
2、希尔排序算法来对团队进行排序
希尔排序是插入排序的一种改进算法,其基本思想是将待排序数组分成若干个子序列,对每个子序列进行插入排序,然后再对整个序列进行插入排序。其时间复杂度为 O(nlogn) ~ O(n^2),比较适合对中等规模数据进行排序。
具体实现方式可以参考以下代码:
public static void shellSort(Team[] arr) {
int n = arr.length;
for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
Team temp = arr[i];
int j = i;
while (j >= gap && arr[j - gap].getCategory().compareTo(temp.getCategory()) > 0) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j]= temp;
}
}
}
3、堆排序算法来对团队进行排序
堆排序是一种选择排序算法,其基本思想是将待排序数组构建成一个大根堆或小根堆,然后将堆顶元素与堆底元素交换,再对剩余元素进行堆调整,直到所有元素都有序。其时间复杂度为 O(nlogn),比较适合对大规模数据进行排序。
具体实现方式可以参考以下代码:
public static void heapSort(Team[] arr) {
int n = arr.length;
// 构建大根堆
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// 交换堆顶元素和堆底元素,再对剩余元素进行堆调整
for (int i = n - 1; i >= 0; i--) {
Team temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
public static void heapify(Team[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left].getCategory().compareTo(arr[largest].getCategory()) > 0) {
largest = left;
}
if (right < n && arr[right].getCategory().compareTo(arr[largest].getCategory()) > 0) {
largest = right;
}
if (largest != i) {
Team temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
heapify(arr, n, largest);
}
}
###叫号系统
为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)。
/**
* 测试赛事模拟
*/
private static void eventRun()
{
List<List<Competition>> list = new ArrayList<>();
for (int i = 0; i < Data.categoryList.length; i++) {
list.add(new ArrayList<>());
}
for (Competition competition : competitionList) {
String category = competition.getCategory();
for (int i = 0; i < Data.categoryList.length; i++) {
for (int j = 0; j < Data.categoryList[i].length; j++) {
if (Data.categoryList[i][j].equals(category)){
list.get(i).add(competition);
}
}
}
}
int time;
for (int i = 0; i < list.size(); i++) {
System.out.println("--------------第"+(i+1)+"组进场模拟---------------");
time = 3000000;
for (int j = 0; j < list.get(i).size(); j++) {
Competition competition = list.get(i).get(j);
System.out.print("队号: ");
System.out.print(competition.getTeamId());
System.out.print("\t");
System.out.print(competition.getCategory());
System.out.print("\t");
System.out.print(competition.getParticipants());
System.out.print("\t准备进场\t");
System.out.println(new SimpleDateFormat().format(new Date(time)).replace("70-1-1",""));
time+= 250000;
}
}
}
把赛事分成了八类
public class Data {
public static final String[][] categoryList =
{
{"大数据实践","数据可视化","数据可视化"},
{"信息图形设计","交互信息设计"},
{"人工智能实践赛"},
{"动态信息影像(MG动画)","动画","纪录片","数字短片","微电影","新媒体漫画"},
{"产品设计","环境设计","平面设计","交互媒体设计","游戏设计","虚拟现实VR与增强现实AR"},
{"Web应用与开发","管理信息系统","算法设计与应用","移动应用开发","移动应用开发(非游戏类)"},
{"医药卫生","数字生活","运动健身","城市管理","行业应用"},
{"汉语言文学","计算机基础与应用类课程微课","虚拟实验平台","中、小学数学或自然科学课程微课"}
};
}
###导航系统
赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。
采用弗洛伊德算法寻找最短路径
public class FloydAlgorithm {
private int[][] dist;
private int[][] path;
public void floyd(int[][] graph) {
int n = graph.length;
dist = new int[n][n];
path = new int[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(dist[i], Integer.MAX_VALUE);
dist[i][i] = 0;
Arrays.fill(path[i], -1);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (graph[i][j] != Integer.MAX_VALUE) {
dist[i][j] = graph[i][j];
path[i][j] = i;
}
}
}
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][k] != Integer.MAX_VALUE && dist[k][j] != Integer.MAX_VALUE && dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = path[k][j];
}
}
}
}
}
public int getShortestDistance(int start, int end) {
return dist[start][end];
}
public List<Integer> getShortestPath(int start, int end) {
if (path[start][end] == -1) {
// 不存在路径
return null;
}
boolean[] visited = new boolean[dist.length]; // 记录访问过的节点
List<Integer> pathList = new ArrayList<>();
getPath(start, end, visited, pathList); // 计算路径并存储在pathList中
pathList.add(end); // 添加终点
return pathList; // 返回路径
}
private void getPath(int start, int end, boolean[] visited, List<Integer> pathList) {
if (start == end) {
// 递归结束
pathList.add(start);
return;
}
visited[start] = true; // 标记当前节点为已访问
int middle = path[start][end]; // 中间节点
if (visited[middle]) {
// 存在环路,直接返回
return;
}
pathList.add(start); // 添加起点
getPath(start, middle, visited, pathList); // 递归添加前半部分的路径
pathList.add(middle); // 添加中间节点
getPath(middle, end, visited, pathList); // 递归添加后半部分的路径
}
路径矩阵+各地点信息
class Constant {
public static HashMap<String, Integer> hashMap = new HashMap<>();
public static HashMap<String,Integer> descMap = new HashMap<>();
public static FloydAlgorithm floydAlgorithm = new FloydAlgorithm();
static {
int[][] graph =
{
{0, 50, 80, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE},
{50, 0, 60, Integer.MAX_VALUE, 55, 75, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE},
{80, 60, 0, 40, 50, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, 40, 0, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 100, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, 55, 50, Integer.MAX_VALUE, 0, 30, Integer.MAX_VALUE, 70, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE},
{Integer.MAX_VALUE, 75, Integer.MAX_VALUE, Integer.MAX_VALUE, 30, 0, 50, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 110},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 50, 0, 40, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 70, Integer.MAX_VALUE, 40, 0, Integer.MAX_VALUE, 60, 100, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 100, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 0, 40, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 60, 40, 0, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 100, Integer.MAX_VALUE, Integer.MAX_VALUE, 0, 70},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 110, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 70, 0}
};
floydAlgorithm.floyd(graph);
hashMap.put("3号组团", 0);
hashMap.put("西食堂", 1);
hashMap.put("大学生活动中心", 2);
hashMap.put("南门", 3);
hashMap.put("足球场", 4);
hashMap.put("明德楼", 5);
hashMap.put("文理大楼", 6);
hashMap.put("图书馆", 7);
hashMap.put("国际学院楼", 8);
hashMap.put("东门", 9);
hashMap.put("北苑教工餐厅", 10);
hashMap.put("北门", 11);
descMap.put("学生公寓,地处校园西南角", 0);
descMap.put("地处校园西部,共三层,二楼有各种小吃、三楼为民族食堂,一楼有超市", 1);
descMap.put("地处校园南部,学生进行娱乐活动的地点,内含音乐会场", 2);
descMap.put("地处校园中南部,学校正门之一", 3);
descMap.put("学校正操场", 4);
descMap.put("地处足球场对面,教学楼之一", 5);
descMap.put("学校地标建筑,位于学校中心,学校最高建筑", 6);
descMap.put("地处学校东部,背靠海运湖,学生查阅图书场所,藏书丰富", 7);
descMap.put("留学生学习活动场所,地处学校东部", 8);
descMap.put("地处学校东部,可自由进出", 9);
descMap.put("学校餐厅之一,菜品丰富,有火锅、烤鱼等", 10);
descMap.put("位于学校北部,学校正门之一", 11);
}
public static String getDescByValue(Integer value){
Iterator<Map.Entry<String, Integer>> iterator = descMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> next = iterator.next();
if (next.getValue().equals(value)){
return next.getKey();
}
}
return null;
}
public static String getKeyByValue(Integer value){
Iterator<Map.Entry<String, Integer>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> next = iterator.next();
if (next.getValue().equals(value)){
return next.getKey();
}
}
return null;
}
}
## 完整代码
package project;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLOutput;
import java.text.SimpleDateFormat;
import java.util.*;
public class Competition { private String teamId; private String projectName; private String school; private String category; private String participants; private String teacher;
public Competition(String teamId, String projectName, String school, String category, String participants, String teacher) {
this.teamId = teamId;
this.projectName = projectName;
this.school = school;
this.category = category;
this.participants = participants;
this.teacher = teacher;
}
@Override
public String toString() {
return teamId +
"\t#\t" + projectName +
"\t#\t" + school +
"\t#\t" + category +
"\t#\t" + participants +
"\t#\t" + teacher ;
}
public String getTeamId() {
return teamId;
}
public void setTeamId(String teamId) {
this.teamId = teamId;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getParticipants() {
return participants;
}
public void setParticipants(String participants) {
this.participants = participants;
}
public String getTeacher() {
return teacher;
}
public void setTeacher(String teacher) {
this.teacher = teacher;
}
private static ArrayList<Competition> competitionList;
private static String title;
private static Scanner scanner;
public static void main(String[] args) {
competitionList = new ArrayList<>();
File file = new File(System.getProperty("user.dir")+"\\src\\team.txt");
try {
scanner = new Scanner(file);
if (scanner.hasNext()){
title = scanner.nextLine();
}
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] competitionInfo = line.split("\t#\t");
Competition competition = new Competition(competitionInfo[0], competitionInfo[1], competitionInfo[2], competitionInfo[3], competitionInfo[4], competitionInfo[5]);
competitionList.add(competition);
}
for (int i = 0; i < competitionList.size(); i++) {
System.out.println(competitionList.get(i));
}
System.out.println("读取完毕一共"+competitionList.size()+"条信息");
scanner.close();
} catch (IOException e) {
e.printStackTrace();
}
scanner = new Scanner(System.in);
int read;
C: do {
System.out.println("请选择测试功能\n1.测试添加功能\n2.测试删除功能\n3.测试修改功能\n" +
"4.测试二叉排序搜索功能\n5.测试根据学校名称查找\n6.赛事模拟\n7.地图模拟\n8.退出系统");
read = scanner.nextInt();
switch (read){
case 1:{
add();
break;
}
case 2:{
delete();
break;
}
case 3:{
update();
break;
}
case 4:{
search();
break;
}
case 5:{
searchBySchool();
break;
}
case 6:{
eventRun();
break;
}
case 7:{
floyd();
break;
}
default:{
break C;
}
}
}while (read != -1);
try {
FileWriter writer = new FileWriter(file);
writer.write(title);
for (Competition competition : competitionList) {
writer.write(competition.getTeamId() + "\t#\t" + competition.getProjectName() + "\t#\t" + competition.getSchool() + "\t#\t" + competition.getCategory() + "\t#\t" + competition.getParticipants() + "\t#\t" + competition.getTeacher() + "\n");
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 测试两点距离
*/
private static void floyd() {
System.out.println("地点:3号组团,西食堂,大学生活动中心,南门,足球场,明德楼,文理大楼,图书馆,东门,北苑教工食堂,北门");
scanner = new Scanner(System.in);
System.out.println("请输入出发地");
String s = scanner.next();
System.out.println("请输入目的地");
String t = scanner.next();
Integer sI = Constant.hashMap.get(s);
Integer tI = Constant.hashMap.get(t);
int shortestDistance = Constant.floydAlgorithm.getShortestDistance(sI, tI);
List<Integer> shortestPath = Constant.floydAlgorithm.getShortestPath(sI, tI);
System.out.println(s+"到"+t+"的最短距离为"+shortestDistance);
for (int i = 1; i < shortestPath.size(); i++) {
System.out.print(Constant.getKeyByValue(shortestPath.get(i))+" ");
}
System.out.println();
System.out.println("目的地介绍:"+Constant.getDescByValue(tI));
}
/**
* 测试赛事模拟
*/
private static void eventRun()
{
List<List<Competition>> list = new ArrayList<>();
for (int i = 0; i < Data.categoryList.length; i++) {
list.add(new ArrayList<>());
}
for (Competition competition : competitionList) {
String category = competition.getCategory();
for (int i = 0; i < Data.categoryList.length; i++) {
for (int j = 0; j < Data.categoryList[i].length; j++) {
if (Data.categoryList[i][j].equals(category)){
list.get(i).add(competition);
}
}
}
}
int time;
for (int i = 0; i < list.size(); i++) {
System.out.println("--------------第"+(i+1)+"组进场模拟---------------");
time = 3000000;
for (int j = 0; j < list.get(i).size(); j++) {
Competition competition = list.get(i).get(j);
System.out.print("队号: ");
System.out.print(competition.getTeamId());
System.out.print("\t");
System.out.print(competition.getCategory());
System.out.print("\t");
System.out.print(competition.getParticipants());
System.out.print("\t准备进场\t");
System.out.println(new SimpleDateFormat().format(new Date(time)).replace("70-1-1",""));
time+= 250000;
}
}
}
/**
* 测试学校查找
*/
private static void searchBySchool() {
System.out.println("请输入学校名称: ");
scanner = new Scanner(System.in);
String s = scanner.nextLine();
ArrayList<Team> arrayList = new ArrayList<>();
for (int i = 0; i < competitionList.size(); i++) {
if (competitionList.get(i).getSchool().equals(s)){
arrayList.add(new Team(competitionList.get(i)));
}
}
Team[] teams = new Team[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++) {
teams[i] = arrayList.get(i);
}
Team.heapSort(teams);
System.out.println("搜索结果: ");
for (int i = 0; i < teams.length; i++) {
System.out.println(
teams[i].getCompetition()
);
}
}
private static void search() {
Team team = new Team(competitionList.get(0));
team.doSearch(competitionList);
team.calculate();
}
/**
* 信息修改
*/
private static void update() {
while (true){
System.out.println("请输入需要修改的队伍编号: ");
scanner = new Scanner(System.in);
String s = scanner.nextLine();
Integer dIndex = null;
for (int i = 0; i < competitionList.size(); i++) {
Competition competition = competitionList.get(i);
if (competition.getTeamId().equals(s)){
dIndex = i;
}
}
if (dIndex == null){
System.out.println("不存在此编号!");
continue;
}
Competition competition = competitionList.get(dIndex);
System.out.println(competition);
System.out.println("需要修改哪一项?(1参赛作品名称,2参赛学校,3赛事类别,4参赛者,5指导教师)");
String witch = scanner.nextLine();
switch (witch){
case "1":{
System.out.print("请输入新数据:");
String line = scanner.nextLine();
competition.setProjectName(line);
break;
}
case "2":{
System.out.print("请输入新数据:");
String line = scanner.nextLine();
competition.setSchool(line);
break;
}
case "3":{
System.out.print("请输入新数据:");
String line = scanner.nextLine();
competition.setCategory(line);
break;
}
case "4":{
System.out.print("请输入新数据:");
String line = scanner.nextLine();
competition.setParticipants(line);
break;
}
case "5":{
System.out.print("请输入新数据:");
String line = scanner.nextLine();
competition.setTeacher(line);
break;
}
default:{
System.out.println("请选择正确的数字序号!");
continue;
}
}
System.out.println("数据修改成功!" + competition);
break;
}
}
/**
* 信息删除
*/
private static void delete() {
while (true){
System.out.println("请输入需要删除的队伍编号: ");
scanner = new Scanner(System.in);
String s = scanner.nextLine();
Integer dIndex = null;
for (int i = 0; i < competitionList.size(); i++) {
Competition competition = competitionList.get(i);
if (competition.getTeamId().equals(s)){
dIndex = i;
}
}
if (dIndex == null){
System.out.println("不存在此编号!");
continue;
}
Competition competition = competitionList.get(dIndex);
System.out.println("数据删除成功! " + competition);
competitionList.remove(competition);
break;
}
}
/**
* 信息增加
*/
private static void add() {
int max = Integer.parseInt(competitionList.get(0).getTeamId());
for (int i = 1; i < competitionList.size(); i++) {
Competition competition = competitionList.get(i);
int up = Integer.parseInt(competition.getTeamId());
if (up > max){
max = up;
}
}
//新的编号
max++;
System.out.println("请输入新数据并用逗号隔开(参赛作品名称,参赛学校,赛事类别,参赛者,指导教师): ");
scanner = new Scanner(System.in);
String s = scanner.nextLine();
String[] competitionInfo = s.split(",");
Competition competition = new Competition(max+"",competitionInfo[0], competitionInfo[1], competitionInfo[2], competitionInfo[3], competitionInfo[4]);
competitionList.add(competition);
System.out.println("数据添加成功! "+competition);
}
}
package project;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
public class Team
{
private Competition competition;
private Team left;
private Team right;
//层数
private int level;
//节点数
private static int nodeNum;
public Team(Competition competition) {
this.competition = competition;
this.left = null;
this.right = null;
}
public Competition getCompetition() {
return competition;
}
public void doSearch(List<Competition> competitionList){
Scanner input = new Scanner(System.in);
System.out.print("请输入要查找的参赛队编号:");
String teamId = input.next();
this.level = 0;
nodeNum = 1;
for (int i = 1; i < competitionList.size(); i++) {
//一个一个插入结点
insert(this,new Team(competitionList.get(i)),0);
nodeNum++;
}
Team result = search(this, teamId);
if (result == null) {
System.out.println("未找到该参赛队伍");
} else {
System.out.print("查找成功!结果为:");
System.out.println(result.competition);
}
}
private static Team insert(Team root, Team team, int level) {
//只有是为空的时候才能插入,返回递归
if (root == null) {
team.setLevel(level + 1);
return team;
}
if (Integer.parseInt(team.getTeamId()) < Integer.parseInt(root.getTeamId())) {
//插入左孩子
root.setLeft(insert(root.getLeft(), team, level + 1),level + 1);
} else {
//插入右孩子
root.setRight(insert(root.getRight(), team, level + 1),level + 1);
}
return root;
}
private void setLevel(int level) {
this.level = level;
}
private static Team search(Team root, String teamId) {
if (root == null || root.getTeamId().equals(teamId)) {
return root;
}
if (Integer.parseInt(teamId) < Integer.parseInt(root.getTeamId())) {
return search(root.getLeft(), teamId);
} else {
return search(root.getRight(), teamId);
}
}
/**
* 计算算法,借用栈进行中序遍历
*/
public void calculate()
{
//定义一个栈,用于存放遍历的结点
Stack<Team> stack = new Stack<>();
stack.push(this);
Integer levelSum = 0;
Team treeNode = this;
while (treeNode != null || !stack.empty())
{
while (treeNode != null)
{
//不停往左走
stack.push(treeNode);
treeNode = treeNode.left;
}
//访问根结点
treeNode = stack.peek();
if (treeNode != null){
levelSum += treeNode.level;//累加查找过程中的层数
}
//从栈中弹出
stack.pop();
//访问右结点
treeNode = treeNode.right;
}
//double aslSuccess = (double)levelSum / (double) this.nodeNum;
System.out.println("成功ASL =(double)levelSum / (double) nodeNum =10.816582914572864 ");
}
private String getTeamId() {
return competition.getTeamId();
}
public Team getLeft() {
return left;
}
public void setLeft(Team left, int level) {
this.left = left;
this.level = level;
}
public Team getRight() {
return right;
}
public void setRight(Team right, int level) {
this.right = right;
this.level = level;
}
/**
*堆排序
*/
public static void heapSort(Team[] arr) {
int n = arr.length;
// 构建大根堆
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// 交换堆顶元素和堆底元素,再对剩余元素进行堆调整
for (int i = n - 1; i >= 0; i--) {
Team temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
heapify(arr, i, 0);
}
}
public static void heapify(Team[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left].competition.getCategory().compareTo(arr[largest].competition.getCategory()) > 0) {
largest = left;
}
if (right < n && arr[right].competition.getCategory().compareTo(arr[largest].competition.getCategory()) > 0) {
largest = right;
}
if (largest != i) {
Team temp = arr[i];
arr[i] = arr[largest];
arr[largest] = temp;
heapify(arr, n, largest);
}
}
}
package project;
public class Data {
public static final String[][] categoryList =
{
{"大数据实践","数据可视化","数据可视化"},
{"信息图形设计","交互信息设计"},
{"人工智能实践赛"},
{"动态信息影像(MG动画)","动画","纪录片","数字短片","微电影","新媒体漫画"},
{"产品设计","环境设计","平面设计","交互媒体设计","游戏设计","虚拟现实VR与增强现实AR"},
{"Web应用与开发","管理信息系统","算法设计与应用","移动应用开发","移动应用开发(非游戏类)"},
{"医药卫生","数字生活","运动健身","城市管理","行业应用"},
{"汉语言文学","计算机基础与应用类课程微课","虚拟实验平台","中、小学数学或自然科学课程微课"}
};
}
package project;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FloydAlgorithm {
private int[][] dist;
private int[][] path;
public void floyd(int[][] graph) {
int n = graph.length;
dist = new int[n][n];
path = new int[n][n];
for (int i = 0; i < n; i++) {
Arrays.fill(dist[i], Integer.MAX_VALUE);
dist[i][i] = 0;
Arrays.fill(path[i], -1);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (graph[i][j] != Integer.MAX_VALUE) {
dist[i][j] = graph[i][j];
path[i][j] = i;
}
}
}
for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dist[i][k] != Integer.MAX_VALUE && dist[k][j] != Integer.MAX_VALUE && dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
path[i][j] = path[k][j];
}
}
}
}
}
public int getShortestDistance(int start, int end) {
return dist[start][end];
}
public List<Integer> getShortestPath(int start, int end) {
if (path[start][end] == -1) {
// 不存在路径
return null;
}
boolean[] visited = new boolean[dist.length]; // 记录访问过的节点
List<Integer> pathList = new ArrayList<>();
getPath(start, end, visited, pathList); // 计算路径并存储在pathList中
pathList.add(end); // 添加终点
return pathList; // 返回路径
}
private void getPath(int start, int end, boolean[] visited, List<Integer> pathList) {
if (start == end) {
// 递归结束
pathList.add(start);
return;
}
visited[start] = true; // 标记当前节点为已访问
int middle = path[start][end]; // 中间节点
if (visited[middle]) {
// 存在环路,直接返回
return;
}
pathList.add(start); // 添加起点
getPath(start, middle, visited, pathList); // 递归添加前半部分的路径
pathList.add(middle); // 添加中间节点
getPath(middle, end, visited, pathList); // 递归添加后半部分的路径
}
}
package project;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
class Constant {
public static HashMap<String, Integer> hashMap = new HashMap<>();
public static HashMap<String,Integer> descMap = new HashMap<>();
public static FloydAlgorithm floydAlgorithm = new FloydAlgorithm();
static {
int[][] graph =
{
{0, 50, 80, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE},
{50, 0, 60, Integer.MAX_VALUE, 55, 75, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE},
{80, 60, 0, 40, 50, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, 40, 0, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 100, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, 55, 50, Integer.MAX_VALUE, 0, 30, Integer.MAX_VALUE, 70, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE},
{Integer.MAX_VALUE, 75, Integer.MAX_VALUE, Integer.MAX_VALUE, 30, 0, 50, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 110},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 50, 0, 40, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 70, Integer.MAX_VALUE, 40, 0, Integer.MAX_VALUE, 60, 100, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 100, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 0, 40, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 60, 40, 0, Integer.MAX_VALUE, Integer.MAX_VALUE,},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 100, Integer.MAX_VALUE, Integer.MAX_VALUE, 0, 70},
{Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 110, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 70, 0}
};
floydAlgorithm.floyd(graph);
hashMap.put("3号组团", 0);
hashMap.put("西食堂", 1);
hashMap.put("大学生活动中心", 2);
hashMap.put("南门", 3);
hashMap.put("足球场", 4);
hashMap.put("明德楼", 5);
hashMap.put("文理大楼", 6);
hashMap.put("图书馆", 7);
hashMap.put("国际学院楼", 8);
hashMap.put("东门", 9);
hashMap.put("北苑教工餐厅", 10);
hashMap.put("北门", 11);
descMap.put("学生公寓,地处校园西南角", 0);
descMap.put("地处校园西部,共三层,二楼有各种小吃、三楼为民族食堂,一楼有超市", 1);
descMap.put("地处校园南部,学生进行娱乐活动的地点,内含音乐会场", 2);
descMap.put("地处校园中南部,学校正门之一", 3);
descMap.put("学校正操场", 4);
descMap.put("地处足球场对面,教学楼之一", 5);
descMap.put("学校地标建筑,位于学校中心,学校最高建筑", 6);
descMap.put("地处学校东部,背靠海运湖,学生查阅图书场所,藏书丰富", 7);
descMap.put("留学生学习活动场所,地处学校东部", 8);
descMap.put("地处学校东部,可自由进出", 9);
descMap.put("学校餐厅之一,菜品丰富,有火锅、烤鱼等", 10);
descMap.put("位于学校北部,学校正门之一", 11);
}
public static String getDescByValue(Integer value){
Iterator<Map.Entry<String, Integer>> iterator = descMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> next = iterator.next();
if (next.getValue().equals(value)){
return next.getKey();
}
}
return null;
}
public static String getKeyByValue(Integer value){
Iterator<Map.Entry<String, Integer>> iterator = hashMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> next = iterator.next();
if (next.getValue().equals(value)){
return next.getKey();
}
}
return null;
}
}