【用C语言描述数据结构】课程设计:歌手比赛系统,2024年大数据开发知识体系总结

36 阅读14分钟
printf("=========请选择操作============\n");
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("========0.退出系统============\n");
printf("=============================\n");

}


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0e55b875ce734dd0ad9707cc7ffec66f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=2GCq0xr%2FC2doFmGP13dYPb3Fxxg%3D)


### 3.输入选手数据模块



//1.输入选手数据 S *create() { S *head, *p, *q;//定义指针 int i; head = (S *) malloc(sizeof(S));//头节点开辟空间 head->average = 0;//置空头节点的average成员 head->next = NULL;//置空头节点的指针域 q = head;//q指针记录头节点的地址 p = head->next;//p指针记录头节点的指针域的地址 printf("请输入选手编号和姓名(编号为0则表示停止):\n"); int id; printf("请输入选手id(输入0退出):\n"); scanf("%d", &id); while (id != 0)//输入选手编号输入为零停止循环 { p = (S *) malloc(sizeof(S));//p指针开辟空间 p->id = id; printf("请输入选手姓名:\n"); scanf("%s", p->name); for (i = 0; i < NUMBER; i++) { p->grade[i] = 0; } p->sum = 0; p->average = 0; p->next = NULL;//置空p节点的指针域 q->next = p;//p,q节点连接 q = p;//q指针后移 printf("请输入选手id(输入0退出):\n"); scanf("%d", &id); } return head;//返回链表的起始地址 }


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/d08c5cfc136749afb6a322eda9fee850~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=XBKain%2FR1IJr0ctOB4J5ngYiKuY%3D)


### 4.评委打分模块



//2.评委打分 void giveScore(S *head) { //定义指针 S *p; p = head->next; float max, min; while (p != NULL) { if (p->grade[0] != 0) { p = p->next; continue; } printf("请十位评为给编号为%d的选手打分:\n", p->id); p->sum = 0; for (int i = 0; i < NUMBER; i++) { printf("请第%d位评委打分:", i); scanf("%f", &p->grade[i]); p->sum += p->grade[i]; } printf("\n"); min = max = p->grade[0]; for (int i = 0; i < NUMBER; i++) { if (p->grade[i] > max) max = p->grade[i]; if (p->grade[i] < min) min = p->grade[i]; } p->average = (p->sum - max - min) / 8; p = p->next; } }


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/cf28d4f651ea4c08afa5314447dea2e2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=%2Bs%2FxtEqODw%2FTYBIPef2gDe1k1pE%3D)


### 5.按照平均成绩排序 – 采用冒泡排序,交换节点



//3.按照平均成绩排序 -- 采用冒泡排序,交换节点 void sort(S *head) { S *p, *pre, *temp, *tail;

tail = NULL;

// 算法的核心部分,节点交换 while (head->next != tail) { pre = head; p = head->next; while (p->next != tail) { if (p->average < p->next->average) { temp = p->next; pre->next = p->next; p->next = p->next->next; pre->next->next = p; p = temp; } // 节点后移 p = p->next; pre = pre->next; } tail = p; } }


### 6.数据查询模块



//4.根据id查找节点模块 void search(S *head) { S *p;//定义指针 int id;//定义b用于输入查找编号 printf("请输入要查找的选手编号:"); //输入查找编号 scanf("%d", &id); p = head->next; while (p != NULL) { if (p->id == id)//判断是否找到选手编号 { //为真时,输出信息 printf("编号\t姓名\t\t\t\t\t十位评委的成绩\t\t\t\t\t总成绩\t平均成绩\n"); printf("%d %s %.2f%.2f%.2f%.2f%.2f%.2f%.2f%.2f%.2f%.2f %.2f %.2f\n", p->id, p->name, p->grade[0], p->grade[1], p->grade[2], p->grade[3], p->grade[4], p->grade[5], p->grade[6], p->grade[7], p->grade[8], p->grade[9], p->sum, p->average); break; } else //为假时 p = p->next;//指针后移 } if (p == NULL)//查找到最后一个节点还未查到要的编号时,输出ERROR INPUT printf("输入的选手编号错误\n"); }


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c75662b8399845f98d9d9154d70a1448~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=AcmovvOLFndHPK6z1uwJUyrKg00%3D)


### 7.追加选手数据模块



