用SBT实现一个学生健康管理系统...

 

此乃数据结构作业

//         程序名:student.cpp
//       程序功能:用Size Balanced Tree实现一个学生管理系统
//           作者:zgmf_x20a
//           日期:2008.11.18
//           版本:1.0
//             说明:SBT是一颗高度平衡的二叉搜索树,它的所有动态操作,包括查找,求最小值,最大值,前驱,后继,
//                   插入和删除,在最坏的情况下都保持在O(log n),而且实现简单

#include 
< iostream >
#include 
< fstream >
#include 
< string >
using   namespace  std;


ifstream fin;
ofstream fout;

struct  Datatype{
    
int  ID;
    
string  name;
    
string  birth;
    
string  sex;
    
string  health;
    
void   operator = (Datatype temp){
        ID
= temp.ID;
        name
= temp.name;
        birth
= temp.birth;
        sex
= temp.sex;
        health
= temp.health;
    }
};

inline 
void  InputData(Datatype  * a){
    cin
>> a -> ID >> a -> name >> a -> birth >> a -> sex >> a -> health;
}

inline 
void  OutputData(Datatype  * a){
    cout
<< a -> ID << ' \t ' << a -> name << ' \t ' << a -> birth << " \t\t " << a -> sex << ' \t ' << a -> health << ' \n ' ;
}

struct  SBTNode{
    SBTNode 
* lc, * rc;
    
int  sz;
    Datatype key;
    SBTNode(Datatype
*  _key){
        key
=* _key;
        sz
= 1 ;
        lc
= NULL;
        rc
= NULL;
    }
};

////////////////////////////// /

SBTNode
*  SBTSearch(SBTNode *  T, int  ID);

void  SBTInsert(SBTNode *   & T,SBTNode *  x); // 修改了树的结构,故参数需引用

Datatype
*  SBTDel(SBTNode *   & T, int  ID); //

SBTNode
*  SBTPred(SBTNode *  T, int  ID);

SBTNode
*  SBTSucc(SBTNode *  T, int  ID);

SBTNode
*  SBTSelect(SBTNode *  T, int  k);

int  SBTRank(SBTNode *  T, int  ID);

void  InOrder(SBTNode *  T);

//////////////////////////////


void  RightRotate(SBTNode *   & x){
    
int  res = 0 ;
    SBTNode
*  y = x -> lc;
    x
-> lc = y -> rc;
    y
-> rc = x;
    y
-> sz = x -> sz;
    
if (x -> lc != NULL)
        res
+= x -> lc -> sz;
    
if (x -> rc != NULL)
        res
+= x -> rc -> sz;
    x
-> sz = res + 1 ;
    x
= y;
}

void  LeftRotate(SBTNode *   & x){
    
int  res = 0 ;
    SBTNode
*  y = x -> rc;
    x
-> rc = y -> lc;
    y
-> lc = x;
    y
-> sz = x -> sz;
    
if (x -> lc != NULL)
        res
+= x -> lc -> sz;
    
if (x -> rc != NULL)
        res
+= x -> rc -> sz;
    x
-> sz = res + 1 ;
    x
= y;
}

SBTNode
*  SBTSearch(SBTNode *  T, int  ID){
    
if ( ! ||  ID == T -> key.ID)
        
return  T;
    
if (ID < T -> key.ID)
        
return  SBTSearch(T -> lc,ID);
    
else
        
return  SBTSearch(T -> rc,ID);
}

void  Maintain(SBTNode *   & T, bool  RightDeeper){
    
if (T == NULL  ||  T -> sz <= 2 )
        
return ;
    
if ( ! RightDeeper){
        
if (T -> lc  &&  T -> lc -> lc  &&  ( T -> rc == NULL  ||  T -> lc -> lc -> sz > T -> rc -> sz))
            RightRotate(T);
        
else   if (T -> lc  &&  T -> lc -> rc  &&  (T -> rc == NULL  ||  T -> lc -> rc -> sz > T -> rc -> sz)){
            LeftRotate(T
-> lc);
            RightRotate(T);
        }
        
else
            
return ;
    }
    
else {
        
if (T -> rc  &&  T -> rc -> rc  &&  ( T -> lc == NULL  ||  T -> rc -> rc -> sz > T -> lc -> sz))
            LeftRotate(T);
        
else   if (T -> rc  &&  T -> rc -> lc  &&  (T -> lc == NULL  ||  T -> rc -> lc -> sz > T -> lc -> sz)){
            RightRotate(T
-> rc);
            LeftRotate(T);
        }
        
else
            
return ;
    }
    
// if(T->lc->sz>2)
        Maintain(T -> lc, false );
    
// if(T->rc->sz>2)
        Maintain(T -> rc, true );
    
// if(T->sz>2)
        Maintain(T, false );
    
// if(T->sz>2)
        Maintain(T, true );
}

