用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;
}

posted @ 2008-11-18 23:59  Beetlebum  阅读(398)  评论(0编辑  收藏  举报