//5.追加节点模块(可多个插入) void insert(S *head) { int i, id, flag = 1;//flag实现判断指针是否到达最后一个节点 S *p, *q, *r; //定义指针便于插入操作 p = head; printf("请输入选手信息:\n"); printf("请输入选手id(输入0退出):\n"); scanf("%d", &id); while (id != 0)//输入编号不为零时循环,以零终止,可实现多个插入 { r = (S *) malloc(sizeof(S));//为r开辟空间 r->next = NULL;//置空r的指针域 //输入相关数据,并计算相关数据 r->id = id; printf("请输入选手姓名:\n"); scanf("%s", r->name); r->sum = 0; r->average = 0; for (i = 0; i < NUMBER; i++) { r->grade[i] = 0; }

    while (p->next != NULL) {
        p = p->next;
    }
    p->next = r;

    printf("请输入选手id(输入0退出):\n");
    scanf("%d", &id);
}

}


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/754ad7a5c25a4ce8884d2e8718bb4e5e~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=AkYBNj5BEToRlHCwDY3zF%2FAAFvo%3D)


### 8.删除选手信息模块



//6.删除节点模块 void del(S *head) { S *p, *q;//定义指针 int b;//用于输入编号查找删除 p = head;//p记录头节点的地址 q = head->next;//q记录头节点的指针域的地址 printf("请输入要删除选手的id:"); //输入编号 scanf("%d", &b); while (q != NULL)//q不为空时执行循环 { if (q->id == b)//判断是否找到输入的编号 //为真时 { p->next = q->next;//断开q节点 free(q);//释放q节点neicun q = NULL; //置空q指针防止出现野指针 } else { //判断为假时 p = p->next;//p指针后移 q = q->next;//q指针后移 } } if (p == NULL)//当查找到最后一个节点还未查到要删除的编号时,输出ERROR INPUT printf("输入的选手id不存在!\n"); }


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/b9a6b30d32964d5a8aa806f18cea18f2~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=8eZ75ZLq2TUVnr3l0xnyyNysAfY%3D)


### 9.修改选手信息模块



//修改选手信息 void update(S *head) { S *p, *q, *new;//定义指针 int id;//用于输入编号查找删除 float min = 999, max = 0; p = head;//p记录头节点的地址 q = head->next;//q记录头节点的指针域的地址 printf("请输入要修改的选手id:"); //输入编号 scanf("%d", &id); while (q != NULL)//q不为空时执行循环 { //判断是否找到输入的编号 if (q->id == id) { new = (S *) malloc(sizeof(S)); printf("请输入%d号选手的新成绩:", q->id); new->id = q->id; strcpy(new->name, q->name); new->sum = 0; new->average = 0; for (int i = 0; i < NUMBER; ++i) { scanf("%f", &new->grade[i]); new->sum += new->grade[i]; if (new->grade[i] > max) { max = new->grade[i]; } if (new->grade[i] < min) { min = new->grade[i]; } } new->average = (new->sum - max - min) / (NUMBER - 2); new->next = q->next;//断开q节点 p->next = new; free(q);//释放q节点 q = NULL; //置空q指针防止出现野指针 } else { //判断为假时 p = p->next;//p指针后移 q = q->next;//q指针后移 } } if (p == NULL)//当查找到最后一个节点还未查到要修改的编号时 printf("输入的选手id不存在!\n"); }


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/fe64777762fd4659b3dc53a8cc111b5a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=pccOhVu3xjw1IibmjGSeTgiWKWc%3D)


### 10.输出全部选手信息模块



//7.输出全部选手信息 void print(S *head) { int i; S *p = head->next; printf("编号\t姓名\t总成绩\t平均成绩\t\t\t\t\t十位评委的成绩\t\t\t\t\n"); while (p)//当p不为空的时候执行 { printf("%-d\t%-s\t%-.2f\t%-.2f\t", p->id, p->name, p->sum, p->average); for (i = 0; i < NUMBER; i++) printf("%-6.2f\t", p->grade[i]); printf("\n"); p = p->next;//指针后移 } }


* 运行结果如下:  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7402c15a3c9946928504f760e32b69f4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1771866664&x-signature=IlscBa0z9rpH4QmEuFYt3%2FjOpfA%3D)


### 11.写入数据文件(记得修改写入文件地址)



//8.写入数据文件 void save(S *head) { S *p; p = head->next; FILE *fp; if ((fp = fopen("C:\Users\zhuxuanyu\Desktop\file.txt", "wt")) == NULL) { printf("打开写入文件fle.txt失败\n"); return; } while (p) { fprintf(fp, "编号:%-d\t 姓名:%-s\t 总成绩:%-.2f\t 平均成绩:%-.2f\t 评委打分:", p->id, p->name, p->sum, p->average); for (int i = 0; i < NUMBER; ++i) { fprintf(fp, "%-.2f\t", p->grade[i]); } fprintf(fp, "\n"); p = p->next; } fclose(fp); }


## 五、完整代码



#include <stdio.h> #include <stdlib.h> #include <string.h> //创建结构体及其成员

#define MAXSIZE 20 #define NUMBER 10

typedef struct Node { int id;//编号 char name[MAXSIZE];//姓名 float grade[NUMBER];//评委评分 float sum;//总分 float average;//平均分 struct Node *next;//指针域 } S;//结构体定义为S //各函数定义 void menu(); //菜单函数 S *create();//创建链表函数 void print(S *);//输出链表函数 void insert(S *);//插入节点函数 void del(S *);//删除节点函数 void update(S *);

void search(S *);//查找节点函数 void sort(S *);//节点排序函数 void save(S *);

void giveScore(S *);

//主函数 int main() { S *head; int n, a = 1;//n用来控制选择操作类型,a控制循环,以-1终止 while (a > 0) { menu();//显示菜单 printf("请输入操作数:"); scanf("%d", &n);//选择操作 switch (n)//各操作数字对应菜单数字,通过n确定操作类型 { //创建结点,输入选手数据 case 1: head = create(); break; //评委打分 case 2: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } giveScore(head); break; //排序 case 3: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } sort(head); break; //查询 case 4: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } search(head); break; //追加数据 case 5: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } insert(head); break; //删除 case 6: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } del(head); break; //修改数据 case 7: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } update(head); break; //输出全部选手信息 case 8: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } print(head); break; //写入文件 case 9: if (head == NULL) { printf("链表为空,请先执行1操作!\n"); break; } save(head); break; //退出系统 case 0: exit(0); break; default: printf("退出系统"); a = -1;//跳出循环条件 break; } } return 0; }

//菜单模块直接显示 void menu() { printf("==============================\n"); printf("=========请选择操作============\n"); 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("========0.退出系统============\n"); printf("=============================\n"); }

//1.输入选手数据 S *create() { S *head, *p, *q;//定义指针 int i; head = (S *) malloc(sizeof(S));//头节点开辟空间 head->average = 0;//置空头节点的average成员 head->next = NULL;//置空头节点的指针域 q = head;//q指针记录头节点的地址 p = head->next;//p指针记录头节点的指针域的地址 printf("请输入选手编号和姓名(编号为0则表示停止):\n"); int id; printf("请输入选手id(输入0退出):\n"); scanf("%d", &id); while (id != 0)//输入选手编号输入为零停止循环 { p = (S *) malloc(sizeof(S));//p指针开辟空间 p->id = id; printf("请输入选手姓名:\n"); scanf("%s", p->name); for (i = 0; i < NUMBER; i++) { p->grade[i] = 0; } p->sum = 0; p->average = 0; p->next = NULL;//置空p节点的指针域 q->next = p;//p,q节点连接 q = p;//q指针后移 printf("请输入选手id(输入0退出):\n"); scanf("%d", &id); } return head;//返回链表的起始地址 }

//2.评委打分 void giveScore(S *head) { //定义指针 S *p; p = head->next; float max, min; while (p != NULL) { if (p->grade[0] != 0) { p = p->next; continue; } printf("请十位评为给编号为%d的选手打分:\n", p->id); p->sum = 0; for (int i = 0; i < NUMBER; i++) { printf("请第%d位评委打分:", i); scanf("%f", &p->grade[i]); p->sum += p->grade[i]; } printf("\n"); min = max = p->grade[0]; for (int i = 0; i < NUMBER; i++) { if (p->grade[i] > max) max = p->grade[i]; if (p->grade[i] < min) min = p->grade[i]; } p->average = (p->sum - max - min) / 8; p = p->next; } }

//3.按照平均成绩排序 -- 采用冒泡排序,交换节点 void sort(S *head) { S *p, *pre, *temp, *tail;

tail = NULL;

// 算法的核心部分,节点交换 while (head->next != tail) { pre = head; p = head->next; while (p->next != tail) { if (p->average < p->next->average) { temp = p->next; pre->next = p->next; p->next = p->next->next; pre->next->next = p; p = temp; } // 节点后移 p = p->next; pre = pre->next; } tail = p; } }

//4.根据id查找节点模块 void search(S *head) { S *p;//定义指针 int id;//定义b用于输入查找编号 printf("请输入要查找的选手编号:"); //输入查找编号 scanf("%d", &id); p = head->next; while (p != NULL) { if (p->id == id)//判断是否找到选手编号 { //为真时,输出信息 printf("编号\t姓名\t\t\t\t\t十位评委的成绩\t\t\t\t\t总成绩\t平均成绩\n"); printf("%d %s %.2f%.2f%.2f%.2f%.2f%.2f%.2f%.2f%.2f%.2f %.2f %.2f\n", p->id, p->name, p->grade[0], p->grade[1], p->grade[2], p->grade[3], p->grade[4], p->grade[5], p->grade[6], p->grade[7], p->grade[8], p->grade[9], p->sum, p->average); break; } else //为假时 p = p->next;//指针后移 } if (p == NULL)//查找到最后一个节点还未查到要的编号时,输出ERROR INPUT printf("输入的选手编号错误\n"); }

//5.追加节点模块(可多个插入) void insert(S *head) { int i, id, flag = 1;//flag实现判断指针是否到达最后一个节点 S *p, *q, *r; //定义指针便于插入操作 p = head; printf("请输入选手信息:\n"); printf("请输入选手id(输入0退出):\n"); scanf("%d", &id); while (id != 0)//输入编号不为零时循环,以零终止,可实现多个插入 { r = (S *) malloc(sizeof(S));//为r开辟空间 r->next = NULL;//置空r的指针域 //输入相关数据,并计算相关数据 r->id = id; printf("请输入选手姓名:\n"); scanf("%s", r->name); r->sum = 0; r->average = 0; for (i = 0; i < NUMBER; i++) { r->grade[i] = 0; }

    while (p->next != NULL) {
        p = p->next;
    }
    p->next = r;

    printf("请输入选手id(输入0退出):\n");
    scanf("%d", &id);
}

}

//6.删除节点模块 void del(S *head) { S *p, *q;//定义指针 int b;//用于输入编号查找删除 p = head;//p记录头节点的地址 q = head->next;//q记录头节点的指针域的地址 printf("请输入要删除选手的id:"); //输入编号 scanf("%d", &b); while (q != NULL)//q不为空时执行循环 { if (q->id == b)//判断是否找到输入的编号 //为真时 { p->next = q->next;//断开q节点 free(q);//释放q节点neicun q = NULL; //置空q指针防止出现野指针 } else { //判断为假时 p = p->next;//p指针后移 q = q->next;//q指针后移 } } if (p == NULL)//当查找到最后一个节点还未查到要删除的编号时,输出ERROR INPUT printf("输入的选手id不存在!\n"); }

//修改选手信息 void update(S *head) { S *p, *q, *new;//定义指针 int id;//用于输入编号查找删除 float min = 999, max = 0; p = head;//p记录头节点的地址 q = head->next;//q记录头节点的指针域的地址 printf("请输入要修改的选手id:"); //输入编号 scanf("%d", &id); while (q != NULL)//q不为空时执行循环 { //判断是否找到输入的编号 if (q->id == id) { new = (S *) malloc(sizeof(S)); printf("请输入%d号选手的新成绩:", q->id); new->id = q->id; strcpy(new->name, q->name); new->sum = 0; new->average = 0; for (int i = 0; i < NUMBER; ++i) { scanf("%f", &new->grade[i]); new->sum += new->grade[i]; if (new->grade[i] > max) { max = new->grade[i]; } if (new->grade[i] < min) { min = new->grade[i]; } } new->average = (new->sum - max - min) / (NUMBER - 2); new->next = q->next;//断开q节点 p->next = new; free(q);//释放q节点 q = NULL; //置空q指针防止出现野指针 } else { //判断为假时 p = p->next;//p指针后移 q = q->next;//q指针后移 } } if (p == NULL)//当查找到最后一个节点还未查到要修改的编号时 printf("输入的选手id不存在!\n"); }

//7.输出全部选手信息 void print(S *head) { int i; S *p = head->next; printf("编号\t姓名\t总成绩\t平均成绩\t\t\t\t\t十位评委的成绩\t\t\t\t\n"); while (p)//当p不为空的时候执行 { printf("%-d\t%-s\t%-.2f\t%-.2f\t", p->id, p->name, p->sum, p->average); for (i = 0; i < NUMBER; i++) printf("%-6.2f\t", p->grade[i]); printf("\n"); p = p->next;//指针后移 } }

//8.写入数据文件(记得修改文件地址)

void save(S *head) { S *p; p = head->next;

img img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!