基于二叉排序树的高校分数查询系统

Posted excre

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于二叉排序树的高校分数查询系统相关的知识,希望对你有一定的参考价值。

前述:该学期最后的数据结构的课程设计选题,于是记录在自己博客中,作为自己技术成长的点滴吧。

题目:高校最低录取分数线的查询

编程实现一个开放式的高校本科招生最低分数线的查询系统,供师生及家长等查询,高校自愿放入该校的信息,可能随时有高校加入。

要求实现的查询功能有:

  • 查询等于用户给定分数的高校
  • 查询大于(或小于)用户给定分数的高校
  • 查询最低录取分数线的用户给定的分数段中的高校

  以上就是老师给定题目中要求实现的功能,为了是程序整体更加完整,自己对高校使用部分做了一些功能添加,例如学校信息的增删改查等功能。

题目分析:

  该设计重要功能是查找,查找表为高校最低录取分数信息的集合。根据题意可知,该查找表中的元素个数可能随时增减,所以它是一个动态查找表,可采用树状结构保存。为了提高查询速度,可建立二叉排序树并在二叉排序树中实现查找。

程序的代码结构:

  • 头文件的引入以及结构体的定义
     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&&LT==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 }

     

程序的运行结果:

高校使用:

  • 学校信息添加
    技术分享图片
  • 学校名称修改
    技术分享图片
  • 学校分数线修改
    技术分享图片
  • 学校申请退
    技术分享图片

该部分的所有数据均随时产生,与实际高校录取线并无直接关系,仅仅用来程序演示。

 

学生使用:

  • 根据特定分数查询相应学校
    技术分享图片
  • 查询大于给定分数的高效
    技术分享图片
  • 查询小于给定分数的高效
    技术分享图片
  • 查询给定分数段中的高校
    技术分享图片

当且仅当院校数据存在时才可进行数据查询。

 

总结

 本次程序整体的数据结构基于二叉排序树建立,以分数为判断依据,来决定该高校在改二叉顺序数中的存储位置,这就要求我们对该结构的熟练结构,以便于实现数据的增删查改,其中相对于重要的是数据的删除,删除一个节点时出现的情况多种多样,相对于较难以处理的就是该节点有左右子树均存在时,这时需要查找一个相对与接近删除节点的信息用来替代此节点。用转移的思想,把复杂的节点转化为相对简单的节点来进行处理。通过这次课程设计,认识到,数据结构的重要性,我们应该认真学习数据结构,体会其中的思想和逻辑处理。

以上是关于基于二叉排序树的高校分数查询系统的主要内容,如果未能解决你的问题,请参考以下文章

基于二叉排序树的查找

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

基于树的查找

基于树的查找法

基于树的查找法

二叉排序树查找所在层次 与判断是否为二叉排序树