题目:高校最低录取分数线的查询
编程实现一个开放式的高校本科招生最低分数线的查询系统,供师生及家长等查询,高校自愿放入该校的信息,可能随时有高校加入。
要求实现的查询功能有:
- 查询等于用户给定分数的高校
- 查询大于(或小于)用户给定分数的高校
- 查询最低录取分数线的用户给定的分数段中的高校
以上就是老师给定题目中要求实现的功能,为了是程序整体更加完整,自己对高校使用部分做了一些功能添加,例如学校信息的增删改查等功能。
题目分析:
该设计重要功能是查找,查找表为高校最低录取分数信息的集合。根据题意可知,该查找表中的元素个数可能随时增减,所以它是一个动态查找表,可采用树状结构保存。为了提高查询速度,可建立二叉排序树并在二叉排序树中实现查找。
程序的代码结构:
- 头文件的引入以及结构体的定义
1 #include <string.h> 2 #include <ctype.h> 3 #include <malloc.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 7 #define TRUE 1 8 #define FALSE 0 9 #define OK 1 10 #define ERROR 0 11 12 typedef int Status; 13 14 typedef struct node{ 15 struct node *lchild; 16 struct node *rchild; 17 int grade; 18 char university[36]; 19 }BiTreeNode, *BiTree; 20 21 typedef struct element{ 22 int grade; 23 char university[30]; 24 }Information;
- 创建节点
1 Status CreateBiTree(BiTree &T){ 2 T=(BiTree)malloc(sizeof(BiTreeNode)); 3 T->lchild = NULL; 4 T->rchild = NULL; 5 return OK; 6 }
- 高校信息的插入
1 Status InsertData(BiTree &T,Information mess){ 2 BiTree NT; 3 if(T==NULL){ 4 CreateBiTree(T); 5 T->grade=mess.grade; 6 strcpy(T->university,mess.university); 7 }else{ 8 if(mess.grade<T->grade){ 9 if(T->lchild==NULL){ 10 CreateBiTree(NT); 11 T->lchild=NT; 12 NT->grade=mess.grade; 13 strcpy(NT->university,mess.university); 14 }else 15 InsertData(T->lchild,mess); 16 }else{ 17 if(T->rchild==NULL){ 18 CreateBiTree(NT); 19 T->rchild=NT; 20 NT->grade=mess.grade; 21 strcpy(NT->university,mess.university); 22 }else 23 InsertData(T->rchild,mess); 24 } 25 } 26 return OK; 27 }
- 查找相应的学校,存在返回结构体指针T,否则返回NULL,其中FT为查找到节点T的父母节点,lr用来表明为其左右子树(0为左子树,1为右子树)
1 BiTree FindUniversity(BiTree T,BiTree &FT,Information mess,int &lr){ 2 BiTree BT=NULL; 3 if(T->lchild){ 4 if(FindUniversity(T->lchild,FT,mess,lr)) 5 BT=FindUniversity(T->lchild,FT,mess,lr); 6 if(strcmp(T->lchild->university,mess.university)==0){ 7 FT=T; 8 lr=0; 9 } 10 } 11 if(strcmp(T->university,mess.university)==0){ 12 return T; 13 } 14 if(T->rchild){ 15 if(FindUniversity(T->rchild,FT,mess,lr)) 16 BT=FindUniversity(T->rchild,FT,mess,lr); 17 if(strcmp(T->rchild->university,mess.university)==0){ 18 FT=T; 19 lr=1; 20 } 21 } 22 return BT; 23 }
- 删除学校
1 Status DeleteData(BiTree &T,Information mess){ 2 BiTree NT=NULL,FT=NULL,GT=NULL,LT=NULL; 3 int lr=3; 4 if(NT=FindUniversity(T,FT,mess,lr)){ 5 if(NT->lchild==NULL&&NT->rchild==NULL){ 6 free(NT); 7 if(lr==0) 8 FT->lchild=NULL; 9 else if(lr==1) 10 FT->rchild=NULL; 11 else 12 T=NULL; 13 }else if(NT->lchild==NULL){ 14 if(lr==0) 15 FT->lchild=NT->rchild; 16 else if(lr==1) 17 FT->rchild=NT->rchild; 18 else 19 T=NT->rchild; 20 free(NT); 21 }else if(NT->rchild==NULL){ 22 if(lr==0) 23 FT->lchild=NT->lchild; 24 else if(lr==1) 25 FT->rchild=NT->lchild; 26 else 27 T=NT->lchild; 28 free(NT); 29 }else{ 30 LT=NT; 31 GT=NT->rchild; 32 while(GT->lchild){ 33 LT=GT; 34 GT=GT->lchild; 35 } 36 if(GT->rchild&<==NT){ 37 LT->rchild=GT->rchild; 38 NT->grade=GT->grade; 39 strcpy(NT->university,GT->university); 40 free(GT); 41 }else if(GT->rchild){ 42 LT->lchild=GT->rchild; 43 NT->grade=GT->grade; 44 strcpy(NT->university,GT->university); 45 free(GT); 46 }else{ 47 NT->grade=GT->grade; 48 strcpy(NT->university,GT->university); 49 LT->lchild=NULL; 50 free(GT); 51 } 52 } 53 } 54 return OK; 55 }
- 查询学生需要的信息,根据stat数值完成相应操作
1 Status DisplayNeed(BiTree T,int stat,int score,int score_max){ 2 if(T->lchild) 3 DisplayNeed(T->lchild,stat,score,score_max); 4 switch(stat){ 5 case 1:{ 6 if(T->grade==score){ 7 printf("学校:%30s 分数线:%5d ",T->university,T->grade); 8 } 9 break; 10 } 11 case 2:{ 12 if(T->grade>score){ 13 printf("学校:%30s 分数线:%5d ",T->university,T->grade); 14 } 15 break; 16 } 17 case 3:{ 18 if(T->grade<score){ 19 printf("学校:%30s 分数线:%5d ",T->university,T->grade); 20 } 21 break; 22 } 23 case 4:{ 24 if(T->grade>=score&&T->grade<=score_max){ 25 printf("学校:%30s 分数线:%5d ",T->university,T->grade); 26 } 27 break; 28 } 29 } 30 if(T->rchild) 31 DisplayNeed(T->rchild,stat,score,score_max); 32 return OK; 33 }
- 中序遍历整个二叉顺序树
1 Status InOrderTraverse(BiTree T){ 2 if(T->lchild) 3 InOrderTraverse(T->lchild); 4 printf("学校:%30s 分数线:%5d ",T->university,T->grade); 5 if(T->rchild) 6 InOrderTraverse(T->rchild); 7 return OK; 8 }
- 主函数
1 int main(){ 2 BiTree T,BT,FT; 3 int Ch_one,Ch_two,score,score_min,score_max,lr,num; 4 Information message,backmessage; 5 char universityName[16]; 6 T=NULL; 7 BT=NULL; 8 FT=NULL; 9 lr=3; 10 Ch_one=1; 11 Ch_two=1; 12 printf("高校分数查询系统 V1.0"); 13 14 while(Ch_one){ 15 printf(" 请输入相应序号进行操作!(输入0退出本系统,回车键表示确定) "); 16 printf(" 1 学生使用 2 高校使用 请输入:"); 17 scanf("%d",&Ch_one); 18 Ch_two=1; 19 if(Ch_one==1){ 20 while(Ch_two){ 21 if(T){ 22 printf(" 1 查询等于给定分数的高校 2 查询大于给定分数的高校 3 查询小于给定分数的高校 "); 23 printf(" 4 查询最低录取分数线的给定的分数段中的高校 0 返回主菜单 请输入:"); 24 num=0; 25 score_max=0; 26 scanf("%d",&Ch_two); 27 }else{ 28 printf(" 院校数据不存在,请先对院校数据进行添加! "); 29 Ch_two=0; 30 } 31 32 switch(Ch_two){ 33 case 0: break; 34 case 1:{ 35 printf(" 请输入给定的分数:"); 36 scanf("%d",&score); 37 NumberGet(T,Ch_two,score,score_max,num); 38 if(num){ 39 printf(" 共查询到高校%d个 ",num); 40 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 41 DisplayNeed(T,Ch_two,score,score_max); 42 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 43 }else 44 printf(" 未查询到结果! "); 45 break; 46 } 47 case 2:{ 48 printf(" 请输入给定的分数:"); 49 scanf("%d",&score); 50 NumberGet(T,Ch_two,score,score_max,num); 51 if(num){ 52 printf(" 共查询到高校%d个 ",num); 53 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 54 DisplayNeed(T,Ch_two,score,score_max); 55 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 56 }else 57 printf(" 未查询到结果! "); 58 59 break; 60 } 61 case 3:{ 62 printf(" 请输入给定的分数:"); 63 scanf("%d",&score); 64 NumberGet(T,Ch_two,score,score_max,num); 65 if(num){ 66 printf(" 共查询到高校%d个 ",num); 67 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 68 DisplayNeed(T,Ch_two,score,score_max); 69 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 70 }else 71 printf(" 未查询到结果! "); 72 break; 73 } 74 case 4:{ 75 printf(" 请输入给定的分数段的最小值:"); 76 scanf("%d",&score_min); 77 printf(" 请输入给定的分数段的最大值:"); 78 scanf("%d",&score_max); 79 NumberGet(T,Ch_two,score_min,score_max,num); 80 if(num){ 81 printf(" 共查询到高校%d个 ",num); 82 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 83 DisplayNeed(T,Ch_two,score_min,score_max); 84 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 85 }else 86 printf(" 未查询到结果! "); 87 break; 88 } 89 default: 90 printf("输入错误! "); 91 } 92 } 93 } 94 if(Ch_one==2){ 95 while(Ch_two){ 96 printf(" 1 高校信息加入 2 高校分数修改 3 高校名称修改 "); 97 printf(" 4 高校申请退出 5 高校信息展示 0 返回主菜单 请输入:"); 98 scanf("%d",&Ch_two); 99 switch(Ch_two){ 100 case 0: break; 101 case 1:{ 102 printf(" 请输入学校名称:"); 103 scanf("%s",universityName); 104 strcpy(message.university,universityName); 105 printf(" 请输入最低分数线:"); 106 scanf("%d",&message.grade); 107 if(T&&FindUniversity(T,FT,message,lr)){ 108 DeleteData(T,message); 109 InsertData(T,message); 110 printf(" 该高校已存在!已将新数据作为数据源进行修改 "); 111 } 112 else{ 113 InsertData(T,message); 114 printf(" 信息添加成功! "); 115 } 116 break; 117 } 118 case 2:{ 119 printf(" 请输入学校名称:"); 120 scanf("%s",universityName); 121 strcpy(message.university,universityName); 122 printf(" 请输入修改后的最低分数线:"); 123 scanf("%d",&message.grade); 124 if(T&&FindUniversity(T,FT,message,lr)){ 125 DeleteData(T,message); 126 InsertData(T,message); 127 printf(" 分数线修改成功! "); 128 }else{ 129 InsertData(T,message); 130 printf(" 之前该学校不存在,现已将数据插入数据库! "); 131 } 132 133 break; 134 } 135 case 3:{ 136 printf(" 请输入原学校名称:"); 137 scanf("%s",universityName); 138 strcpy(message.university,universityName); 139 printf(" 请输入修改后的学校名称:"); 140 scanf("%s",universityName); 141 strcpy(backmessage.university,universityName); 142 if(T&&FindUniversity(T,FT,message,lr)&&!FindUniversity(T,FT,backmessage,lr)){ 143 BT=FindUniversity(T,FT,message,lr); 144 strcpy(BT->university,universityName); 145 printf(" 学校名称修改成功! "); 146 }else 147 printf(" 该学校不存在或已包含更名后的学校! "); 148 break; 149 } 150 case 4:{ 151 printf(" 请输入申请退出的学校名称:"); 152 scanf("%s",universityName); 153 strcpy(message.university,universityName); 154 if(T&&FindUniversity(T,FT,message,lr)){ 155 DeleteData(T,message); 156 printf(" 该校已退出分数查询系统! "); 157 }else 158 printf(" 该学校不存在! "); 159 160 break; 161 } 162 case 5:{ 163 if(T){ 164 printf(" --*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 165 InOrderTraverse(T); 166 printf("--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-- "); 167 }else 168 printf(" 数据为空! "); 169 170 break; 171 } 172 default: 173 printf(" 输入错误! "); 174 } 175 } 176 } 177 } 178 return 0; 179 }
程序的运行结果:
高校使用:
- 学校信息添加
- 学校名称修改
- 学校分数线修改
- 学校申请退
该部分的所有数据均随时产生,与实际高校录取线并无直接关系,仅仅用来程序演示。
学生使用:
- 根据特定分数查询相应学校
- 查询大于给定分数的高效
- 查询小于给定分数的高效
- 查询给定分数段中的高校
当且仅当院校数据存在时才可进行数据查询。
总结
本次程序整体的数据结构基于二叉排序树建立,以分数为判断依据,来决定该高校在改二叉顺序数中的存储位置,这就要求我们对该结构的熟练结构,以便于实现数据的增删查改,其中相对于重要的是数据的删除,删除一个节点时出现的情况多种多样,相对于较难以处理的就是该节点有左右子树均存在时,这时需要查找一个相对与接近删除节点的信息用来替代此节点。用转移的思想,把复杂的节点转化为相对简单的节点来进行处理。通过这次课程设计,认识到,数据结构的重要性,我们应该认真学习数据结构,体会其中的思想和逻辑处理。