⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bigwork.cpp

📁 数据结构课程设计——家谱管理系统设计与实现
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -