📄 bigwork.cpp
字号:
#include"genealogy.h"
GEnealogy::GEnealogy()
{
T=NULL;//开始为空家谱
}
GEnealogy::~GEnealogy()
{
DestroyGEnealogy();//释放资源
}
void GEnealogy::NewGEnealogy()
{
//建立一空家谱,
DestroyGEnealogy();//删除原有家谱
T=NULL;
}
void GEnealogy::CreateGEnealogy()
{
DestroyGEnealogy();//删除原来家谱树结构
int n=0;//初始化数组下标,用来看有几多个数据
fstream f("1.dat",ios::binary|ios::in);//以二进制读方式打开
if(!f)
{
cerr<<"File can't be open"<<endl;//不能打开,显示出错信息
return;
}
f.seekg(0,ios::end);//指针移到文件尾
long posEnd=f.tellg();//记录文件尾位置
f.seekg(0,ios::beg);//指针移到文件头
person ParentT=new CSNode;
ParentT=NULL;
person temp[max_char_num];//定义读取数据的数组
for(int i=0;i<max_char_num;i++)
temp[i]=new CSNode;//初始化一个地址值,且不能为空否则出错
if( posEnd == f.tellg( ) )
{
cout<<"It's a null Genealogy"<<endl;//文件头与文件尾相同,说明文件无数据,为空树
return;
}
while( posEnd != f.tellg() )//从头到尾读取二进制数据
{
f.read((char*)&(temp[n]->data),sizeof(Info));
n++;
}
NewGEnealogy();
T=temp[0];T->firstchild=T->nextsibling=NULL;//将第一个赋给根结点
for(int j=1;j<n;j++)//其余继续用类似Add()函数来添加进树里
{
FindByName(T,ParentT,temp[j]->data.parentname);
if(ParentT)
{
temp[j]->firstchild=temp[j]->nextsibling=NULL;
temp[j]->parent=ParentT;
if(ParentT->firstchild)
{
InsertSibling(ParentT->firstchild,temp[j]);
}
else
ParentT->firstchild=temp[j];
}
}
f.close();//关闭文件流
}
void DestroyNode(person &pnode)
{
//删除一结点
if(pnode)
{
delete pnode;
pnode=NULL;
}
}
void GEnealogy::DestroyGEnealogy()
{
//删除家谱,释放资源
PostOrderTraverse(T,DestroyNode);
}
void GEnealogy::PostOrderTraverse(person &T,void (__cdecl *Visit)(person &T))
{
//后序遍历二叉树,并执行visit函数
if(T)
{
PostOrderTraverse(T->firstchild,Visit);
PostOrderTraverse(T->nextsibling,Visit);
(*Visit)(T);
}
}
void GEnealogy::PreOrderTraverse(fstream &f,person &T, void (__cdecl *Visit)(fstream &f,person &T))
{
//先序遍历二叉树,并执行visit函数
if(T)
{
(*Visit)(f,T);
PreOrderTraverse(f,T->firstchild,Visit);
PreOrderTraverse(f,T->nextsibling,Visit);
}
}
void SaveNode(fstream &f, person &pnode)
{
//以二进制形式保存一个结点的info信息
if(pnode)
{
f.write ( (char * )&pnode->data, sizeof(Info) ) ;
}
}
void GEnealogy::SaveGEnealogy()
{
//保存二叉树到文件
fstream f("1.dat",ios::binary|ios::out);//以二进制写方式打开文件
if(!f)
{
cerr<<"File can't be open"<<endl;//如果不能打开,显示出错信息
return;
}
PreOrderTraverse(f,T,SaveNode);//调用先序遍历写二叉树信息到文件
f.close();//关闭文件
}
person& GEnealogy::GetRoot()
{
//返回家谱的根结点
return T;
}
void GEnealogy::ReadNode(fstream &f,person &pnode)
{
//读取文件的Info信息到pnode中去,供createGenealogy()调用
f.read((char*)&pnode->data,sizeof(Info));
}
void GEnealogy::FindByName(person& T,person& Tname,char* name)//search the name in info from root T
{
//查找姓名=name的人,若在家谱中,用Tname返回,否则Tname为空,Tname初始为空
if(T)
{
if(strcmp(T->data.name,name)==0) //用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
Tname=T;
else
{
FindByName(T->firstchild,Tname,name); //对T的firstchild递归搜索
FindByName(T->nextsibling,Tname,name); //对T的nextsibling递归搜索
}
}
}
void GEnealogy::FindByBirthplace(person& T,person& Tname,char* birthplace)
{
//查找出生地=birthplace的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(strcmp(T->data.birthplace,birthplace)==0)//用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
{
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname); //调用Display()显示Tname的详细信息
}
FindByBirthplace(T->firstchild,Tname,birthplace); //对T的firstchild递归搜索
FindByBirthplace(T->nextsibling,Tname,birthplace); //对T的nextsibling递归搜索
}
}
void GEnealogy::FindByBirthday(person& T,person& Tname,Date day1)
{
//查找出生日期=day1的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(T->data.birthdate.year==day1.year&&T->data.birthdate.month==day1.month&&T->data.birthdate.day==day1.day)
{ //用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname);//调用Display()显示Tname的详细信息
}
FindByBirthday(T->firstchild,Tname,day1); //对T的firstchild递归搜索
FindByBirthday(T->nextsibling,Tname,day1); //对T的nextsibling递归搜索
}
}
void GEnealogy::FindByDeathday(person& T,person& Tname,Date day1)
{
//查找死亡日期=day1的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(T->data.deathdate.year==day1.year&&T->data.deathdate.month==day1.month&&T->data.deathdate.day==day1.day) //T结点姓名和name相同,把T结点指针传给Tname
{ //用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname);//调用Display()显示Tname的详细信息
}
FindByDeathday(T->firstchild,Tname,day1); //对T的firstchild递归搜索
FindByDeathday(T->nextsibling,Tname,day1); //对T的nextsibling递归搜索
}
}
void GEnealogy::FindBySex(person& T,person& Tname,char *sex)
{
//查找性别=sex的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(strcmp(T->data.sex,sex)==0)//用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
{
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname);//调用Display()显示Tname的详细信息
}
FindBySex(T->firstchild,Tname,sex); //对T的firstchild递归搜索
FindBySex(T->nextsibling,Tname,sex); //对T的nextsibling递归搜索
}
}
void GEnealogy::FindByHeight(person& T,person& Tname,int h)
{
//查找身高=h的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(T->data.height==h)
{
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname);//调用Display()显示Tname的详细信息
}
FindByHeight(T->firstchild,Tname,h);//对T的firstchild递归搜索
FindByHeight(T->nextsibling,Tname,h); //对T的nextsibling递归搜索
}
}
void GEnealogy::FindByEducation(person& T,person& Tname,char* edu)
{
//查找受教育程度=edu的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(strcmp(T->data.education,edu)==0) //用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
{
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname);//调用Display()显示Tname的详细信息
}
FindByEducation(T->firstchild,Tname,edu); //对T的firstchild递归搜索
FindByEducation(T->nextsibling,Tname,edu); //对T的nextsibling递归搜索
}
}
void GEnealogy::FindByOccupation(person& T,person& Tname,char* job)
{
//查找职位=job的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(strcmp(T->data.occupation,job)==0)//用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
{
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname);//调用Display()显示Tname的详细信息
}
FindByOccupation(T->firstchild,Tname,job); //对T的firstchild递归搜索
FindByOccupation(T->nextsibling,Tname,job); //对T的nextsibling递归搜索
}
}
void GEnealogy::FindByTopHeadship(person& T,person& Tname,char* top)
{
//查找最高职位=top的人,若在家谱中,则显示出来,否则显示出错信息,Tname初始为空
if(T)
{
if(strcmp(T->data.top_headship,top)==0) //用string库的strcmp()比较两个字符串,若相等,则找到符合条件的
{
Tname=T;
cout<<"Record found!"<<endl;
Display(Tname);//调用Display()显示Tname的详细信息
}
FindByTopHeadship(T->firstchild,Tname,top); //对T的firstchild递归搜索
FindByTopHeadship(T->nextsibling,Tname,top);//对T的nextsibling递归搜索
}
}
void GEnealogy::AddOperation()
{
person result=new CSNode;//初始化搜索结果的结点
person pnode=new CSNode;//初始化要添加的结点
char Name1[max_char_num];
cout<<"Please input the information of the person"<<endl;
InputData(pnode); //输入pnode基本信息
cout<<"Please input the name of the person you want to add for current person's parent"<<endl;
cin>>Name1;
result=NULL;//result初值赋NULL,以供各个find函数调用
FindByName(T,result,Name1);
if(result) //找到符合条件的结点
{
strcpy(pnode->data.parentname,Name1);//将Name1值赋给pnode结点的parentname,以供读取文件建二叉树用
Add(result,pnode); //将pnode添加到result的孩子结点中去
cout<<"Add successfully"<<endl;
}
else
cout<<"No such a person"<<endl;//输出出错信息
}
void GEnealogy::Inquire()
{
char keyword[max_char_num];
int choice;
int key;
Date day;
person tname;
//以上初始化各个变量,以供搜索函数调用
while(1)
{
//输出选择菜单
cout<<"please choose inquire condition"<<endl;
cout<<"1.by name"<<endl;
cout<<"2.by birthplace"<<endl;
cout<<"3.by birthday"<<endl;
cout<<"4.by deathday"<<endl;
cout<<"5.by sex"<<endl;
cout<<"6.by height"<<endl;
cout<<"7.by education"<<endl;
cout<<"8.by occupation"<<endl;
cout<<"9.by top headship"<<endl;
cout<<"0.exit"<<endl;
cin>>choice;
switch(choice)
{
case 1:
//选1,执行搜索姓名函数
cout<<"please input the name you want to inquire:";
cin>>keyword;
tname=NULL;
FindByName(T,tname,keyword);
if(tname)
{
Display(tname);
}
else
cout<<"NO such a person"<<endl;
break;
case 2:
//选2,执行搜索出生地点函数
cout<<"please input the birthplace you want to inquire:";
cin>>keyword;
tname=NULL;
FindByBirthplace(T,tname,keyword);
if(!tname)cout<<"NO such a person"<<endl;
break;
case 3:
//选3,执行搜索出生日期函数
cout<<"please input the birthday you want to inquire"<<endl;
cout<<"input the year of the birthday:";
cin>>day.year;
cout<<"input the month of the birthday:";
cin>>day.month;
cout<<"input the day of the birthday:";
cin>>day.day;
tname=NULL;
FindByBirthday(T,tname,day);
if(!tname)cout<<"NO such a person"<<endl;
break;
case 4:
//选4,执行搜索死亡日期函数
cout<<"please input the birthday you want to inquire:";
cout<<"input the year of the deathday:";
cin>>day.year;
cout<<"input the month of the deathday:";
cin>>day.month;
cout<<"input the day of the deathday:";
cin>>day.day;
tname=NULL;
FindByDeathday(T,tname,day);
if(!tname)cout<<"NO such a person"<<endl;
break;
case 5:
//选5,执行搜索性别函数
cout<<"please input the sex('m' or 'f') you want to inquire:";
cin>>keyword;
tname=NULL;
FindBySex(T,tname,keyword);
if(!tname)cout<<"NO such a person"<<endl;
break;
case 6:
//选6,执行搜索身高函数
cout<<"please input the height you want to inquire:";
cin>>key;
tname=NULL;
FindByHeight(T,tname,key);
if(!tname)cout<<"NO such a person"<<endl;
break;
case 7:
//选7,执行搜索教育程度函数
cout<<"please input the education you want to inquire:";
cin>>keyword;
tname=NULL;
FindByEducation(T,tname,keyword);
if(!tname)cout<<"NO such a person"<<endl;
break;
case 8:
//选8,执行搜索职位函数
cout<<"please input the occupation you want to inquire:";
cin>>keyword;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -