数据结构课程设计——赛事管理系统

1 问题描述:

本次课程设计要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务,该系统能够为省级赛事管理解决以下问题:

  1. 能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项;包括增加、删除、修改参赛队伍的信息。
  2. 从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。根据提示输入参赛队编号,若查找成功,输出该赛事类别对应的基本信息(参赛作品名称、参赛学校、赛事类别、参赛者和指导老师信息),同时,输出查找成功时的平均查找长度ASL;否则,输出“查找失败!”。
  3. 能够提供按参赛学校查询参赛团队(或根据赛事类别查询参赛团队),即,根据提示输入参赛学校名称(赛事类别),若查找成功,输出该学校参赛的(该赛事类别的)所有团队的基本信息,输出的参赛团队按赛事类别有序输出。(排序算法可从选择排序、插入排序、希尔排序、归并排序、堆排序中任意选择,并为选择算法的原因做出说明。)
  4. 为省赛现场设计一个决赛叫号系统。所有参赛队按赛事组织文件中的赛事类别分到9个决赛室,决赛室按顺序叫号,被叫号参赛队进场,比赛结束后,下一参赛队才能进赛场。请模拟决赛叫号系统,演示省赛现场各决赛室的参赛队进场情况。(模拟时,要能直观展示叫号顺序与进场秩序一致)
  5. 赛事系统为参赛者提供赛地的校园导游程序,为参赛者提供各种路径导航的查询服务。以我校长山校区提供比赛场地为例,(请为参赛者提供不少于10个目标地的导航。可为参赛者提供校园地图中任意目标地(建筑物)相关信息的查询;提供任意两个目标地(建筑物)的导航查询,即查询任意两个目的地(建筑物)之间的一条最短路径。

2、问题分析

1:管理各参赛队的基本信息,增删修改参赛队伍的信息。可以构建一个team结构体,利用函数读取文本中的信息,将各team放入二叉树中。

// 定义参赛队伍结构体
typedef struct {
    char teamID[20];
    char projectName[100];
    char school[50];
    char category[20];
    char participant[50];
    char advisor[50];
    char entrance[4];
} Team;
/*函数声明*/
// 从文件中读取参赛队伍的基本信息,构建二叉排序树
BSTNode* buildBSTFromFile(const char* filename);

// 在二叉排序树中插入参赛队伍
void insertTeam(BSTNode** root, Team team);

// 删除参赛队伍
void deleteTeam(BSTNode** root, char* teamID);

// 修改参赛队伍
void modifyTeam(BSTNode* root, char* teamID);

// 在二叉排序树中查找参赛队伍
BSTNode* searchTeam(BSTNode* root, char* teamID, int* asl);

// 打印参赛队伍的基本信息
void printTeamInfo(Team team);

// 打印比赛时,参赛队伍的基本信息
void printTeamInfoBattle(Team* team);

// *对排序
void sortByCategory(BSTNode* root, Team* entrance, char* category);

// 销毁二叉排序树
void destroyBST(BSTNode* root);

由于第2问有关二叉排序树的查找,所以构建一个二叉排序树的结构体

// 定义二叉排序树结点结构体
typedef struct BSTNode {
    Team team;
    struct BSTNode* left;
    struct BSTNode* right;
} BSTNode;

2从team.txt中读取信息,实现基于二叉树的查找

// 从文件中读取参赛队伍的基本信息,构建二叉排序树
BSTNode* root = buildBSTFromFile("team.txt");
 

// 定义二叉排序树结点结构体

typedef struct BSTNode {
    Team team;
    struct BSTNode* left;
    struct BSTNode* right;
} BSTNode;
STNode* searchTeam(BSTNode* root, char* teamID, int* asl) {
    if (root == NULL) {
        *asl = 0;
        return NULL;
    }

    BSTNode* current = root;
    int count = 0;

    // 在二叉排序树中查找指定的参赛队伍
    while (current != NULL) {
        count++;
        int cmp = strcmp(teamID, current->team.teamID);
        if (cmp == 0) {
            *asl = count;
            return current;
        }
        if (cmp < 0) {
            current = current->left;
        }
        else {
            current = current->right;
        }
    }

    *asl = count;
    return NULL;
}
  1. 首先,判断给定的根节点是否为空。如果为空,则返回 NULL 并将平均查找长度设置为 0。
  2. 如果给定的根节点不为空,则从该节点开始按照二叉排序树的查找规则进行查找。具体来说,每次比较查询关键字与当前节点存储的关键字(这里是参赛队伍的 ID)的大小,如果相等则说明已经找到目标节点,返回该节点指针并将查找的次数作为平均查找长度。
  3. 如果查询关键字小于当前节点的关键字,则向当前节点的左子树查找;否则向右子树查找,直到找到目标节点或遇到空节点为止。
  4. 最终,如果未能找到目标节点,则返回 NULL 并将查找的次数设置为平均查找长度。

3赛事类别查找参赛队伍

void printTeamsByCategory(BSTNode* root, char* category) {
    if (root == NULL) {
        //printf("没有找到相关的参赛队伍!\n");
        return;
    }
    if (root->left != NULL)
    {
        printTeamsByCategory(root->left, category);
    }

    if (strcmp(root->team.category, category) == 0) {
        printTeamInfo(root->team);
    }

    printTeamsByCategory(root->right, category);
}
  1. 首先,判断给定的根节点是否为空。如果为空,则直接返回。
  2. 如果给定的根节点不为空,就先递归地查找其左子树,以便按照关键字的大小顺序遍历整个树。
  3. 如果当前节点存储的参赛队伍所属类别和指定的查询类别相同,则输出该参赛队伍的信息。具体来说,调用 printTeamInfo() 函数将该参赛队伍的信息打印到控制台上。
  4. 最后,再递归地查找当前节点的右子树,继续按照关键字遍历二叉排序树。

4决赛摇号系统

const char* TypesAndEntrances[][2] = {
       {"大数据实践", "A"},
       {"信息图形设计", "A"},
       {"动态信息影像(MG动画)", "A"},
       {"交互信息设计", "A"},
       {"数据可视化", "A"},
       {"人工智能实践赛", "B"},
       {"Web应用与开发", "B"},
       {"管理信息系统", "B"},
       {"算法设计与应用", "B"},
       {"移动应用开发", "B"},
       {"医药卫生", "C"},
       {"数字生活", "C"},
       {"运动健身", "C"},
       {"城市管理", "D"},
       {"行业应用", "D"},
       {"动画", "E"},
       {"纪录片", "E"},
       {"数字短片", "E"},
       {"微电影", "E"},
       {"新媒体漫画", "F"},
       {"产品设计", "F"},
       {"环境设计", "F"},
       {"平面设计", "F"},
       {"交互媒体设计", "G"},
       {"游戏设计", "G"},
       {"虚拟现实VR与增强现实AR", "G"},
       {"汉语言文学", "I"},
       {"计算机基础与应用类课程微课", "I"},
       {"虚拟实验平台", "I"},
       {"中、小学数学或自然科学课程微课", "I"}
};

//延时函数
void delay(int milliseconds) {
    clock_t start_time = clock();
    while (clock() < start_time + milliseconds)
        ;
}

// 根据类型进行决赛分组
void sortByCategory(BSTNode* root, Team* entrance[], char* type) {
    if (root == NULL) {
        return;
    }
    if (root->left != NULL)
    {
        sortByCategory(root->left,entrance, type);
    }

    if (strcmp(root->team.entrance, type) == 0) {
        entrance[entranceCount] = &root->team;
        entranceCount++;
    }
    sortByCategory(root->right,entrance, type);
}
  1. 函数 sortByCategory() 实现参赛队伍按照比赛入口进行分组。具体来说,该函数的参数包括一个指向根节点的指针 root,一个存储参赛队伍信息的数组 entrance[],以及一个指向比赛入口字符串的指针 type。函数首先使用递归的方式遍历二叉排序树,将符合指定比赛入口的参赛队伍信息存储到 entrance[] 数组中,并过 entranceCount 记录已经存储的队伍数量。

5地图导航系统,设置了一个简易的地图查看系统

#include<iostream>
#include "stdio.h"
#include<iostream> 
#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
using namespace std;
using namespace cv;



int main(int argc, char** argv)
{
	int a;
	cout << "欢迎使用地图导航系统" << endl;
	cout << "江科大地图a,请按1" << endl;
	cout << "江科大地图b,请按2" << endl;
	cin >> a;
	if (a == 1)
	{
		Mat img = imread("C:\\Users\\lenovo\\Desktop\\数据结构课程设计\\江科大地图a.jpg");
		namedWindow("1");
		imshow("1", img);
		cv::waitKey(6000);
	}
	if (a == 2)
	{
		Mat img = imread("C:\\Users\\lenovo\\Desktop\\数据结构课程设计\\江科大地图b.jpg");
		namedWindow("2");
		imshow("2", img);
		cv::waitKey(6000);
	}
	return 0;
}

【设计要求】

  1. 1)赛事数据要求存入文件(txt或excel)并能读入查询;
  2. 2)赛地目的地查询,需提供目的地(建筑物)名称、代号、简介、两地之间路径长度等信息;
  3. 3)输入数据形式和范围:赛事相关数据可从键盘输入,或自文件导入。
  4. 4)界面要求:交互设计要合理,每个功能可以设计菜单,用户根据提示,完成相关功能的要求。
  5. #define _CRT_SECURE_NO_WARNINGS //避免VS报错
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    
    const char* TypesAndEntrances[][2] = {
           {"大数据实践", "A"},
           {"信息图形设计", "A"},
           {"动态信息影像(MG动画)", "A"},
           {"交互信息设计", "B"},
           {"数据可视化", "B"},
           {"人工智能实践赛", "B"},
           {"Web应用与开发", "C"},
           {"管理信息系统", "C"},
           {"算法设计与应用", "C"},
           {"移动应用开发", "D"},
           {"医药卫生", "D"},
           {"行业应用", "D"},
           {"数字生活", "E"},
           {"运动健身", "E"},
           {"城市管理", "E"},
           {"动画", "F"},
           {"纪录片", "F"},
           {"数字短片", "F"},
           {"微电影", "G"},
           {"新媒体漫画", "G"},
           {"产品设计", "G"},
           {"环境设计", "H"},
           {"平面设计", "H"},
           {"交互媒体设计", "H"},
           {"游戏设计", "I"},
           {"虚拟现实VR与增强现实AR", "I"},
           {"汉语言文学", "I"},
           {"计算机基础与应用类课程微课", "G"},
           {"虚拟实验平台", "F"},
           {"中、小学数学或自然科学课程微课", "E"}
    };
    
    //延时函数
    void delay(int milliseconds) {
        clock_t start_time = clock();
        while (clock() < start_time + milliseconds)
            ;
    }
    
    // 定义参赛队伍结构体
    typedef struct {
        char teamID[20];
        char projectName[100];
        char school[50];
        char category[20];
        char participant[50];
        char advisor[50];
        char entrance[4];
    } Team;
    
    // 定义二叉排序树结点结构体
    typedef struct BSTNode {
        Team team;
        struct BSTNode* left;
        struct BSTNode* right;
    } BSTNode;
    
    /*函数声明*/
    // 从文件中读取参赛队伍的基本信息,构建二叉排序树
    BSTNode* buildBSTFromFile(const char* filename);
    
    // 在二叉排序树中插入参赛队伍
    void insertTeam(BSTNode** root, Team team);
    
    // 删除参赛队伍
    void deleteTeam(BSTNode** root, char* teamID);
    
    // 修改参赛队伍
    void modifyTeam(BSTNode* root, char* teamID);
    
    // 在二叉排序树中查找参赛队伍
    BSTNode* searchTeam(BSTNode* root, char* teamID, int* asl);
    
    // 打印参赛队伍的基本信息
    void printTeamInfo(Team team);
    
    // 打印比赛时,参赛队伍的基本信息
    void printTeamInfoBattle(Team* team);
    
    // 按参赛学校查询参赛队伍
    void printTeamsBySchool(BSTNode* root, char* school);
    
    // 按赛事类别查询参赛队伍
    void printTeamsByCategory(BSTNode* root, char* category);
    
    // *对排序
    void sortByCategory(BSTNode* root, Team* entrance, char* category);
    
    // 销毁二叉排序树
    void destroyBST(BSTNode* root);
    
    // 将每个节点写入文件
    void updateFile(BSTNode* root, FILE* file) {
        if (root != NULL) {
            // 将左子树写入文件
            updateFile(root->left, file);
    
            // 将当前节点的内容写入文件
            fprintf(file, "%s\t#\t%s\t#\t%s\t#\t%s\t#\t%s\t#\t%s\n", root->team.teamID, root->team.projectName, root->team.school, root->team.category, root->team.participant, root->team.advisor);
    
            // 将右子树写入文件
            updateFile(root->right, file);
        }
    }
    
    // 打开文件,执行上面的递归函数
    void updata(BSTNode* root)
    {
        // 打开文件进行内容更新
        FILE* filez = fopen("team.txt", "w");
        if (filez == NULL) {
            printf("无法打开文件 team.txt\n");
            return;
        }
        // 遍历二叉排序树并将修改后的内容写入文件
        updateFile(root, filez);
    
        // 关闭文件
        fclose(filez);
    }
    // 最多地标点数和地标名称长度
    #define MAX_BUILDINGS 10
    #define MAX_NAME_LENGTH 20
    
    // 定义地标的结构体
    struct Building {
        int id;
        char name[MAX_NAME_LENGTH];
        char description[100];
    };
    
    // 定义两地距离
    struct Edge {
        int start;
        int end;
        int distance;
    };
    
    struct Graph {
        struct Building buildings[MAX_BUILDINGS];
        struct Edge edges[MAX_BUILDINGS * (MAX_BUILDINGS - 1) / 2];
        int numBuildings;
        int numEdges;
    };
    // 添加
    void addBuilding(struct Graph* graph, int id, const char* name, const char* description);
    void addEdge(struct Graph* graph, int start, int end, int distance);
    int findBuildingId(struct Graph* graph, const char* name);
    void printBuildingInfo(struct Graph* graph, const char* name);
    void navigate(struct Graph* graph, const char* startName, const char* endName);
    
    int choice; //将按键值作为全局变量
    int entranceCount = 0;//计数器
    Team* entranceA[30];
    Team* entranceB[30];
    Team* entranceC[30];
    Team* entranceD[30];
    Team* entranceE[30];
    Team* entranceF[30];
    Team* entranceG[30];
    Team* entranceH[30];
    Team* entranceI[30];
    
    int main() {
        BSTNode* root = buildBSTFromFile("team.txt"); // 从文件中读取参赛队伍的基本信息,构建二叉排序树
        srand(time(NULL));// 设置随机数种子
        // 定义变量
        char teamID[20];
        char school[50];
        char category[20];
        char siteA[20];
        char siteB[20];
        char buildingname[20];
    
        struct Graph graph;
        graph.numBuildings = 0;
        graph.numEdges = 0;
    
        FILE* buildingFile = fopen("地点.txt", "r");
        if (buildingFile == NULL) {
            printf("无法打开地点文件。\n");
            return 1;
        }
    
        char line[100];
        while (fgets(line, sizeof(line), buildingFile)) {
            char name[MAX_NAME_LENGTH];
            char description[100];
            sscanf(line, "%[^,],%[^\n]", name, description);
            addBuilding(&graph, graph.numBuildings + 1, name, description);
        }
    
        fclose(buildingFile);
    
        FILE* distanceFile = fopen("距离.txt", "r");
        if (distanceFile == NULL) {
            printf("无法打开距离文件。\n");
            return 1;
        }
    
        while (fgets(line, sizeof(line), distanceFile)) {
            char startName[MAX_NAME_LENGTH];
            char endName[MAX_NAME_LENGTH];
            int distance;
            sscanf(line, "%[^,],%[^,],%d", startName, endName, &distance);
            int start = findBuildingId(&graph, startName);
            int end = findBuildingId(&graph, endName);
            if (start != -1 && end != -1) {
                addEdge(&graph, start, end, distance);
            }
        }
    
        fclose(distanceFile);
    
        // 循环展示菜单,等待用户输入选项
        while (1) {
            printf("1. 插入参赛队伍\n");
            printf("2. 删除参赛队伍\n");
            printf("3. 修改参赛队伍\n");
            printf("4. 查找参赛队伍\n");
            printf("5. 按参赛学校查询参赛队伍\n");
            printf("6. 按赛事类别查询参赛队伍\n");
            printf("7. 建筑物介绍\n");
            printf("8. 导航查询最短距离\n");
            printf("9. 决赛叫号系统\n");
            printf("10. 退出\n");
            printf("请选择操作:");
            scanf("%d", &choice);
    
            switch (choice) {
            case 1:
                printf("请输入参赛队伍信息:\n");
                Team newTeam;
                printf("参赛队编号:");
                scanf("%s", newTeam.teamID);
                getchar();  // 消耗换行符
                printf("参赛作品名称:");
                fgets(newTeam.projectName, sizeof(newTeam.projectName), stdin);
                newTeam.projectName[strcspn(newTeam.projectName, "\n")] = '\0';
                printf("参赛学校:");
                fgets(newTeam.school, sizeof(newTeam.school), stdin);
                newTeam.school[strcspn(newTeam.school, "\n")] = '\0';
                printf("赛事类别:");
                fgets(newTeam.category, sizeof(newTeam.category), stdin);
                newTeam.category[strcspn(newTeam.category, "\n")] = '\0';
                printf("参赛者:");
                fgets(newTeam.participant, sizeof(newTeam.participant), stdin);
                newTeam.participant[strcspn(newTeam.participant, "\n")] = '\0';
                printf("指导老师:");
                fgets(newTeam.advisor, sizeof(newTeam.advisor), stdin);
                newTeam.advisor[strcspn(newTeam.advisor, "\n")] = '\0';
                insertTeam(&root, newTeam); // 插入新的参赛队伍
                updata(root);
                printf("参赛队伍插入成功!\n");
                break;
            case 2:
                printf("请输入要删除的参赛队编号:");
                scanf("%s", teamID);
                deleteTeam(&root, teamID); // 删除指定的参赛队伍
                break;
            case 3:
                printf("请输入要修改的参赛队编号:");
                scanf("%s", teamID);
                modifyTeam(root, teamID); // 修改指定的参赛队伍
                break;
            case 4:
                printf("请输入要查找的参赛队编号:");
                scanf("%s", teamID);
                int asl; // 用于记录查找操作中的平均查找长度
                BSTNode* result = searchTeam(root, teamID, &asl); // 查找指定的参赛队伍
                if (result != NULL) {
                    printf("查找成功!\n");
                    printf("平均查找长度:%d\n", asl);
                    printTeamInfo(result->team);
                }
                else {
                    printf("查找失败!\n");
                }
                break;
            case 5:
                printf("请输入要查询的参赛学校:");
                scanf("%s", school);
                printTeamsBySchool(root, school); // 按参赛学校查询参赛队伍
                break;
            case 6:
                printf("请输入要查询的赛事类别:");
                scanf("%s", category);
                printTeamsByCategory(root, category); // 按赛事类别查询参赛队伍
                break;
            case 7:
                printf("请输入想了解的建筑物:");
                scanf("%s", buildingname);
                printBuildingInfo(&graph, buildingname);
                break;
            case 8:
                printf("请输入当前位置:");
                scanf("%s", siteA);
                printf("请输入目的地:");
                scanf("%s", siteB);
                navigate(&graph, siteA, siteB); // 查询最短距离
                break;
            case 9:
                printf("叫号系统正在启动中:");
                //将不同类型分组
                sortByCategory(root,entranceA, "A");
                entranceCount = 0;
                sortByCategory(root, entranceB, "B");
                entranceCount = 0;
                sortByCategory(root, entranceC, "C");
                entranceCount = 0;
                sortByCategory(root, entranceD, "D");
                entranceCount = 0;
                sortByCategory(root, entranceE, "E");
                entranceCount = 0;
                sortByCategory(root, entranceF, "F");
                entranceCount = 0;
                sortByCategory(root, entranceG, "G");
                entranceCount = 0;
                sortByCategory(root, entranceH, "H");
                entranceCount = 0;
                sortByCategory(root, entranceI, "I");
                entranceCount = 0;
    
                int selectNum=0;
                printf("抽取的个数:");
                scanf("%d", &selectNum);
                for (size_t en = 0; en < selectNum; en++)
                {
                    
                    int randomNum = (rand() % 30) + 1;// 生成随机整数
                    printTeamInfoBattle(entranceA[randomNum], 1);
                    printTeamInfoBattle(entranceB[randomNum], 2);
                    printTeamInfoBattle(entranceC[randomNum], 3);
                    printTeamInfoBattle(entranceD[randomNum], 4);
                    printTeamInfoBattle(entranceE[randomNum], 5);
                    printTeamInfoBattle(entranceF[randomNum], 6);
                    printTeamInfoBattle(entranceG[randomNum], 7);
                    printTeamInfoBattle(entranceH[randomNum], 8);
                    printTeamInfoBattle(entranceI[randomNum], 9);
                }
                break;
            case 10:
                destroyBST(root);
                printf("程序已退出。\n");
                return 0;
                break;
            default:
                printf("无效的选项!\n");
                break;
            }
    
            printf("\n");
        }
    }
    
    BSTNode* buildBSTFromFile(const char* filename) {
        FILE* file = fopen(filename, "r");
        if (file == NULL) {
            printf("无法打开文件 %s\n", filename);
            return NULL;
        }
    
        BSTNode* root = NULL;
        char line[300];
    
        while (fgets(line, sizeof(line), file) != NULL) {
            line[strcspn(line, "\n")] = '\0';
    
            char* token = strtok(line, "\t#\t");
    
            Team team;
            strcpy(team.teamID, token);
    
            token = strtok(NULL, "\t#\t");
            strcpy(team.projectName, token);
    
            token = strtok(NULL, "\t#\t");
            strcpy(team.school, token);
    
            token = strtok(NULL, "\t#\t");
            strcpy(team.category, token);
    
            for (int i = 0; i < 30; i++) 
            {
                if (strcmp(token, TypesAndEntrances[i][0]) == 0) {
                    strcpy(team.entrance, TypesAndEntrances[i][1]);
                }
            }
    
            token = strtok(NULL, "\t#\t");
            strcpy(team.participant, token);
    
            token = strtok(NULL, "\t#\t");
            strcpy(team.advisor, token);
    
    
            insertTeam(&root, team);
        }
    
        fclose(file);
        return root;
    }
    
    void insertTeam(BSTNode** root, Team team) {
        BSTNode* newNode = (BSTNode*)malloc(sizeof(BSTNode));
        newNode->team = team;
        newNode->left = NULL;
        newNode->right = NULL;
    
        if (*root == NULL) {
            *root = newNode;
        }
        else {
            BSTNode* current = *root;
            while (1) {
                int cmp = strcmp(team.teamID, current->team.teamID);
                if (cmp < 0) {
                    if (current->left == NULL) {
                        current->left = newNode;//在左节点插入
                        break;
                    }
                    current = current->left;
                }
                else {
                    if (current->right == NULL) {
                        current->right = newNode;//在右节点插入
                        break;
                    }
                    current = current->right;
                }
            }
        }
    }
    
    void deleteTeam(BSTNode** root, char* teamID) {
        if (*root == NULL) {
            printf("没有找到相关的参赛队伍!\n");
            return;
        }
    
        BSTNode* parent = NULL;
        BSTNode* current = *root;
        int found = 0;
    
        // 在二叉排序树中查找要删除的参赛队伍
        while (current != NULL) {
            int cmp = strcmp(teamID, current->team.teamID);
            if (cmp == 0) {
                found = 1;
                break;
            }
            parent = current;
            if (cmp < 0) {
                current = current->left;
            }
            else {
                current = current->right;
            }
        }
    
        if (!found) {
            printf("没有找到相关的参赛队伍!\n");
            return;
        }
    
        // 根据情况删除参赛队伍
        if (current->left == NULL && current->right == NULL) {
            // 如果要删除的节点没有子节点
            if (parent == NULL) {
                *root = NULL;
            }
            else if (parent->left == current) {
                parent->left = NULL;
            }
            else {
                parent->right = NULL;
            }
            free(current);
        }
        // 如果要删除的节点只有一个子节点
        else if (current->left == NULL || current->right == NULL) {
            BSTNode* child = (current->left != NULL) ? current->left : current->right;
            if (parent == NULL) {
                *root = child;
            }
            else if (parent->left == current) {
                parent->left = child;
            }
            else {
                parent->right = child;
            }
            free(current);
        }
        // 如果要删除的节点有两个子节点
        else {
            BSTNode* successor = current->right;
            BSTNode* successorParent = current;
            while (successor->left != NULL) {
                successorParent = successor;
                successor = successor->left;
            }
            strcpy(current->team.teamID, successor->team.teamID);
            strcpy(current->team.projectName, successor->team.projectName);
            strcpy(current->team.school, successor->team.school);
            strcpy(current->team.category, successor->team.category);
            strcpy(current->team.participant, successor->team.participant);
            strcpy(current->team.advisor, successor->team.advisor);
            if (successorParent->left == successor) {
                successorParent->left = successor->right;
            }
            else {
                successorParent->right = successor->right;
            }
            free(successor);
        }
        updata(root);
        printf("参赛队伍删除成功!\n");
    }
    
    void modifyTeam(BSTNode* root, char* teamID) {
        if (root == NULL) {
            printf("没有找到相关的参赛队伍!\n");
            return;
        }
    
        BSTNode* current = root;
        int found = 0;
    
        // 在二叉排序树中查找要修改的参赛队伍
        while (current != NULL) {
            int cmp = strcmp(teamID, current->team.teamID);
            if (cmp == 0) {
                found = 1;
                break;
            }
            if (cmp < 0) {
                current = current->left;
            }
            else {
                current = current->right;
            }
        }
    
        if (!found) {
            printf("没有找到相关的参赛队伍!\n");
            return;
        }
        // 修改参赛队伍的信息
        printf("请输入修改后的参赛队伍信息:\n");
        printf("参赛队编号:");
        scanf("%s", current->team.teamID);
        getchar();  // 消耗换行符
        printf("参赛作品名称:");
        fgets(current->team.projectName, sizeof(current->team.projectName), stdin);
        current->team.projectName[strcspn(current->team.projectName, "\n")] = '\0';
        printf("参赛学校:");
        fgets(current->team.school, sizeof(current->team.school), stdin);
        current->team.school[strcspn(current->team.school, "\n")] = '\0';
        printf("赛事类别:");
        fgets(current->team.category, sizeof(current->team.category), stdin);
        current->team.category[strcspn(current->team.category, "\n")] = '\0';
        printf("参赛者:");
        fgets(current->team.participant, sizeof(current->team.participant), stdin);
        current->team.participant[strcspn(current->team.participant, "\n")] = '\0';
        printf("指导老师:");
        fgets(current->team.advisor, sizeof(current->team.advisor), stdin);
        current->team.advisor[strcspn(current->team.advisor, "\n")] = '\0';
        updata(root);
        printf("参赛队伍修改成功!\n");
    }
    
    BSTNode* searchTeam(BSTNode* root, char* teamID, int* asl) {
        if (root == NULL) {
            *asl = 0;
            return NULL;
        }
    
        BSTNode* current = root;
        int count = 0;
    
        // 在二叉排序树中查找指定的参赛队伍
        while (current != NULL) {
            count++;
            int cmp = strcmp(teamID, current->team.teamID);
            if (cmp == 0) {
                *asl = count;
                return current;
            }
            if (cmp < 0) {
                current = current->left;
            }
            else {
                current = current->right;
            }
        }
    
        *asl = count;
        return NULL;
    }
    
    void printTeamInfo(Team team) {
        printf("参赛队编号:%s\n", team.teamID);
        printf("参赛作品名称:%s\n", team.projectName);
        printf("参赛学校:%s\n", team.school);
        printf("赛事类别:%s\n", team.category);
        printf("参赛者:%s\n", team.participant);
        printf("指导老师:%s\n", team.advisor);
    }
    
    void printTeamInfoBattle(Team *team,int num) {
        if (team!=NULL)
        {
            printf("【决赛室%d】\n参赛队信息如下:\n", num);
            printf("队号:%s\n", team->teamID);
            printf("赛事类别:%s\n", team->entrance);
            printf("学校:%s\n", team->school);
            printf("项目名称:%s\n", team->projectName);
            printf("指导老师:%s\n", team->advisor);
            printf("参赛选手:%s\n", team->participant);
            printf("\n比赛进行中,请等待比赛结束……\n\n");
            delay(500);
        }
        else
        {
            printf("【决赛室%d】\n", num);
            printf("该决赛室内已无比赛选手……\n\n");
            delay(500);
        }
    }
    
    void printTeamsBySchool(BSTNode* root, char* school) {
        if (root == NULL) {
            //printf("没有找到相关的参赛队伍!\n");
            return;
        }
    
        if (strcmp(root->team.school, school) == 0) {
            printTeamInfo(root->team);
        }
    
        printTeamsBySchool(root->left, school);
        printTeamsBySchool(root->right, school);
    }
    
    void printTeamsByCategory(BSTNode* root, char* category) {
        if (root == NULL) {
            //printf("没有找到相关的参赛队伍!\n");
            return;
        }
        if (root->left != NULL)
        {
            printTeamsByCategory(root->left, category);
        }
    
        if (strcmp(root->team.category, category) == 0) {
            printTeamInfo(root->team);
        }
    
        printTeamsByCategory(root->right, category);
    }
    
    void destroyBST(BSTNode* root) {
        if (root != NULL) {
            destroyBST(root->left);
            destroyBST(root->right);
            free(root);
        }
    }
    
    
    void addBuilding(struct Graph* graph, int id, const char* name, const char* description) {
        struct Building building;
        building.id = id;
        strncpy(building.name, name, MAX_NAME_LENGTH - 1);
        building.name[MAX_NAME_LENGTH - 1] = '\0';
        strncpy(building.description, description, 99);
        building.description[99] = '\0';
        graph->buildings[graph->numBuildings++] = building;
    }
    
    void addEdge(struct Graph* graph, int start, int end, int distance) {
        struct Edge edge;
        edge.start = start;
        edge.end = end;
        edge.distance = distance;
        graph->edges[graph->numEdges++] = edge;
    }
    
    int findBuildingId(struct Graph* graph, const char* name) {
        for (int i = 0; i < graph->numBuildings; i++) {
            if (strcmp(graph->buildings[i].name, name) == 0) {
                return i;
            }
        }
        return -1;
    }
    
    // 查询建筑物介绍
    void printBuildingInfo(struct Graph* graph, const char* name) {
        int buildingId = findBuildingId(graph, name);
        if (buildingId == -1) {
            printf("无法找到指定的建筑物。\n");
            return;
        }
        printf("建筑物名称:%s\n", graph->buildings[buildingId].name);
        printf("建筑物介绍:%s\n", graph->buildings[buildingId].description);
    }
    
    // 查询两地最短距离
    void navigate(struct Graph* graph, const char* startName, const char* endName) {
        int start = findBuildingId(graph, startName);
        int end = findBuildingId(graph, endName);
        if (start == -1 || end == -1) {
            printf("无法找到指定的建筑物。\n");
            return;
        }
    
        int distances[MAX_BUILDINGS];
        int previous[MAX_BUILDINGS];
        int visited[MAX_BUILDINGS];
        int numVisited = 0;
    
        for (int i = 0; i < graph->numBuildings; i++) {
            distances[i] = INT_MAX;
            previous[i] = -1;
            visited[i] = 0;
        }
    
        distances[start] = 0;
    
        while (numVisited < graph->numBuildings) {
            int minDistance = INT_MAX;
            int current = -1;
    
            for (int i = 0; i < graph->numBuildings; i++) {
                if (!visited[i] && distances[i] < minDistance) {
                    minDistance = distances[i];
                    current = i;
                }
            }
    
            if (current == -1) {
                break;
            }
    
            visited[current] = 1;
            numVisited++;
    
            for (int i = 0; i < graph->numEdges; i++) {
                if (graph->edges[i].start == current) {
                    int neighbor = graph->edges[i].end;
                    int distance = graph->edges[i].distance;
                    int totalDistance = distances[current] + distance;
    
                    if (totalDistance < distances[neighbor]) {
                        distances[neighbor] = totalDistance;
                        previous[neighbor] = current;
                    }
                }
            }
        }
    
        if (previous[end] == -1) {
            printf("无法找到从%s到%s的路径。\n", startName, endName);
            return;
        }
    
        printf("从%s到%s的最短路径为:\n", startName, endName);
        printf("%s", graph->buildings[start].name);
    
        int path[MAX_BUILDINGS];
        int pathLength = 0;
        int current = end;
    
        while (current != start) {
            path[pathLength++] = current;
            current = previous[current];
        }
    
        for (int i = pathLength - 1; i >= 0; i--) {
            printf(" -> %s", graph->buildings[path[i]].name);
        }
    
        printf("\n");
    }
    // 根据类型进行决赛分组
    void sortByCategory(BSTNode* root, Team* entrance[], char* type) {
        if (root == NULL) {
            return;
        }
        if (root->left != NULL)
        {
            sortByCategory(root->left,entrance, type);
        }
    
        if (strcmp(root->team.entrance, type) == 0) {
            entrance[entranceCount] = &root->team;
            entranceCount++;
        }
        sortByCategory(root->right,entrance, type);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值