2017年信科课设代码备份/Treap平衡树

   1 /*有于需要额外加载easy-x 图形库
   2 所以没有装图形库的Vc6.0编译器不能成功编译该代码
   3 可以在可执行程序文件夹内
   4 找到已经编译好的exe程序和Data.txt(50000学生信息的输入文件)
   5 */
   6 #include<iostream>
   7 #include<cstdio>
   8 #include<cstdlib>
   9 #include<cstring>
  10 #include<ctime>
  11 #include<vector>
  12 #include<graphics.h>//图形库
  13 #include<Windows.h>
  14 #include<tchar.h>
  15 using namespace std;
  16 #define MAXN 2010000 //最大值 
  17 char inName[100];//读取文件的文件名 
  18 char outName[100];//输出至文件的文件名 
  19 int num = 0;
  20 int maxdeep = 0;
  21 char name[30]={0};
  22 typedef int Element;
  23 template<class T>
  24 struct Node {
  25     Node *left_son;//左孩子指针
  26     Node *right_son;//右孩子指针
  27     T data;//节点储存的信息
  28     Node *father;//父亲节点
  29     int value;//随机化权值,用于随机数的旋转,保证平衡
  30 };
  31 template<class T>
  32 class Data_tree {//信息类 基于 平衡树-树堆(Treap)实现
  33 public:
  34     Data_tree() {
  35         init();
  36     }
  37     T* Get_head()//平衡树根指针方法
  38     {
  39         return head;
  40     }
  41     void Set_head(T *pt)//更改平衡树指针方法
  42     {
  43         head = pt;
  44     }
  45     void init() {
  46         head = NULL;//根节点置为空节点
  47         size = 0;
  48     }
  49     void left_turn(T *x) {//节点左旋
  50         T* y = x->right_son;//y为节点的右孩子
  51         if (y->left_son != NULL) {
  52             x->right_son = y->left_son;//y的左孩子设置为x的右孩子
  53             y->left_son->father = x;
  54         }
  55         else
  56             x->right_son = NULL;
  57         y->father = x->father;//y的父亲设置为x的父亲
  58         if (y->father == NULL) {
  59             Set_head(y);
  60         }
  61         else {
  62             if (y->father->left_son == x)//如果x是他前父亲的左孩子
  63             {
  64                 y->father->left_son = y;//y就成了他父亲的左孩子
  65             }
  66             else if (y->father->right_son == x)//如果x是他前父亲的右孩子
  67             {
  68                 y->father->right_son = y;//y就成了他父亲的右孩子
  69             }
  70         }
  71         y->left_son = x;
  72         x->father = y;
  73     }
  74     void right_turn(T *y) {
  75         T *x = y->left_son;//x是y的左孩子
  76         if (x->right_son != NULL) {
  77             y->left_son = x->right_son;//把x的右孩子设置为y的左孩子
  78             x->right_son->father = y;//y为x的右孩子的父亲
  79         }
  80         else
  81             y->left_son = NULL;
  82         x->father = y->father;//将y的父亲设置为x的父亲
  83         if (x->father == NULL) {//如果x没有父亲了
  84             Set_head(x);//那么它就是根节点
  85         }
  86         else {
  87             if (x->father->left_son == y) {
  88                 x->father->left_son = x;
  89             }
  90             else if (x->father->right_son == y) {
  91                 x->father->right_son = x;
  92             }
  93         }
  94         x->right_son = y;
  95         y->father = x;
  96     }
  97     void insert(T* &pt) {//插入节点pt
  98         int index;//树的性质用决定什么树,以及排序的方式
  99         T* newp = Get_newNode();
 100         newp->data = pt->data;
 101         T* node = Get_head();//获取根节点,以二叉搜索树形式插入
 102         size++;
 103         if (node == NULL) {//如果是空树
 104             Set_head(newp);
 105             return;
 106         }
 107         while (node != NULL) {
 108             if (node->data < pt->data)
 109             {
 110                 if (node->right_son == NULL)
 111                     break;
 112                 node = node->right_son;//大节点插入右子树
 113             }
 114             else
 115             {
 116                 if (node->left_son == NULL)//下一个节点为空,跳出循环
 117                     break;
 118                 node = node->left_son;//小节点插入左子树
 119             }
 120         }
 121         if (node->data < pt->data) {
 122             node->right_son = newp;//插入新节点
 123         }
 124         else {
 125             node->left_son = newp;//插入新节点
 126         }
 127         newp->father = node;
 128         while (node->father != NULL&&node->father->value > node->value) {
 129             if (node == node->father->right_son)
 130                 left_turn(node->father);
 131             else if (node == node->father->left_son)
 132                 right_turn(node->father);
 133         }
 134     }
 135     T* Search(T *pt) {
 136         T* node = Get_head();//获取根节点,以二叉搜索树形式查找
 137         if (node == NULL) {//如果是空树
 138             return 0;
 139         }
 140         while (node != NULL) {
 141             if (node->data == pt->data) {
 142                 break;
 143             }
 144             else if (node->data < pt->data)
 145             {
 146                 node = node->right_son;//大节点插入右子树
 147             }
 148             else
 149             {
 150                 node = node->left_son;//小节点插入左子树
 151             }
 152         }
 153         return node;
 154     }
 155     bool Erase(T *pt) {
 156         T *node = Search(pt);
 157         if (node == NULL)//如果没有找到该节点,返回该节点
 158             return 0;
 159         if (node->father == NULL&&size == 1)//如果是根独苗
 160         {
 161             Set_head(NULL);//设置为空树
 162             size--;
 163             return 1;
 164         }
 165         size--;
 166         //    cout<<node->right_son<<endl;
 167         while (node->left_son != NULL && node->right_son != NULL) {
 168             //    cout << "???: " << node->data << " " << node->left_son->data << " " << node->right_son->data << endl;
 169             if (node->left_son->value<node->right_son->value) {
 170                 right_turn(node);
 171             }
 172             else {
 173                 left_turn(node);
 174             }
 175         }
 176         //    cout << "***: " << node << " " << node->left_son << " " << node->right_son << " " << node->father << endl;
 177         if (node->left_son != NULL) {//如果还有左孩子 
 178             if (node->father != NULL)
 179                 node->left_son->father = node->father;
 180             else {
 181                 Set_head(node->left_son);
 182                 node->left_son->father = NULL;
 183             }
 184             if (node->father != NULL) {
 185                 if (node->father->left_son == node)
 186                     node->father->left_son = node->left_son;
 187                 else if (node->father->right_son == node)
 188                     node->father->right_son = node->left_son;
 189             }
 190         }
 191         else if (node->right_son != NULL) {//如果还有右孩子 
 192             if (node->father != NULL) {
 193 
 194                 node->right_son->father = node->father;
 195             }
 196             else {
 197                 Set_head(node->right_son);
 198                 node->right_son->father = NULL;
 199             }
 200             if (node->father != NULL) {
 201                 if (node->father->left_son == node)
 202                     node->father->left_son = node->right_son;
 203                 else if (node->father->right_son == node)
 204                     node->father->right_son = node->right_son;
 205             }
 206             delete node;
 207         }
 208         else {//如果没有后代了 
 209             if (node->father->left_son == node)
 210                 node->father->left_son = NULL;
 211             else if (node->father->right_son == node)
 212                 node->father->right_son = NULL;
 213             delete node;
 214         }
 215         return 1;
 216     }
 217     void out(T* pt, int k = 0,FILE *tp=NULL) {//递归前序遍历平衡树 
 218         if (pt == NULL) return;//空节点不遍历
 219         if (pt->left_son != NULL)
 220             out(pt->left_son, k,tp);
 221         num++;
 222         if (k == 1) {
 223             printf("%-7d", num);
 224             pt->data.out();
 225             putchar('\n');
 226         }
 227         else if(k==2){
 228             fprintf(tp,"%-7d", num);
 229             pt->data.out(tp);
 230             fprintf(tp,"\n");
 231         }
 232         if (pt->right_son != NULL)
 233             out(pt->right_son, k,tp);
 234     }
 235     void out2(T* pt, int deep) {//递归前序遍历平衡树 
 236         if (pt == NULL) return;//空节点不遍历
 237         printf("%d\n", pt->value);
 238         if (deep>maxdeep) maxdeep = deep;
 239         if (pt->left_son != NULL)
 240             out(pt->left_son, deep + 1);
 241         num++;
 242         if (pt->right_son != NULL)
 243             out(pt->right_son, deep + 1);
 244     }
 245     void out3(T *pt, vector<int> *a) {
 246         if (pt == NULL) return;//空节点不遍历
 247         if (pt->left_son != NULL)
 248             out3(pt->left_son, a);
 249         a->push_back(pt->data.getnumber());
 250         if (pt->right_son != NULL)
 251             out3(pt->right_son, a);
 252     }
 253     int size;//平衡树的节点个数
 254 private:
 255     T* head;//平衡树的根节点指针
 256     T *Get_newNode() {//获取一个新声明的初始化节点
 257         T* pt;
 258         pt = new T();
 259         pt->father = NULL;//父亲节点设置为空
 260         pt->left_son = NULL;//左右儿子节点置为空
 261         pt->right_son = NULL;
 262         pt->value = rand();//设置权值为随机数
 263         return pt;
 264     }
 265 };
 266 void get_name(int);
 267 struct ScoreData {//学生成绩结构体 
 268     int score;//分数 
 269     int number;//学号 
 270     bool operator<(const struct ScoreData &pt)const {
 271         if (this->score != pt.score)
 272             return this->score>pt.score;
 273         else
 274             return this->number<pt.number;
 275     }
 276     bool operator==(const struct ScoreData &pt)const {
 277         return this->number == pt.number;
 278     }
 279     void out(FILE *pt=NULL)//输出成绩
 280     {
 281         get_name(number);
 282         if(pt==NULL)
 283         printf("%-7d %-7d %-7s", number, score,name);
 284         else
 285         fprintf(pt,"%-7d %-7d %-7s",number,score,name);
 286     }
 287 };
 288 
 289 struct NumberData {//学生学号结构体 
 290     int number;//学号 
 291     int score;//分数
 292     bool operator<(const struct NumberData &pt)const {
 293         return number<pt.number;
 294     }
 295     bool operator==(const struct NumberData &pt)const {
 296         return number == pt.number;
 297     }
 298     int getnumber() {
 299         return number;
 300     }
 301 };
 302 
 303 struct Student_type {
 304     int number;//学号 
 305     int index;//信息数组下标 
 306     bool operator<(const Student_type&pt)const {
 307         return this->number<pt.number;
 308     }
 309     bool operator==(const Student_type&pt)const {
 310         return this->number == pt.number;
 311     }
 312 };
 313 struct Student {
 314     char name[30];
 315     int number;//该学生的学号 
 316     char classnumber[20];
 317     char department[20];//该学生的系别编号 
 318     Student() {
 319         name[0] = 0;
 320         classnumber[0] = 0;
 321         department[0] = 0;
 322     }
 323 };
 324 
 325 struct ListNode {//信息链表,节点区别为课程名字或系别或班级名字 
 326     ListNode *next;
 327     Data_tree<Node <ScoreData> > tree_score;
 328     Data_tree<Node <NumberData> > tree_number;
 329     char s[50];
 330     int lens;
 331     int property;
 332 };
 333 
 334 ListNode *Listhead = NULL;//信息链表头 
 335 
 336 ListNode* insert_node(char s[], int k = 0) {
 337     ListNode *pt = new ListNode();//新生命节点 
 338     pt->lens = strlen(s);
 339     for (int i = 0; i <= pt->lens; i++)/*字符数组s存入新建节点*/
 340         pt->s[i] = s[i];
 341     pt->next = Listhead;//新节点的下一个为头结点
 342     pt->property = k;//设置节点优先级 
 343     Listhead = pt;
 344     return Listhead;//返回该节点指针作为返回值 
 345 }
 346 
 347 
 348 ListNode* Search(char s[], int k = 0) {//查找链表 
 349     ListNode *pt = Listhead;//指针指向链表头部 
 350     int len = strlen(s);//将字符串s的长度存入len 
 351     while (pt != NULL) {//循环遍历链表 
 352         if (pt->lens != len)//如果字符串长度不相同,跳过 
 353         {
 354             pt = pt->next;
 355             continue;
 356         }
 357         else {//否则返回逐一检查字符串中每一个字符 
 358             int ok = 1;
 359             for (int i = 0; i<len; i++)
 360                 if (s[i] != pt->s[i]) {//如果发现不相等字符,就继续 
 361                     ok = 0;
 362                     break;
 363                 }
 364             if (ok == 1) {//信息吻合,就返回该节点的指针作为返回值 
 365                 return pt;
 366             }
 367         }
 368         pt = pt->next;
 369     }
 370     pt = insert_node(s, k);//如果没有找到该节点,那么就新建立一个该属性的节点 
 371     return pt;//返回新建节点的指针值 
 372 }
 373 
 374 void insert_data(ListNode* pt, int number, int score) {//向链表的平衡树中插入信息
 375     Node<ScoreData> *the_data = new Node<ScoreData>();//插入一个成绩信息,用于该科目核对
 376     Node<NumberData> *other_data = new Node<NumberData>();//插入一个学号信息,是否有该学生
 377     ScoreData sdata;
 378     NumberData odata;
 379     odata.number = number;//设置该节点编号
 380     other_data->data = odata;
 381     other_data = pt->tree_number.Search(other_data);
 382     if (other_data != NULL) {//如果该节点非空
 383         sdata.number = number;//设置学号
 384         sdata.score = other_data->data.score;
 385         the_data->data = sdata;
 386         pt->tree_score.Erase(the_data);//尝试删除该信息原来的点,以达到覆盖效果
 387     }
 388     sdata.number = number;//设置节点的学号 
 389     sdata.score = score;//设置节点的分数 
 390     the_data->data = sdata;
 391     other_data = new Node<NumberData>();
 392     pt->tree_score.insert(the_data);//插入该节点
 393     odata.score = score;//设置节点的分数 
 394     odata.number = number;//设置节点的学号 
 395     other_data->data = odata;
 396     pt->tree_number.Erase(other_data);//尝试删除该信息原来的点(如果有的话),以达到覆盖效果
 397     pt->tree_number.insert(other_data);//插入该节点 
 398 }
 399 
 400 void erase_data(ListNode* pt, int number) {//向链表的平衡树中删除信息
 401     Node<ScoreData> *the_data = new Node<ScoreData>();//插入一个成绩信息,用于该科目核对
 402     ScoreData sdata;
 403     sdata.number = number;//设置节点学号 
 404     the_data->data = sdata;
 405     pt->tree_score.Erase(the_data);//尝试删除该信息原来的点(如果有的话),
 406     Node<NumberData> *other_data = new Node<NumberData>();//建立一个学号信息
 407     NumberData odata;
 408     odata.number = number;
 409     other_data->data = odata;
 410     pt->tree_number.Erase(other_data);//尝试删除该信息原来的点(如果有的话),以达到覆盖效果
 411 }
 412 
 413 int getsumscore(int number, int k = 0) {//当k=1时输出该学生各科目信息
 414     int sum = 0;//初始化总分数变量 
 415     ListNode* pt = Listhead;//指针指向链表头部 
 416     Node<NumberData> *other_data = new Node<NumberData>();
 417     NumberData odata;
 418     odata.number = number;//设置学号 
 419     other_data->data = odata;
 420     Node<NumberData> *search_data;
 421     while (pt != NULL) {//遍历链表 
 422         if (pt->property != 0) {//如果不是课程节点
 423             pt = pt->next;//链表指针指向下一个 
 424             continue;
 425         }
 426         search_data = pt->tree_number.Search(other_data);//查找是否能找到有该学号的人 
 427 
 428         if (search_data == NULL) {//如果节点为空,那么就跳过
 429             pt = pt->next;//链表指针指向下一个 
 430             continue;
 431         }
 432         sum += search_data->data.score;//加入成绩至总分 
 433         if (k != 0)//如果不为0就输出 
 434             printf("其%s科目的成绩为: %d\n", pt->s, search_data->data.score);
 435         pt = pt->next;//链表指针指向下一个 
 436     }
 437     if (k != 0)
 438         printf("其总分为: %d\n", sum);
 439     return sum;
 440 }
 441 
 442 int studentnum = 0;//学生编号表
 443 Student studentlist[MAXN];//学生信息表 
 444 Data_tree<Node <Student_type> > studenttree;
 445 int student_insert(int number) {//新插入一个学号的学生 
 446                                 //Student_type pt = new Student_type();
 447     Node<Student_type> *pt = new Node<Student_type>();
 448     pt->data.number = number;
 449     pt->data.index = studentnum;
 450     studentlist[studentnum].number = number;
 451     studenttree.insert(pt);
 452     return studentnum++;//返回当前编号 
 453 }
 454 
 455 
 456 int get_student_index(int number)//获取该学号在学生数组里的下标
 457 {
 458     Node<Student_type> *pt = new Node<Student_type>();
 459     pt->data.number = number;
 460     pt = studenttree.Search(pt);
 461     if (pt == NULL)
 462         return -1;//失败返回-1
 463     else
 464         return pt->data.index;//成功返回编号 
 465 }
 466 
 467 void set_student_name(int number, char s[])//设置该学号学生的名字
 468 {
 469     int index = get_student_index(number);
 470     if (index<0)//若没有该学生信息 
 471         index = student_insert(number);//插入该学生信息 
 472     int size = strlen(s);
 473     for (int i = 0; i <= size; i++)
 474         studentlist[index].name[i] = s[i];//设置学生的名字 
 475     return;
 476 }
 477 
 478 void set_student_classnumber(int number, char s[]) {
 479     int index = get_student_index(number);
 480     if (index<0)//若没有该学生信息 
 481         index = student_insert(number);//插入该学生信息
 482     int lens = strlen(studentlist[index].classnumber);
 483     if (lens > 0)//如果发现有原来班级的信息
 484     {
 485         ListNode* pt;
 486         pt = Search(studentlist[index].classnumber, 1);//找到原来班级的链表节点
 487         erase_data(pt, number);//从原来班级删除该学生
 488     }
 489     int size = strlen(s);
 490     for (int i = 0; i <= size; i++)
 491         studentlist[index].classnumber[i] = s[i];//设置学生的班级名字 
 492     return;
 493 }
 494 
 495 void get_name(int number) {
 496     int index = get_student_index(number);
 497     if (index<0)//若没有该学生信息 
 498     {
 499         name[0]='N',name[1]='o',name[2]='t',name[3]=' ',name[4]='s';
 500         name[5]='e',name[5]='t',name[5]=' ',name[6]='n';name[7]='a';
 501         name[8]='m',name[9]='e',name[10]=0; 
 502         return;//设置没有名字 
 503     }
 504     int lens = strlen(studentlist[index].name);
 505     for(int i=0;i<=lens;i++)
 506         name[i]=studentlist[index].name[i];
 507     return;
 508 }
 509 
 510 void set_student_department(int number, char s[]) {
 511     int index = get_student_index(number);
 512     if (index<0)//若没有该学生信息 
 513         index = student_insert(number);//插入该学生信息 
 514     int lens = strlen(studentlist[index].department);
 515     if (lens > 0)//如果发现有原来系别的信息
 516     {
 517         ListNode* pt;
 518         pt = Search(studentlist[index].department, 1);//找到原来系别的链表节点
 519         erase_data(pt, number);//从原来系别删除该学生
 520     }
 521     int size = strlen(s);
 522     for (int i = 0; i <= size; i++)
 523         studentlist[index].department[i] = s[i];//设置学生的系别名字 
 524     return;
 525 }
 526 
 527 
 528 void Screen_clear() {//清空屏幕 
 529     system("cls");
 530 }
 531 
 532 int Get_score(char s[], int number) {//获取s课程number学号的成绩
 533     ListNode *pt = Search(s);
 534     Node<NumberData> *other_data = new Node<NumberData>();
 535     NumberData odata;
 536     odata.number = number;
 537     other_data->data = odata;
 538     other_data = pt->tree_number.Search(other_data);
 539     if (other_data == NULL)//没有找到该学生
 540         return 0;
 541     else
 542         return other_data->data.score;
 543 }
 544 
 545 int Get_score(ListNode *pt, int number) {//获取课程指针pt内number学号学生的成绩
 546     if (pt == NULL)
 547         return 0;
 548     Node<NumberData> *other_data = new Node<NumberData>();
 549     NumberData odata;
 550     odata.number = number;
 551     other_data->data = odata;
 552     other_data = pt->tree_number.Search(other_data);
 553     if (other_data == NULL)//没有找到该学生
 554         return 0;
 555     else
 556         return other_data->data.score;
 557 }
 558 void Input_System() {//录入系统 
 559     Screen_clear();//清屏 
 560     printf("欢迎您进入学生成绩录入系统\n");
 561     printf("本系统采用命令式信息采集方案\n");
 562     printf("如果输入之前已设置的信息会覆盖即发生修改\n");
 563     printf("命令菜单:\n");
 564     printf("命令\t\t\t\t功能\n");
 565     printf("%-22s\t\t%s\n", "In data.txt", "读取data.txt全部内容直至文件尾(可自定义文件名)");
 566     printf("%-22s\t\t%s\n", "CloseFile", "关闭文件输入方式(需要在文件中输出)");
 567     printf("%-22s\t%s\n", "Set Name 1608024101 王XX", "1608024101的学生的名字为王xx");
 568     printf("%-22s\t%s\n", "Set Class 1608024101 16080241", "1608024101的学生的班级为16080241");
 569     printf("%-22s\t%s\n", "Set Department 1608024101 8院", "1608024101的学生的系别为8院");
 570     printf("%-22s\t%s\n", "Set Score 算法 1608024101 0", "将学号为1608024101的算法成绩设置为0分");
 571     printf("%-25s\t%s\n", "Exit", "退出当前子系统");
 572     printf("现在请您输入相应的指令:\n");
 573     FILE *in;//文件读入指针
 574     int wj = 0;
 575     int start = 0;
 576     while (1) {
 577         char s[300];
 578         if (wj == 0) {
 579             scanf("%s", s);//获命令
 580             int len = strlen(s);
 581             if (len <= 0) {
 582                 printf("语法错误\n");
 583                 fflush(stdin);//清空输入缓冲区 
 584             }
 585             if (s[0] == 'I') {
 586                 scanf("%s", inName);
 587                 in = fopen(inName, "r");
 588                 if (in == 0) {
 589                     printf("打开文件失败,请检查\n");
 590                     continue;
 591                 }
 592                 else {
 593                     printf("打开文件成功\n");
 594                     wj = 1;
 595                     start = clock();
 596                     continue;
 597                 }
 598             }
 599             else if (s[0] == 'C') {
 600                 wj = 0;
 601                 in = NULL;
 602                 int finish = clock();//获取当前时钟
 603                 printf("读取,并且创建平衡树成功\n共耗时%.6f秒\n", (double)(finish - start) / CLOCKS_PER_SEC);
 604                 printf("成功将输入源转至键盘\n");
 605                 continue;
 606             }
 607             else if (s[0] == 'S') {
 608                 scanf("%s", s);
 609                 if (s[0] == 'N') {
 610                     char name[300];
 611                     int number;
 612                     scanf("%d", &number);
 613                     scanf("%s", name);
 614                     set_student_name(number, name);
 615                     printf("设置名字成功\n");
 616                 }
 617                 else if (s[0] == 'C') {
 618                     char classes[300];
 619                     int number;
 620                     scanf("%d", &number);
 621                     scanf("%s", classes);
 622                     set_student_classnumber(number, classes);
 623                     ListNode *pt;
 624                     pt = Search(classes, 1);
 625                     insert_data(pt, number, 1);
 626                     printf("设置班级成功\n");
 627                 }
 628                 else if (s[0] == 'D') {
 629                     char department[300];
 630                     int number;
 631                     scanf("%d", &number);
 632                     scanf("%s", department);
 633                     set_student_department(number, department);
 634                     ListNode *pt;
 635                     pt = Search(department, 1);
 636                     insert_data(pt, number, 1);
 637                     printf("设置系别成功\n");
 638                 }
 639                 else if (s[0] == 'S') {
 640                     int number;
 641                     char coursename[30];
 642                     int score;
 643                     scanf("%s", coursename);
 644                     scanf("%d%d", &number, &score);
 645                     int index = get_student_index(number);
 646                     if (index<0)//若没有该学生信息 
 647                         index = student_insert(number);//插入该学生信息 
 648                     ListNode *pt;
 649                     pt = Search(coursename);
 650                     insert_data(pt, number, score);
 651                     printf("设置成绩成功\n");
 652                 }
 653                 else {
 654                     printf("语法错误\n");
 655                     fflush(stdin);//清空输入缓冲区 
 656                 }
 657             }
 658             else if (s[0] == 'E') {
 659                 printf("即将在2秒后退出\n");
 660                 Sleep(2000);
 661                 return;
 662             }
 663             else {
 664                 printf("语法错误\n");
 665                 fflush(stdin);//清空输入缓冲区 
 666             }
 667         }
 668         else {
 669             if(fscanf(in, "%s", s)==EOF){
 670                 s[0]='C';
 671                 s[1]=0;//没有文件,设置结束 
 672             };//获命令
 673             int len = strlen(s);
 674             if (len <= 0) {
 675             }
 676             else if (s[0] == 'C') {
 677                 wj = 0;
 678                 in = NULL;
 679                 int finish = clock();//获取当前时钟
 680                 printf("读取,并且创建平衡树成功\n共耗时%.6f秒\n", (double)(finish - start) / CLOCKS_PER_SEC);
 681                 printf("成功将输入源转至键盘\n");
 682                 continue;
 683             }
 684             else if (s[0] == 'S') {
 685                 fscanf(in, "%s", s);
 686                 if (s[0] == 'N') {
 687                     char name[300];
 688                     int number;
 689                     fscanf(in, "%d", &number);
 690                     fscanf(in, "%s", name);
 691                     set_student_name(number, name);
 692                 }
 693                 else if (s[0] == 'C') {
 694                     char classes[300];
 695                     int number;
 696                     fscanf(in, "%d", &number);
 697                     fscanf(in, "%s", classes);
 698                     set_student_classnumber(number, classes);
 699                     ListNode *pt;
 700                     pt = Search(classes, 1);
 701                     insert_data(pt, number, 1);
 702                 }
 703                 else if (s[0] == 'D') {
 704                     char department[300];
 705                     int number;
 706                     fscanf(in, "%d", &number);
 707                     fscanf(in, "%s", department);
 708                     set_student_department(number, department);
 709                     ListNode *pt;
 710                     pt = Search(department, 1);
 711                     insert_data(pt, number, 1);
 712                 }
 713                 else if (s[0] == 'S') {
 714                     int number;
 715                     char coursename[30];
 716                     int score;
 717                     fscanf(in, "%s", coursename);
 718                     fscanf(in, "%d%d", &number, &score);
 719                     int index = get_student_index(number);
 720                     if (index<0)//若没有该学生信息 
 721                         index = student_insert(number);//插入该学生信息 
 722                     ListNode *pt;
 723                     pt = Search(coursename);
 724                     insert_data(pt, number, score);
 725                 }
 726             }
 727         }
 728     }
 729 }
 730 
 731 vector<int> num_vector;
 732 ScoreData* Score_vector;
 733 
 734 void Output_System() {//输出系统
 735     Screen_clear();//清屏 
 736     printf("欢迎您进入信息输出系统\n");
 737     printf("本系统采用命令式交互方案\n");
 738     printf("命令菜单:\n");
 739     printf("命令\t\t\t\t\t功能\n");
 740     printf("%-22s\t\t%s\n", "Query Number 1608024101", "输出1608024101的各科目成绩");
 741     printf("%-22s\t\t%s\n", "Query Data 1608024101", "输出1608024101的信息");
 742     printf("%-22s\t\t%s\n", "Query Course 数学分析", "输出数学分析科目的所有的成绩");
 743     printf("%-22s\t\t%s\n", "Query Department 8院", "输出8院的所有同学的学号");
 744     printf("%-22s\t\t%s\n", "Query Class 16080241", "输出16080241班的所有同学的学号");
 745     printf("%-25s\t\t%s\n", "Exit", "退出当前子系统");
 746     printf("现在请您输入相应的指令:\n");
 747     while (1) {
 748         char s[300];
 749         num = 0;
 750         scanf("%s", s);//获命令
 751         int len = strlen(s);
 752         if (len <= 1) {
 753             printf("语法错误\n");
 754             fflush(stdin);//清空输入缓冲区 
 755             continue;
 756         }
 757         if (s[0] == 'Q') {
 758             scanf("%s", s);
 759             if (strlen(s) < 3) {
 760                 printf("语法错误\n");
 761                 fflush(stdin);//清空输入缓冲区 
 762                 continue;
 763             }
 764             if (s[0] == 'N'&&s[1] == 'u') {
 765                 char name[300];
 766                 int number;
 767                 scanf("%d", &number);
 768                 getsumscore(number, 1);
 769                 printf("查找该学生成绩成功\n");
 770             }
 771             else if (s[0] == 'D'&&s[1] == 'a') {
 772                 char name[300];
 773                 int number;
 774                 scanf("%d", &number);
 775                 int index = get_student_index(number);
 776                 if (index < 0)//没有该生信息
 777                 {
 778                     printf("对不起,并没有找到该学号的学生\n");
 779                     continue;
 780                 }
 781                 else if (index >= 0) {
 782                     printf("学号:%d\n", number);
 783                     if (strlen(studentlist[index].name) > 0)
 784                         printf("姓名:%s\n", studentlist[index].name);
 785                     else
 786                         printf("姓名:尚未定义\n");
 787                     if (strlen(studentlist[index].classnumber) > 0)
 788                         printf("班级:%s\n", studentlist[index].classnumber);
 789                     else
 790                         printf("班级:尚未定义\n");
 791                     if (strlen(studentlist[index].department) > 0)
 792                         printf("系别:%s\n", studentlist[index].department);
 793                     else
 794                         printf("系别:尚未定义\n");
 795                 }
 796                 printf("查找该学生信息成功\n");
 797                 continue;
 798             }
 799             else if (s[0] == 'C'&&s[1] == 'o') {
 800                 char classes[300];
 801                 scanf("%s", classes);
 802                 ListNode* pt;
 803                 pt = Search(classes); 
 804                 printf("%7s %7s %7s %7s\n", "名次", "学号", "成绩","姓名");
 805                 pt->tree_score.out(pt->tree_score.Get_head(), 1);
 806             }
 807             else if (s[0] == 'D') {
 808                 char department[300];
 809                 scanf("%s", department);
 810                 ListNode* pt;
 811                 pt = Search(department);
 812                 printf("%7s %7s\n", "序号", "学号");
 813                 num_vector.clear();
 814                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
 815                 int i;
 816                 for (i = 0; i < num_vector.size(); i++) {
 817                     printf("%-7d%-7d\n", i + 1, num_vector[i]);
 818                 }
 819             }
 820             else if (s[0] == 'C'&&s[1] == 'l') {
 821                 char classes[300];
 822                 scanf("%s", classes);
 823                 ListNode* pt;
 824                 pt = Search(classes);
 825                 printf("%7s %7s\n", "序号", "学号");
 826                 num_vector.clear();
 827                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
 828                 int i;
 829                 for (i = 0; i < num_vector.size(); i++) {
 830                     printf("%7d %7d\n", i + 1, num_vector[i]);
 831                 }
 832             }
 833             else {
 834                 printf("语法错误\n");
 835                 fflush(stdin);//清空输入缓冲区 
 836             }
 837         }
 838         else if (s[0] == 'E') {
 839             printf("即将在2秒后退出\n");
 840             Sleep(2000);
 841             return;
 842         }
 843         else {
 844             printf("语法错误\n");
 845             fflush(stdin);//清空输入缓冲区 
 846         }
 847     }
 848 }
 849 
 850 void swap(ScoreData *p, ScoreData *q) {    //交换两个变量的值
 851     ScoreData t = *q;
 852     *q = *p; *p = t;
 853 }
 854 
 855 void Quicksort(ScoreData a[], int l, int r) {//快速排序
 856     if (l >= r) return;//区间内小于等于1个元素的时候,不用排序,直接返回
 857     int t = rand() % (r - l + 1) + l;    //t为基准值位置,这里采用随机选取
 858     swap(&a[l], &a[t]);
 859     int i = l, j = r;
 860     ScoreData mid = a[l];
 861     while (i<j) {
 862         while (i < j&&mid < a[j]) j--; //将比基准值小的元素放在基准值左边
 863         a[i] = a[j];
 864         while (i < j && !(mid < a[i])) i++; //将比基准值大的元素放在基准值右边
 865         a[j] = a[i];
 866     }
 867     a[i] = mid;//基准值放在中间
 868     Quicksort(a, l, i - 1);//递归排序基准值左边
 869     Quicksort(a, i + 1, r);//递归排序基准值右边
 870 }
 871 
 872 int pass_score = 60, good_score = 90;//及格线,优秀线
 873 void analy(ScoreData a[], int n) {
 874     int passnum = 0, goodnum = 0;//及格人数,优秀人数
 875     for (int i = 0; i < n; i++) {
 876         if (a[i].score >= pass_score)
 877             passnum++;
 878         if (a[i].score >= good_score)
 879             goodnum++;
 880     }
 881     printf("总人数: %d\n", n);
 882     printf("及格人数: %d\n", passnum);
 883     printf("及格率: %.2f\n", (double)passnum / n);
 884     printf("优秀人数: %d\n", goodnum);
 885     printf("优秀率: %.2f\n", (double)goodnum / n);
 886 }
 887 
 888 void analy2(ScoreData a[], int n) {
 889     int minn = 0x3f3f3f3f, maxn = 0;//及格人数,优秀人数
 890     int ans = 0;
 891     for (int i = 0; i < n; i++) {
 892         if (a[i].score > maxn)
 893             maxn = a[i].score;
 894         if (a[i].score < minn)
 895             minn = a[i].score;
 896         ans += a[i].score;
 897     }
 898     printf("总人数: %d\n", n);
 899     printf("最高分数: %d\n", maxn);
 900     printf("最低分数: %d\n", minn);
 901     printf("平均成绩: %.2f\n", (double)ans / n);
 902 }
 903 
 904 void Analyze_System() {
 905     Screen_clear();//清除屏幕
 906     printf("欢迎您进入成绩分析系统\n");
 907     printf("本系统采用命令式交互方案\n");
 908     printf("命令菜单:\n");
 909     printf("命令\t\t\t\t\t功能\n");
 910     printf("%-22s\t\t%s\n", "Analyze Class 16080241 数学分析", "输出16080241班的数学分析的成绩分析");
 911     printf("%-22s\t%s\n", "Analyze Department 数学系 数学分析", "输出数学系班的数学分析的成绩分析");
 912     printf("%-22s\t\t\t%s\n", "Set Goodline 95", "设置优秀线95 默认是90分");
 913     printf("%-22s\t\t\t%s\n", "Set Passline 50", "设置及格线50 默认是60分");
 914     printf("%-25s\t\t%s\n", "Exit", "退出当前子系统");
 915     printf("现在请您输入相应的指令:\n");
 916     while (1) {
 917         char s[300];
 918         scanf("%s", s);
 919         if (s[0] == 'A') {
 920             scanf("%s", s);
 921             if (strlen(s) < 1) {
 922                 printf("语法错误\n");
 923                 continue;
 924             }
 925             else if (s[0] == 'C') {
 926                 char classes[300];
 927                 scanf("%s", classes);
 928                 ListNode* pt;
 929                 pt = Search(classes);
 930                 num_vector.clear();
 931                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
 932                 if (num_vector.size() == 0) {
 933                     printf("该列表没有成员\n");
 934                     continue;
 935                 }
 936                 int i;
 937                 char name[300];
 938                 scanf("%s", name);
 939                 pt = Search(name, 1);//获取该课程指针
 940                 Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表
 941                 for (i = 0; i < num_vector.size(); i++) {
 942                     Score_vector[i].number = num_vector[i];//存储学号
 943                     Score_vector[i].score = Get_score(pt, Score_vector[i].number);
 944                 }
 945                 analy(Score_vector, num_vector.size());
 946             }
 947             else if (s[0] == 'D') {
 948                 char department[300];
 949                 scanf("%s", department);
 950                 ListNode* pt;
 951                 pt = Search(department);
 952                 //printf("%7s %7s\n", "序号", "学号");
 953                 num_vector.clear();
 954                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
 955                 char name[300];
 956                 scanf("%s", name);
 957                 if (num_vector.size() == 0) {
 958                     printf("该列表没有成员\n");
 959                     continue;
 960                 }
 961                 pt = Search(name, 1);//获取该课程指针
 962                 int i;
 963                 Score_vector = new ScoreData[num_vector.size()];//创立一个该系人数大小的线性表
 964                 for (i = 0; i < num_vector.size(); i++) {
 965                     Score_vector[i].number = num_vector[i];//存储学号
 966                     Score_vector[i].score = Get_score(pt, Score_vector[i].number);
 967                 }
 968                 analy(Score_vector, num_vector.size());
 969             }
 970             else {
 971                 printf("语法错误\n");
 972                 continue;
 973             }
 974         }
 975         else if (s[0] == 'S') {
 976             int d;
 977             scanf("%s", s);
 978             scanf("%d", &d);
 979             if (s[0] == 'G') {
 980                 good_score = d;//设置优秀线
 981                 printf("设置成功\n");
 982             }
 983             else if (s[0] == 'P') {
 984                 pass_score = d;//设置及格线
 985                 printf("设置成功\n");
 986             }
 987         }
 988         else if (s[0] == 'E') {
 989             return;
 990         }
 991     }
 992 }
 993 
 994 void Course_System() {
 995     Screen_clear();//清除屏幕
 996     printf("欢迎您进入课程成绩分析系统\n");
 997     printf("请输出操作指令:\n");
 998     printf("1.分析课程\n");
 999     printf("2.退出\n");
1000     while (1) {
1001         int c = getchar();
1002         while (!(c > '0'&&c <= '2')) {
1003             c = getchar();
1004             continue;
1005         }
1006         if (c == '1') {
1007             printf("请输入分析的课程名字:\n");
1008             char name[300];
1009             scanf("%s", name);
1010             ListNode* pt;
1011             pt = Search(name);
1012             num_vector.clear();
1013             pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
1014             if (num_vector.size() == 0) {
1015                 printf("该列表没有成员\n");
1016                 continue;
1017             }
1018             int i;
1019             Score_vector = new ScoreData[num_vector.size()];//创立一个该课程人数大小的线性表
1020             for (i = 0; i < num_vector.size(); i++) {
1021                 Score_vector[i].number = num_vector[i];//存储学号
1022                 Score_vector[i].score = Get_score(pt, Score_vector[i].number);
1023             }
1024             analy2(Score_vector, num_vector.size());
1025         }
1026         else if (c == '2')
1027             return;
1028     }
1029 }
1030 
1031 void Rank_System() {//排名系统
1032     Screen_clear();//清除屏幕
1033     printf("欢迎您进入成绩排名系统\n");
1034     printf("本系统采用命令式交互方案\n");
1035     printf("命令菜单:\n");
1036     printf("命令\t\t\t\t\t功能\n");
1037     printf("%-22s\t\t\t%s\n", "Out to data.txt", "将排名输出至 data.txt 可以自定义文件名");
1038     printf("%-22s\t\t\t%s\n", "Out Recover", "将排名重新输出至屏幕");
1039     printf("%-22s\t\t%s\n", "Rank Class 16080241 数学分析", "输出16080241班的数学分析的成绩排名");
1040     printf("%-22s\t\t%s\n", "Rank Department 数学系 数学分析", "输出数学系的数学分析的成绩排名");
1041     printf("%-22s\t\t\t%s\n", "Rank AllClass 16080241", "输出16080241班的数学分析的成绩排名");
1042     printf("%-22s\t\t%s\n", "Rank AllDepartment 数学系", "输出数学系的总成绩的成绩排名");
1043     printf("%-25s\t\t%s\n", "Exit", "退出当前子系统");
1044     printf("现在请您输入相应的指令:\n");
1045     int i;
1046     int wj = 0;//是否进行文件输出
1047     FILE* filepoint;
1048     while (1) {
1049         char s[300];
1050         scanf("%s", s);
1051         if (s[0] == 'O') {
1052             scanf("%s", outName);
1053             if (outName[0] == 't') {
1054                 scanf("%s", outName);
1055                 filepoint = fopen(outName, "w+");
1056                 if (filepoint == NULL) {
1057                     printf("输出转向文件失败!\n");
1058                     continue;
1059                 }
1060                 else {
1061                     printf("输出转向文件成功\n");
1062                     wj = 1;
1063                     continue;
1064                 }
1065             }
1066             else {
1067                 if (outName[0] == 'R' || outName[0] == 'r') {
1068                     fclose(filepoint);
1069                     filepoint = NULL;
1070                     wj = 0;
1071                     printf("输出转至屏幕成功\n");
1072                     continue;
1073                 }
1074             }
1075         }
1076         else if (s[0] == 'R') {
1077             scanf("%s", s);
1078             if (s[0] == 'C') {
1079                 char classes[300];
1080                 scanf("%s", classes);
1081                 ListNode* pt;
1082                 pt = Search(classes);
1083                 num_vector.clear();
1084                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
1085                 scanf("%s", classes);
1086                 if (num_vector.size() == 0) {
1087                     printf("该列表没有成员\n");
1088                     continue;
1089                 }
1090                 pt = Search(classes, 1);//获取该课程指针
1091                 Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表
1092                 for (i = 0; i < num_vector.size(); i++) {
1093                     //printf("%7d %7d\n", i + 1, num_vector[i]);
1094                     Score_vector[i].number = num_vector[i];//存储学号
1095                     Score_vector[i].score = Get_score(pt, Score_vector[i].number);
1096                 }
1097                 Quicksort(Score_vector, 0, num_vector.size() - 1);
1098                 if (wj == 0)
1099                     printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1100                 else
1101                     fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1102                 int i;
1103                 int start = clock();
1104                 for (i = 0; i <= num_vector.size() - 1; i++) {
1105                     get_name(Score_vector[i].number);
1106                     if (wj == 0)
1107                         printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1108                     else
1109                         fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1110                 }
1111                 int finish = clock();
1112                 if (wj == 1) {
1113                     printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC);
1114                 }
1115             }
1116             else if (s[0] == 'D') {
1117                 char department[300];
1118                 scanf("%s", department);
1119                 ListNode* pt;
1120                 pt = Search(department);
1121                 num_vector.clear();
1122                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
1123                 scanf("%s", department);
1124                 if (num_vector.size() == 0) {
1125                     printf("该列表没有成员\n");
1126                     continue;
1127                 }
1128                 pt = Search(department, 1);//获取该课程指针
1129                 Score_vector = new ScoreData[num_vector.size()];//创立一个该系别人数大小的线性表
1130                 for (i = 0; i < num_vector.size(); i++) {
1131                     Score_vector[i].number = num_vector[i];//存储学号
1132                     Score_vector[i].score = Get_score(pt, Score_vector[i].number);
1133                 }
1134                 Quicksort(Score_vector, 0, num_vector.size() - 1);
1135                 if (wj == 0)
1136                     printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1137                 else
1138                     fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1139                 int start = clock();
1140                 for (i = 0; i <= num_vector.size() - 1; i++) {
1141                     get_name(Score_vector[i].number);
1142                     if (wj == 0)
1143                         printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1144                     else
1145                         fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1146                 }
1147                 int finish = clock();
1148                 if (wj == 1) {
1149                     printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC);
1150                 }
1151             }
1152             else if (s[0] == 'A'&&strlen(s) > 4 && s[3] == 'C') {
1153                 char classes[300];
1154                 scanf("%s", classes);
1155                 ListNode* pt;
1156                 pt = Search(classes);
1157                 num_vector.clear();
1158                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
1159                 if (num_vector.size() == 0) {
1160                     printf("该列表没有成员\n");
1161                     continue;
1162                 }
1163                 Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表
1164                 for (i = 0; i < num_vector.size(); i++) {
1165                     Score_vector[i].number = num_vector[i];//存储学号
1166                     Score_vector[i].score = getsumscore(Score_vector[i].number);
1167                 }
1168                 Quicksort(Score_vector, 0, num_vector.size() - 1);
1169                 if (wj == 0)
1170                     printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1171                 else
1172                     fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1173                 int i;
1174                 int start = clock();
1175                 for (i = 0; i <= num_vector.size() - 1; i++) {
1176                     get_name(Score_vector[i].number);
1177                     if (wj == 0)
1178                         printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1179                     else
1180                         fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1181                 }
1182                 int finish = clock();
1183                 if (wj == 1) {
1184                     printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC);
1185                 }
1186             }
1187             else if (s[0] == 'A'&&strlen(s) > 4 && s[3] == 'D') {
1188                 char department[300];
1189                 scanf("%s", department);
1190                 ListNode* pt;
1191                 pt = Search(department);
1192                 num_vector.clear();
1193                 pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
1194                 int i;
1195                 if (num_vector.size() == 0) {
1196                     printf("该列表没有成员\n");
1197                     continue;
1198                 }
1199                 Score_vector = new ScoreData[num_vector.size()];//创立一个该系别人数大小的线性表
1200                 for (i = 0; i < num_vector.size(); i++) {
1201                     Score_vector[i].number = num_vector[i];//存储学号
1202                     Score_vector[i].score = getsumscore(Score_vector[i].number);
1203                 }
1204                 Quicksort(Score_vector, 0, num_vector.size() - 1);
1205                 if (wj == 0)
1206                     printf("%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1207                 else
1208                     fprintf(filepoint, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1209                 int start = clock();
1210                 for (i = 0; i <= num_vector.size() - 1; i++) {
1211                     get_name(Score_vector[i].number);
1212                     if (wj == 0)
1213                         printf("%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1214                     else
1215                         fprintf(filepoint, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1216                 }
1217                 int finish = clock();
1218                 if (wj == 1) {
1219                     printf("输出至文件成功,所用时间: %.6f 秒\n", (double)(finish - start) / CLOCKS_PER_SEC);
1220                 }
1221             }
1222             else {
1223                 if (wj == 0)
1224                     printf("语法错误\n");
1225                 continue;
1226             }
1227         }
1228         else if (s[0] == 'E') {
1229             return;
1230         }
1231     }
1232 }
1233 const int X = 800, Y = 600;//画面宽度与高度
1234 
1235 int getmouse() {
1236     MOUSEMSG mouse_message;//鼠标消息变量
1237     while (1) {
1238         if (MouseHit()) {//如果有鼠标消息,进入if
1239             mouse_message = GetMouseMsg();//获取当前的鼠标消息
1240             if (mouse_message.uMsg == WM_LBUTTONDOWN)//如果鼠标左键按下
1241             {
1242                 int x = mouse_message.x;
1243                 int y = mouse_message.y;//获取鼠标当前所在的坐标
1244                                         /*检查鼠标位置*/
1245                 if (x >= 100 && y >= 20 && x <= 300 && y <= 140)
1246                     return 1;//退出鼠标检测函数,进入下一项
1247                 else if (x >= 500 && y >= 20 && x <= 700 && y <= 140)
1248                     return 2;//退出鼠标检测函数,进入下一项
1249                 else if (x >= 100 && y >= 250 && x <= 300 && y <= 370)
1250                     return 3;//退出鼠标检测函数,进入下一项
1251                 else if (x >= 500 && y >= 250 && x <= 700 && y <= 370)
1252                     return 4;
1253             }
1254             FlushMouseMsgBuffer();//清空鼠标消息,以避免消息冲突
1255         }
1256     }
1257 }
1258 
1259 void Message(char *s1, char *s2) {//提示框
1260     HWND hwnd = GetHWnd();//获取窗口句柄
1261     MessageBox(hwnd, s1, s2, 0);//输出相关内容
1262 }
1263 char s[1000];
1264 void openfile()//图形化文件读取
1265 {
1266     const int Max_PATH = 100;
1267     TCHAR szBuffer[Max_PATH] = { 0 }; //保存文件名
1268     HWND m_hWnd = GetHWnd();//获取窗口句柄
1269     OPENFILENAME ofn = { 0 };
1270     ofn.lStructSize = sizeof(ofn);
1271     ofn.hwndOwner = m_hWnd;
1272     ofn.lpstrFilter = _T("TxT文件(*.txt)*.txt所有文件(*.*)*.*");//要选择的文件后缀 
1273     ofn.lpstrInitialDir = _T("C:\\Users\\Administrator\\Desktop\\");//默认的文件路径 
1274     ofn.lpstrFile = szBuffer;//存放文件的缓冲区 
1275     ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer);
1276     ofn.nFilterIndex = 0;
1277     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志如果是多选要加上OFN_ALLOWMULTISELECT
1278     BOOL bSel = GetOpenFileName(&ofn);
1279     if (bSel == false) {
1280         Message("请检查文件输入", "请检查文件输入");
1281             return;
1282     }
1283     FILE* in = NULL;
1284     in = fopen(szBuffer, "r");//只读方式打开文件
1285     if (in == NULL) {//文件打开失败
1286         Message("请检查文件是否存在", "请检查文件是否存在");
1287             return;
1288     }
1289     while (1) {//读取文件    
1290         if(fscanf(in, "%s", s)==EOF)
1291             s[0]='C',s[1]=0;
1292         int len = strlen(s);
1293         if (len <= 0) {
1294         }
1295         else if (s[0] == 'C') {
1296             fclose(in);
1297             in = NULL;
1298             int finish = clock();//获取当前时钟
1299             Message("读取成功", "成功");
1300             return;
1301         }
1302         else if (s[0] == 'S') {
1303             fscanf(in, "%s", s);
1304             if (s[0] == 'N') {
1305                 char name[300];
1306                 int number;
1307                 fscanf(in, "%d", &number);
1308                 fscanf(in, "%s", name);
1309                 set_student_name(number, name);
1310             }
1311             else if (s[0] == 'C') {
1312                 char classes[300];
1313                 int number;
1314                 fscanf(in, "%d", &number);
1315                 fscanf(in, "%s", classes);
1316                 set_student_classnumber(number, classes);
1317                 ListNode *pt;
1318                 pt = Search(classes, 1);
1319                 insert_data(pt, number, 1);
1320             }
1321             else if (s[0] == 'D') {
1322                 char department[300];
1323                 int number;
1324                 fscanf(in, "%d", &number);
1325                 fscanf(in, "%s", department);
1326                 set_student_department(number, department);
1327                 ListNode *pt;
1328                 pt = Search(department, 1);
1329                 insert_data(pt, number, 1);
1330             }
1331             else if (s[0] == 'S') {
1332                 int number;
1333                 char coursename[30];
1334                 int score;
1335                 fscanf(in, "%s", coursename);
1336                 fscanf(in, "%d%d", &number, &score);
1337                 int index = get_student_index(number);
1338                 if (index<0)//若没有该学生信息 
1339                     index = student_insert(number);//插入该学生信息 
1340                 ListNode *pt;
1341                 pt = Search(coursename);
1342                 insert_data(pt, number, score);
1343             }
1344         }
1345     }
1346 }
1347 
1348 void Save_course(){//保存课程
1349     const int Max_PATH = 100;
1350     TCHAR szBuffer[Max_PATH] = { 0 }; //保存文件名
1351     HWND m_hWnd = GetHWnd();//获取窗口句柄
1352     OPENFILENAME ofn = { 0 };
1353     ofn.lStructSize = sizeof(ofn);
1354     ofn.hwndOwner = m_hWnd;
1355     ofn.lpstrFilter = _T("TxT文件(*.txt)*.txt所有文件(*.*)*.*");//要选择的文件后缀 
1356     ofn.lpstrInitialDir = _T("C:\\Users\\Administrator\\Desktop\\");//默认的文件路径 
1357     ofn.lpstrFile = szBuffer;//存放文件的缓冲区 
1358     ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer);
1359     ofn.nFilterIndex = 0;
1360     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志如果是多选要加上OFN_ALLOWMULTISELECT
1361     BOOL bSel = GetOpenFileName(&ofn);
1362     if (bSel == false) {
1363         Message("请检查文件输入", "请检查文件输入");
1364             return;
1365     }
1366     FILE* out = NULL;
1367     out = fopen(szBuffer, "w+");//写入方式打开文件
1368     if (out == NULL) {//文件打开失败
1369         Message("请检查文件是否存在", "请检查文件是否存在");
1370         return;
1371     }
1372     char classes[300];
1373     InputBox(classes,250,"请输入要查询的课程名称","请输入",NULL,0,0,true);//弹出提示输入框 读取用户输入
1374     ListNode* pt;
1375     pt = Search(classes);
1376     fprintf(out,"%7s %7s %7s %7s\n", "名次", "学号", "成绩","名字");
1377     pt->tree_score.out(pt->tree_score.Get_head(), 2,out);
1378     fclose(out);
1379     Message("输出成功", "成功");
1380 }
1381 
1382 void save_class(){//输出课程信息至文件
1383     const int Max_PATH = 100;
1384     TCHAR szBuffer[Max_PATH] = { 0 }; //保存文件名
1385     HWND m_hWnd = GetHWnd();//获取窗口句柄
1386     OPENFILENAME ofn = { 0 };
1387     ofn.lStructSize = sizeof(ofn);
1388     ofn.hwndOwner = m_hWnd;
1389     ofn.lpstrFilter = _T("TxT文件(*.txt)*.txt所有文件(*.*)*.*");//要选择的文件后缀 
1390     ofn.lpstrInitialDir = _T("C:\\Users\\Administrator\\Desktop\\");//默认的文件路径 
1391     ofn.lpstrFile = szBuffer;//存放文件的缓冲区 
1392     ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer);
1393     ofn.nFilterIndex = 0;
1394     ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;//标志如果是多选要加上OFN_ALLOWMULTISELECT
1395     BOOL bSel = GetOpenFileName(&ofn);
1396     if (bSel == false) {
1397         Message("请检查文件输入", "请检查文件输入");
1398             return;
1399     }
1400     FILE* out = NULL;
1401     out = fopen(szBuffer, "w+");//写入方式打开文件
1402     if (out == NULL) {//文件打开失败
1403         Message("请检查文件是否存在", "请检查文件是否存在");
1404         return;
1405     }
1406     char classes[300];
1407     InputBox(classes,250,"请输入要查询的班级或系别名称","请输入",NULL,0,0,true);//弹出提示输入框 读取用户输入
1408     ListNode* pt;
1409     pt = Search(classes);
1410     num_vector.clear();
1411     pt->tree_number.out3(pt->tree_number.Get_head(), &num_vector);
1412     if (num_vector.size() == 0) {
1413     fprintf(out,"该列表没有成员\n");
1414     fclose(out);
1415     return;
1416     }
1417     Score_vector = new ScoreData[num_vector.size()];//创立一个该班人数大小的线性表
1418     int i;
1419     for (i = 0; i < num_vector.size(); i++) {
1420             Score_vector[i].number = num_vector[i];//存储学号
1421             Score_vector[i].score = getsumscore(Score_vector[i].number);
1422     }
1423     Quicksort(Score_vector, 0, num_vector.size() - 1);
1424     fprintf(out, "%7s %7s %7s %7s\n", "排名", "学号", "分数","名字");
1425     for (i = 0; i <= num_vector.size() - 1; i++) {
1426             get_name(Score_vector[i].number);
1427             fprintf(out, "%7d %7d %7d %7s\n", i + 1, Score_vector[i].number, Score_vector[i].score,name);
1428     }
1429     Message("输出成功","输出成功");
1430     fclose(out);
1431 }
1432 void exit(){
1433      closegraph();// 关闭绘图窗口
1434 }
1435 void deal() {
1436     while (1) {
1437         int p = getmouse();
1438         if (p == 1) {
1439             openfile();
1440         }
1441         else if (p == 2) {
1442             Save_course();
1443         }
1444         else if (p == 3) {
1445             save_class();
1446         }
1447         else if (p == 4) {
1448             exit();
1449             return;
1450         }
1451     }
1452 }
1453 
1454 void grap()//图形化界面
1455 {
1456     initgraph(X, Y);//创立界面
1457     HWND hwnd = GetHWnd();//获取窗口句柄
1458     SetWindowText(hwnd, "学生成绩管理系统图形化操作界面 BY:WYS");
1459     IMAGE img1;//初始窗口背景
1460     loadimage(&img1, _T("Main_g.jpg"), X, Y, true);
1461     putimage(0, 0, &img1, SRCCOPY);//在窗口上绘制背景图片 第三个参数为 绘制出的像素颜色=原图形颜色
1462     IMAGE img2, img2f;//保存窗口按钮
1463     loadimage(&img1, _T("Main_g.jpg"), X, Y, true);
1464     putimage(0, 0, &img1, SRCCOPY);//在窗口上绘制背景图片 第三个参数为 绘制出的像素颜色=原图形颜色
1465 
1466     loadimage(&img2f, _T("Opy.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码
1467     putimage(100, 20, &img2f, NOTSRCERASE);//打印标题图片-掩码
1468     loadimage(&img2, _T("Op.jpg"), X / 4, Y / 5, true);//加载标题图片
1469     putimage(100, 20, &img2, SRCINVERT);//打印标题图片
1470 
1471     loadimage(&img2f, _T("bcky.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码
1472     putimage(500, 20, &img2f, NOTSRCERASE);//打印标题图片-掩码
1473     loadimage(&img2, _T("bck.jpg"), X / 4, Y / 5, true);//加载标题图片
1474     putimage(500, 20, &img2, SRCINVERT);//打印标题图片
1475 
1476     loadimage(&img2f, _T("bcby.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码
1477     putimage(100, 250, &img2f, NOTSRCERASE);//打印标题图片-掩码
1478     loadimage(&img2, _T("bcb.jpg"), X / 4, Y / 5, true);//加载标题图片
1479     putimage(100, 250, &img2, SRCINVERT);//打印标题图片
1480 
1481     loadimage(&img2f, _T("exitf.jpg"), X / 4, Y / 5, true);//加载标题图片-掩码
1482     putimage(500, 250, &img2f, NOTSRCERASE);//打印标题图片-掩码
1483     loadimage(&img2, _T("exit.jpg"), X / 4, Y / 5, true);//加载标题图片
1484     putimage(500, 250, &img2, SRCINVERT);//打印标题图片
1485     deal();//处理
1486 }
1487 
1488 void Main_menu() {//主菜单 
1489     while (1) {
1490         Screen_clear();//清屏 
1491         printf("\t\t欢迎使用学生成绩管理系统\n");
1492         printf("\t\t\t请输入操作命令\n");
1493         printf("\t\t\t1.录入/修改系统\n");
1494         printf("\t\t\t2.查询系统\n");
1495         printf("\t\t\t3.班/系 成绩分析系统\n");
1496         printf("\t\t\t4.课程成绩分析系统\n");
1497         printf("\t\t\t5.排名系统\n");
1498         printf("\t\t\t6.退出程序\n");
1499         printf("\t\t\t7.拓展功能:图形化操作模式\n");
1500         printf("\t\t\t请您输入操作指令\n");
1501         printf("\t\t\t");
1502         char s;
1503         s = getchar();
1504         if (!(s <= '7'&&s >= '1')) {//检查输入命令 
1505             fflush(stdin);//清空输入缓冲区 
1506             continue;
1507         }
1508         int order = s - '0';//获取命令编号 
1509         if (order == 1)
1510             Input_System();
1511         else if (order == 2)
1512             Output_System();
1513         else if (order == 3)
1514             Analyze_System();
1515         else if (order == 4)
1516             Course_System();
1517         else if (order == 5)
1518             Rank_System();
1519         else if (order == 6)
1520             exit(0);
1521         else if (order == 7)
1522             grap();
1523     }
1524 }
1525 
1526 int main() {
1527     srand(time(0));
1528     Main_menu();
1529     return 0;
1530 }

 

posted @ 2018-03-09 20:23  晓风微微  阅读(292)  评论(0编辑  收藏  举报