void  SBTInsert(SBTNode *   & T,SBTNode *  x){
    
if (T == NULL){
        T
= x;
        
return ;
    }
    T
-> sz ++ ;
    
if (x -> key.ID < T -> key.ID)
        SBTInsert(T
-> lc,x);
    
else
        SBTInsert(T
-> rc,x);
    
// if(T->sz>2)
        Maintain(T,x -> key.ID >= T -> key.ID);
}

Datatype
*  SBTDel(SBTNode *   & T, int  ID){
    Datatype 
* record, * temp;
    
if (T -> sz <= 2 ){
        record
= new  Datatype;
        
* record = T -> key;
        
// T=T->lc+T->rc;
        T = T -> lc ? T -> lc:T -> rc;
        
return  record;
    }
    T
-> sz -- ;
    
if (ID == T -> key.ID){
        
int  res = 0 ;
        record
= SBTDel(T -> lc,ID + 1 );

        temp
= new  Datatype;
        
* temp = T -> key;
        T
-> key =* record; //
         * record =* temp;

        
if (T -> lc)
            res
+= T -> lc -> sz;
        
if (T -> rc)
            res
+= T -> rc -> sz;
        
// T->sz=record->sz; //
        T -> sz = res + 1 ;
        Maintain(T,
true );
    }
    
else   if (ID < T -> key.ID)
        record
= SBTDel(T -> lc,ID);
    
else
        record
= SBTDel(T -> rc,ID);
    Maintain(T,ID
< T -> key.ID);
    
return  record;
}

SBTNode
*  SBTPred(SBTNode *  T, int  ID){
    
if ( ! T)
        
return  NULL;
    
if (ID <= T -> key.ID)
        
return  SBTPred(T -> rc,ID);
    
else {
        SBTNode
*  pred = SBTPred(T -> rc,ID);
        
return  (pred ? pred:T);
    }
}

SBTNode
*  SBTSucc(SBTNode *  T, int  ID){
    
if ( ! T)
        
return  NULL;
    
if (ID >= T -> key.ID)
        
return  SBTSucc(T -> rc,ID);
    
else {
        SBTNode
*  succ = SBTSucc(T -> lc,ID);
        
return  (succ ? succ:T);
    }
}
 
SBTNode
*  SBTSelect(SBTNode *  T, int  k){
    
if (k == T -> lc -> sz + 1 )
        
return  T;
    
if (k <= T -> lc -> sz)
        
return  SBTSelect(T -> lc,k);
    
else
        
return  SBTSelect(T -> rc,k - 1 - T -> lc -> sz);
}


int  SBTRank(SBTNode *  T, int  ID){
    
if (T == NULL)
        
return   1 ;
    
if (ID <= T -> key.ID)
        
return  SBTRank(T -> lc,ID);
    
else
        
return  T -> lc -> sz + 1 + SBTRank(T -> rc,ID);
}

void  InOrder(SBTNode  * T){
    
if (T == NULL)
        
return ;
    InOrder(T
-> lc);
    OutputData(
& (T -> key));
    InOrder(T
-> rc);
}

void  InOrder_file(SBTNode  * T){
    
if (T == NULL)
        
return ;
    InOrder_file(T
-> lc);
    
// fout.write((char*)&(T->key),sizeof(T->key));
    fout << T -> key.ID << '   ' << T -> key.name << '   ' << T -> key.birth << '   ' << T -> key.sex << '   ' << T -> key.health << " \n " ;
    InOrder_file(T
-> rc);
}



////////////////////////////////////////////////


void  menu(){
        cout
<< " \n-----------菜单---------------\n " ;
        cout
<< " |1.新建学生健康表\n " ;
        cout
<< " |2.向学生健康表插入学生信息\n " ;
        cout
<< " |3.在健康表删除学生信息\n " ;
        cout
<< " |4.从文件中读取健康表信息\n " ;
        cout
<< " |5.向文件写入学生健康表信息\n " ;
        cout
<< " |6.在健康表中查询学生信息(按学生学号来进行查找)\n " ;
        cout
<< " |7.在屏幕中输出全部学生信息\n " ;
        cout
<< " |8.退出\n " ;
        cout
<< " ------------------------------\n\n " ;
        cout
<< " 请输入一种操作:\n " ;
}


bool  input( int   & x){
    cin
>> x;
    
if ( ! cin.good()){
        cin.clear();
        cin.ignore();
        
return   false ;
    }
    
return   true ;
}

int  main(){

    
int  chose,i,n,ID;
    
char  ch;
    
bool  flag = true ;

    system(
" color 74 " );

    SBTNode 
* T, * temp;
    Datatype 
* datatemp;


    
while (flag){

        menu();

        
while ( ! (input(chose)  &&  chose >= 1   &&  chose <= 11 ))
            cout
<< " 输入有误,请重新输入: " ;

        
switch (chose){

        
case   1 :
            T
= NULL;
            cout
<< " 请输入将要输入学生数目: " ;
            
while ( ! input(n))
                cout
<< " 输入有误,请重新输入: " ;


            cout
<< " 请顺序输入学号、姓名、出生日期、性别、身体状况(用空格区分):\n " ;
            
for (i = 1 ;i <= n;i ++ ){
                cout
<< " 请输入第 " << i << " 个学生的数据:\n " ;
                datatemp
= new  Datatype;
                
// cin>>datatemp->ID>>datatemp->name>>datatemp->birth>>datatemp->sex>>datatemp->health;
                InputData(datatemp);
                temp
= new  SBTNode(datatemp);
                SBTInsert(T,temp);
            }
            
            
            cout
<< " 建表成功!\n\n " ;
            system(
" PAUSE " );
            
break ;

        
case   2 :
            cout
<< " 顺序输入学号、姓名、出生日期、性别、身体状况(用空格区分):\n " ;
            datatemp
= new  Datatype;
            
// cin>>datatemp->ID>>datatemp->name>>datatemp->birth>>datatemp->sex>>datatemp->health;
            InputData(datatemp);
            temp
= new  SBTNode(datatemp);
            SBTInsert(T,temp);    

            cout
<< " 插入成功!\n\n " ;
            system(
" PAUSE " );
            
break ;

        
case   3 :
            
if (T == NULL){
                cout
<< " 学生健康表已为空!\n " ;
                system(
" PAUSE " );
                
break ;
            }

            cout
<< " 请输入需要删除的学生的学号(若该学号不存在则删除下一个较大的学号): " ;
            cin
>> ID;
            cout
<< " 你将要删除的学生信息如下:\n " ;
            datatemp
= SBTDel(T,ID);
            cout
<< " 学号\t姓名\t出生日期\t性别\t身体状况\n " ;
            
// cout<<datatemp->ID<<'\t'<<datatemp->name<<'\t'<<datatemp->birth<<'\t'<<datatemp->sex<<'\t'<<datatemp->health<<'\n';
            OutputData(datatemp);
            cout
<< " 确定删除?(Y/N): " ;
            cin
>> ch;
            
if (ch == ' N ' ){
                temp
= new  SBTNode(datatemp);
                temp
-> lc = temp -> rc = NULL;
                temp
-> sz = 1 ;
                SBTInsert(T,temp);
            }
            
else
                cout
<< " 删除成功!\n\n " ;


            system(
" PAUSE " );
            
break ;

        
case   4 :
            fin.clear();
            fin.open(
" student.dat " ,ios:: in   |  ios::binary);
            
if ( ! fin)
                cout
<< " 文件打开失败!请检查student.dat是否在根目录中。\n\n " ;
            
else {
                T
= NULL;
                datatemp
= new  Datatype;
                
while (fin >> datatemp -> ID >> datatemp -> name >> datatemp -> birth >> datatemp -> sex >> datatemp -> health){
                    temp
= new  SBTNode(datatemp);
                    SBTInsert(T,temp);
                    datatemp
= new  Datatype;
                }
                cout
<< " 文件读入成功!\n\n " ;
            }
            
            fin.close();

            system(
" PAUSE " );
            
break ;

        
case   5 :
            fout.clear();
            fout.open(
" student.dat " ,ios:: out   |  ios::binary);
            
if ( ! fout)
                cout
<< " 文件保存失败!\n\n " ;
            
else {
                InOrder_file(T);
                cout
<< " 文件保存成功!\n\n " ;
            }
            fout.close();

            system(
" PAUSE " );
            
break ;

        
case   6 :
            cout
<< " 请输入目标学生的学号: " ;
            cin
>> ID;
            temp
= SBTSearch(T,ID);
            
if (temp == NULL)
                cout
<< " 该学生不存在!\n " ;
            
else {
                cout
<< " 该学生的资料如下:\n " ;
                cout
<< " 学号\t姓名\t出生日期\t性别\t身体状况\n " ;
                OutputData(
& (temp -> key));
            }

            cout
<< " \n " ;
            system(
" PAUSE " );
            
break ;
        
        
case   7 :
            cout
<< " 学号\t姓名\t出生日期\t性别\t身体状况\n " ;
            InOrder(T);
            cout
<< " \n " ;
            system(
" PAUSE " );
            
break ;

        
case   8 :
            flag
= false ;
            
break ;

        }
    }
    
return   0 ;
}

你可能感兴趣的:(管理)