家谱管理系统~数据结构大作业

合集下载

家谱管理系统-数据结构大作业

家谱管理系统-数据结构大作业
printf("\t 女 "); if(T->live)
printf("\t 健在 \n"); if(!T->live)
printf("\t 去世于 :%s\n",T->livemassage);*/ PrintInfo(T); PreOrderTraverse_recursion(T->lc); PreOrderTraverse_recursion(T->rc); }
T = NULL; fscanf(in,"%c",&ch); } else { T = (BiTree)malloc(sizeof(BiTNode));
//fscanf(in,"%s%s%s%d%d",nametemp,birthdaytemp,addresstemp,&marriagetemp,&livetemp); fscanf(in,"%s",nametemp); strcpy(T->name,nametemp); fscanf(in,"%s",birthdaytemp); strcpy(T->birthday,birthdaytemp); fscanf(in,"%s",addresstemp); strcpy(T->address,addresstemp); fscanf(in,"%d%d%d%d",&marriagetemp,&livetemp,&leveltemp,&sextemp); T->marriage = marriagetemp; T->live = livetemp; T->level = leveltemp; T->sex = sextemp;

数据结构-家谱管理系统

数据结构-家谱管理系统

数据结构-家谱管理系统数据结构家谱管理系统在当今数字化的时代,信息管理变得越来越重要,而家谱作为家族历史和传承的重要记录,也需要一种有效的管理方式。

一个高效的家谱管理系统能够帮助我们更好地保存、查询和分析家族信息,增强家族成员之间的联系和认同感。

接下来,让我们深入探讨一下家谱管理系统所涉及的数据结构和功能。

首先,我们来了解一下什么是数据结构。

简单来说,数据结构是指数据元素之间的关系和组织方式。

在家谱管理系统中,我们需要选择合适的数据结构来存储和操作家族成员的信息。

一种常见的数据结构选择是树形结构。

家谱本身就具有天然的层次关系,从祖先开始,逐渐分支到子孙后代。

我们可以将每个家族成员看作一个节点,通过父子关系将节点连接起来,形成一棵家族树。

这种树形结构能够清晰地展示家族的分支和传承关系。

为了实现树形结构,我们可以使用链表或者数组来存储节点信息。

链表的优点是插入和删除节点比较方便,适合家族成员信息的动态变化。

而数组则可以更高效地随机访问节点,但在插入和删除操作时可能需要移动大量元素。

在家谱管理系统中,每个家族成员的节点应该包含哪些信息呢?至少要包括姓名、性别、出生日期、婚姻状况等基本信息。

此外,还可以添加照片、个人简介、联系方式等扩展信息,以丰富家族成员的资料。

除了存储家族成员的信息,家谱管理系统还需要提供强大的查询功能。

用户可能想要查找特定姓名的家族成员,或者查找某个时间段出生的成员,甚至是查找具有特定亲属关系的成员。

为了实现这些查询功能,我们可以在数据结构中建立索引,例如按照姓名建立哈希索引,按照出生日期建立排序索引等。

这样可以大大提高查询的效率。

另外,家族关系的计算也是家谱管理系统的一个重要功能。

比如,计算两个家族成员之间的亲属关系远近,判断是否存在共同的祖先等。

这需要我们在树形结构的基础上进行深度优先搜索或者广度优先搜索等算法的应用。

在数据存储方面,我们可以选择将家谱数据存储在本地文件中,如XML 或者 JSON 格式,也可以选择将数据存储在数据库中,如关系型数据库 MySQL 或者非关系型数据库 MongoDB。

家谱管理系统 -数据构架大作业

家谱管理系统 -数据构架大作业

精心整理/*家谱管理系统任务:实现具有下列功能的家谱管理系统功能要求:1).输入文件以存放最初家谱中各成员的信息,成员的信息中均应包含以2).3).4).5).。

6).7).8).9).10).11).12).打开一家谱时,提示当天生日的健在成员。

要求:建立至少30个成员的数据,以较为直观的方式显示结果,并提供文稿形式以便检查。

界面要求:有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。

存储结构:学生自己根据系统功能要求自己设计,但是要求相关数据要存储在数据文件中。

测试数据:要求使用1、全部合法数据;2、局部非法数据。

进行程序测试,以保证程序的稳定。

测试数据及测试结果请在上交的资料中写明;*///树{intmark;//标记intlevel;charname[50];//姓名charbirthday[50];//生日charaddress[MAXN];//住址boolmarriage;//婚否(true表示结婚,false表示没结婚)boollive;//建在(true表示活着,false表示过世)boolsex;//性别(true表示男,false表示女)charlivemassage[50];//死亡日期(如果其已经死亡)Elemtypedata;////charsearchdata[50];charsearchname[50];intcount;//计数intchoice;//各种选择intuse;BiTreetemp;structBiTNodeList{BiTreedata;BiTNodeList*next;};{{}else{T=(BiTree)malloc(sizeof(BiTNode));//fscanf(in,"%s%s%s%d%d",nametemp,birthdaytemp,addresstemp,&mar riagetemp,&livetemp);fscanf(in,"%s",nametemp);strcpy(T->name,nametemp);fscanf(in,"%s",birthdaytemp);strcpy(T->birthday,birthdaytemp); fscanf(in,"%s",addresstemp);strcpy(T->address,addresstemp);p);{}if(!T->live)strcpy(T->livemassage,livemassagetemp); fscanf(in,"%c",&ch);CreatBiTree(T->lc,in);CreatBiTree(T->rc,in);}}voidPrintInfo(BiTreeT){printf("%-10s出生于}voidPreOrderTraverse_recursion(BiTreeT)//递归先序遍历(检查建树是否正确){//printf("PreOrderTraverse_recursion\n");if(T){/*printf("%-10s出生于:%-10s%-10s",T->name,T->birthday,T->address);if(T->marriage)PreOrderTraverse_recursion(T->rc);}}voidShowFamilyTree(BiTreeT)//以图形的方式显示家谱{inti,lev;BiTreep;p=T;if(T){{{}}elseprintf("(未婚)\n"); }if(T->rc){p=T->rc;ShowFamilyTree(p);}}{{{}}}voidSearchByName(BiTreeT)//按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。

家谱管理系统(含源代码)1230

家谱管理系统(含源代码)1230

家谱管理系统——C 语言(数据结构)目的和要求:树形结构是一种非常重要的非线性结构,它用于描述数据元素之间的层次关系,人类家谱是树形结构的典型体现,通过此项训练让学生掌握树形结构的知识;使学生重点掌握树与二叉树的转换,二叉树的存储和遍历,和二叉树相关的一些运算;要求完成家谱信息的录入和保存,任意成员的查找及某一成员祖先、子孙、兄弟、堂兄弟的查找。

排答疑和辅导。

完整代码:#include<stdio.h>#include<stdlib.h>#include<string.h>intMATEFLAG=0;//是否入赘或嫁入这家的,1表示为是,0表示否TreeNode//树节点定义structTreeNodestructTreeNode}TreeNode;voidCreatTree(TreeNode*Tree);//创建树voidOutPutAII(TreeNode*Tree);//输出树TreeNode*SearchTree(TreeNode*Tree ,charname[],intlength);voidMainMenu(TreeNode*Tree);voidSubMenue1(TreeNode*Tree);voidSubMenue2(TreeNode*Tree);voidChange(TreeNode*Tree);voidAddNew(TreeNode*Tree);voidOutPutMessage(TreeNode*Tree ,charname[],intlength);//主函数voidmain(){TreeNode*Tree;//产生根节点Tree=(TreeNode*)malloc(sizeof(TreeNode));Tree->Parent=NULL;MainMenu(Tree);//显示主菜单}//添加新的成员voidAddNew(TreeNode*Tree){SubMenue2(Tree);//添加新成员界面}//显示添加家庭信息的界面voidSubMenue2(TreeNode*Tree) int Num; //保存此人儿女个数cha r Name[20]; //保存此人姓名cha r Kind; //保存此人性别,男M,女FNextNode[20];//保存此人的儿女,NextNode[0]里存放配偶的地址Parent;//保存此节点的父节点*typedefstruct{{charc;intnum;charname[20];TreeNode*NewNode;getchar();while(1){请选择你的操作添加某个人的子女的信息添加某个人配偶的信息退出请选择相应功能:c=getchar();switch(c){case'A'://添加子女信息请输入那个人的名字Tree二SearchTree(Tree,name,20);//在家谱里查找这个人if(Tree==NULL){该家谱图中没有%$这个人的信息请确认是否输入错误break;}if(Tree->Parent==NULL&&Tree->NextNode[0]==NULL||Tree->Parent!=NULL&&Tree->Name!=Tree ->Parent->NextNode[0]->Name){至今还没有配偶请先添加配偶break;}if(Tree->Parent==NULL&&(Tree->Num>20||Tree->Num<0))Tree->Num=0;if(MATEFLAG==1)Tree=Tree->Parent;NewNode=(TreeNode*)malloc(sizeof(TreeNode));请输入添加人员姓名请输入添加人员性别女F男num=Tree->Num;NewNode->NextNode[0]=(TreeNode*)malloc(sizeof(TreeNode));NewNode->NextNode[0]=NULL;NewNode->Num=0;NewNode->Parent=Tree;Tree->NextNode[num+1]=NewNode;Tree->Num=Tree->Num+1;子女的信息添加成功break;case'B':请输入那个人的名字Tree=SearchTree(Tree,name,20);if(Tree->Parent!=NULL&&strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0||Tree-> NextNode[0]!=NULL){已经有了配偶break;}if(Tree==NULL){该家谱图中没有%$这个人的信息请确认break;}NewNode=(TreeNode*)malloc(sizeof(TreeNode));请输入添加人员姓名请输入添加人员性别女F男NewNode->Parent=Tree;Tree->NextNode[0]=NewNode;break;case'C':本项服务到此结束break;case'':break;default:对不起!你的选择错误break;}if(c=='C'||c=='c')break;请按Enter键继续操作getchar();getchar();}}//修改某个人的信息voidChange(TreeNode*Tree){charname[20];TreeNode*NewNode;请输入你要修改的人的信息NewNode=SearchTree(Tree,name,20);if(NewNode==NULL){该家谱图中没有%$这个人的信息请确认是否输入错误return;}else{SubMenue1(NewNode);}}//输出副菜单voidSubMenue1(TreeNode*Tree){charc;intflag,i;charname[20];charParent[2][20];TreeNode*NewNode;getchar();while(1){请选择你的操作修改个人的信息修改父母的信息修改兄弟姐妹的信息修改子女的信息修改配偶的信息退出c=getchar();switch(c){case'A':请输入修改的姓名:如果不需要修改就输入'0'然后按Enter键继续strcpy(Tree->Name,name);是否要修改性别:如果需要就输入’1'不需要修改就输入'0'然后按Enter键继续if(flag==1){if(Tree->Kind=='F'||Tree->Kind=='f')Tree->Kind='M';elseTree->Kind='F';}个人信息修改成功break;case'B':if(Tree->Parent==NULL)//判断是不是头节点{是这个家谱图里最顶端的人没有父母信息break;}if(MATEFLAG==1)//判断是不是入赘或加入此间的{if(Tree->Kind=='F'||Tree->Kind=='f'){她是嫁入此间的所以父母信息不在家谱内包括}else{他是入赘此间的所以父母信息不在家谱内包括}break;}if(Tree->Parent->Kind=='F'||Tree->Parent->Kind=='f'){母亲父亲}else{父亲母亲}请输入%s要修改的姓名:如果不需要修改就输入'O'然后按Enter键继续strcpy(Tree->Parent->Name,name);请输入%s要修改的姓名:如果不需要修改就输入'0'然后按Enter键继续strcpy(Tree->Parent->NextNode[O]->Name,name);父母的信息修改成功break;case'C':NewNode=Tree->Parent;if(NewNode==NULL)//判断是不是头节点{是这个家谱图里最顶端的人没有兄弟姐妹信息break;}if(MATEFLAG==1)//判断是不是入赘或嫁入这家的{if(Tree->Kind=='F'||Tree->Kind=='f'){她是嫁入此间的所以兄弟姐妹信息不在家谱内包括}else{他是入赘此间的所以兄弟姐妹信息不在家谱内包括}break;}if(NewNode->Num==1){没有兄弟姐妹break;}else{for(i=1;i<=NewNode->Num;i++){if(NewNode->NextNode[i]->Name!=Tree->Name){请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续strcpy(NewNode->NextNode[i]->Name,name);是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续if(flag==1){if(NewNode->NextNode[i]->Kind=='G'||NewNode->NextNode[i]->Kind=='g')NewNode->NextNode[i]->Kind='B';elseNewNode->NextNode[i]->Kind='G';}}}}兄弟姐妹的信息修改成功break;case'D':if(Tree->Num==0){至今还没有子女break;}if(Tree->Parent!=NULL)if(strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0)//如果他是入赘或者是嫁入的就需用配偶节点完成修改{Tree=Tree->Parent;}for(i=1;i<=Tree->Num;i++){请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续strcpy(Tree->NextNode[i]->Name,name);是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续if(flag==1){if(Tree->NextNode[i]->Kind=='F'||Tree->NextNode[i]->Kind=='f')Tree->NextNode[i]->Kind='M';elseTree->NextNode[i]->Kind='F';}}子女的信息修改成功break;case'E':if(Tree->Parent!=NULL){if(Tree->NextNode[0]==NULL&&strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)!=0){至今还没有配偶break;}if(strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0){请输入%s修改的姓名:如果不需要修改就输入'O'然后按Enter键继续strcpy(Tree->Parent->Name,name);}else{请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续strcpy(Tree->NextNode[0]->Name,name);}}else{if(Tree->NextNode[0]==NULL)至今还没有配偶else{请输入%s修改的姓名:如果不需要修改就输入'0'然后按Enter键继续strcpy(Tree->NextNode[0]->Name,name);}}配偶的信息修改成功break;case'F':本项服务到此结束break;case'':break;default:对不起!你的选择错误break;}if(c=='F'||c=='f')break;请按Enter键继续操作getchar();getchar();}}//输出主菜单voidMainMenu(TreeNode*Tree){charc;//用于接受用户输入的选项charname[20];while(1){清屏★★•修改成员信息・★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★请选择相应的功能:c=getchar();switch(c){case'1':TreeNode*NewNode;NewNode=(TreeNode*)malloc(sizeof(TreeNode));//建立新节点请输入姓名给节点姓名赋值TreeNode*NewNode;NewNode=(TreeNode*)malloc(sizeof(TreeNode));请输入性别(女F,男 >Kind));//Tree->Parent=NewNode;家谱图已经建立成功建立 建立{getchar();break;}整个家谱的主要信息如下 OutPutAll(Tree);getchar();break;case'5':{家谱图还未建立请先建立getchar();break;}Change(Tree);getchar();break;case'6':本程序结束,欢迎下次使用。

数据结构大作业之家谱管理系统

数据结构大作业之家谱管理系统

C++实现的数据结构大作业之家谱管理系统欢迎界面:主菜单:其他一些运行结果不在一一列举,一面篇幅过长。

这个家谱管理系统,支持键盘操作,所有的操作都可以用键盘完成,如选择功能、退出等。

代码的实现使用的是c++11标准,与旧标准或有不同。

类的头文件:#include<iostream>#include<string>using std::string;using std::ostream;using std::istream;struct BirthDay{//生日结构变量int year=0;int month=0;int day=0;};class Member{friend class FamilySystem;friend ostream&operator<<(ostream&out,const Member&m);//输出成员信息到控制台friend istream&operator>>(istream&, Member&m);//从文件中读入成员信息public:Member()=default;//使用默认合成构造函数void setE();//通过控制台输入给成员赋值~Member()=default;//使用默认合成析构函数Member*pson=nullptr;//指向儿子的指针Member*pbro=nullptr;//指向兄弟的指针private://成员的各种数据string name="未知";string birthPlace="未知";BirthDay birthDay;string sex="未知";float height=0;int age=0;string education="未知";string job="未知";string father="未知";};class FamilySystem{public:FamilySystem()=default;//使用默认合成构造函数~FamilySystem(){delete root;}bool fileInit();//从文件中读取数据int menu();//显示菜单(功能)bool addMem();//增加成员bool deleteMem();//删除成员bool demandMem();//查询bool demandAve();//查询家庭整体情况bool modifyMem();//修改成员bool showFamily();//展示整个家谱bool saveFile();//保存信息到文件中,将使用两个文件,一个保存成员信息,一个保存家谱整体信息Member*root=nullptr;//家谱数结构的根节点指针?private:int total=0;//总人数float aveAge=0;//平均年龄float aveHeight=0;//平均身高float aveMember=0;//家庭平均人数float ratio=0;//男女比例void calculate();//计算平均值等Member*seek(string);//查找是否存在成员void display(Member*,int);//先序遍历树,用于显示所有成员};extern string gets();//用于接收键盘的输入类的函数及相关操作函数的实现#include<iomanip>#include<vector>#include<fstream>#include<sstream>#include<conio.h>#include"SystemClass.h"using std::cin;using std::cout;using std::endl;using std::setw;using std::vector;using std::ios;using std::ifstream;using std::ofstream;using std::istringstream;string gets(){//从控制台获取字符等信息string s;while(int n=_getch()){if(n==27){throw27;break;}else if(n==13){cout<<endl;break;}else if(n==8){s.pop_back();cout<<"\b \b";}else{cout<<char(n);s.push_back(char(n));}}return s;}//与BirthDay相关的函数istream&operator>>(istream&in,BirthDay&b){//从文件中读取生日的信息in>>b.year>>b.month>>b.day;return in;}ostream&operator<<(ostream&out,BirthDay&b){ out<<b.year<<" "<<b.month<<" "<<b.day;return out;}//与Member相关的函数void Member::setE(){try{istringstream sin;cout<<setw(20)<<"请输入成员信息:\n"<<endl<<setw(20)<<"姓名:";sin.str(gets());sin>>name;cout<<endl<<setw(20)<<"出生地:"; sin.str(gets());sin.clear();sin>> birthPlace;cout<<endl<<setw(20)<<"生日:"; sin.str(gets());while(true){sin.clear();sin>>birthDay.year>>birthDay.month>>birthDay.day;if(!sin||birthDay.year>2014|| birthDay.month>12||birthDay.day>31){cout<<"输入错误,请重新输入:";sin.str(gets());}else break;}cout<<endl<<setw(20)<<"性别:";sin.str(gets());sin.clear();while(sin>>sex){if(sex=="male"||sex=="female"|| sex=="男"||sex=="女")break;else{cout<<"性别必须是male、female、男或者女,请重新输入:";sin.str(gets());sin.clear();}}cout<<endl<<setw(20)<<"身高(厘米):"; sin.str(gets());sin.clear();while(!(sin>>height)){cout<<"输入错误,请重新输入:";sin.str(gets());sin.clear();}cout<<endl<<setw(20)<<"年龄:";sin.str(gets());sin.clear();while(!(sin>>age)||age>300){cout<<"输入错误,请重新输入:"<<endl;sin.str(gets());sin.clear();}cout<<endl<<setw(20)<<"学历:";sin.str(gets());sin.clear();sin>>education;cout<<endl<<setw(20)<<"工作:";sin.str(gets());sin.clear();sin>>job;cout<<endl<<setw(20)<<"父亲:";sin.str(gets());sin.clear();sin>>father;}catch(int ex){throw ex;}return;}ostream&operator<<(ostream&out,const Member &m){out<<endl<<setw(25)<<"该成员信息如下:" <<endl<<endl<<setw(25)<<"姓名: "<<<<endl<< endl<<setw(25)<<"出生地: "<<m.birthPlace <<endl<<endl<<setw(25)<<"生日: "<<m.birthDay.year <<" "<<m.birthDay.month<<" "<<m.birthDay.day<<endl<<endl<<setw(25)<<"性别: "<<m.sex<<endl<< endl<<setw(25)<<"身高(厘米): "<<m.height <<endl<<endl<<setw(25)<<"年龄: "<<m.age<<endl<< endl<<setw(25)<<"学历: "<<cation<< endl<<endl<<setw(25)<<"工作: "<<m.job<<endl<< endl<<setw(25)<<"父亲: "<<m.father<< endl;return out;}istream&operator>>(istream&in,Member&m){in>>>>m.birthPlace>>m.birthDay>>m.sex>>m.height>>m.age>>cation>>m.job>>m.father;return in;}//FamilySystem的成员函数int FamilySystem::menu(){cout<<"\n\n";cout<<" ---------------------------\n";cout<<" | |\n";cout<<" | 系统菜单 |\n";cout<<" | |\n";cout<<" | 1.查询成员 |\n";cout<<" | |\n";cout<<" | 2.查询家庭整体情况 |\n";cout<<" | |\n";cout<<" | 3.添加成员 |\n";cout<<" | |\n";cout<<" | 4.删除成员 |\n";cout<<" | |\n";cout<<" | 5.修改成员信息 |\n";cout<<" | |\n";cout<<" | 6.显示整个家谱 |\n";cout<<" | |\n";cout<<" | 按ESC退出系统 |\n";cout<<" | |\n";cout<<" ---------------------------\n";cout<<" ";int n=0;while(1){n=_getch();if(n==27)break;if(n>=49&&n<=54)break;cout<<"\n请按下1、2、3、4、5、6选择或按ESC键退出!"<<endl;}return n;}bool FamilySystem::fileInit(){ifstream infile;//打开存储成员信息的文件,读入成员信息infile.open("Members.txt",ios::in|ios::_Nocreate);if(!infile){return false;}vector<Member*>genely;//保存这一代成员的指针vector<Member*>next;//保存下一代成员的指针Member*temp=new Member;//临时保存输入的成员信息root=temp;//第一个赋给rootgenely.push_back(root);next.push_back(root);while(infile>>*temp){//将成员放入家族树中,成员的父亲必须是这一代的成员for(auto i=genely.begin();i!= genely.end();++i){if((*i)->name==temp->father){if((*i)->pson==nullptr)(*i)->pson=temp;else{Member*p=(*i)->pson;while(p->pbro!=nullptr)p=p->pbro;p->pbro=temp;}next.push_back(temp);temp=nullptr;break;}}//若成员的父亲不是这一代的成员,则将next赋予genely,迭进下一代if(temp!=nullptr){genely=next;//迭进下一代next.clear();//清空nextfor(auto i:genely){//将成员放入家族树中if(i->name==temp->father){i->pson=temp;next.push_back(temp);temp=nullptr;break;}}}//动态创建临时成员变量,用于存储输入的下一个成员的信息temp=new Member;}infile.close();//关闭存储成员信息的文件//若文件中没有成员信息,将root置为空if(root->name=="未知")root=nullptr;//打开存储家庭总体信息的文件,读入信息infile.open("Wholes.txt",ios::in|ios::_Nocreate);if(!infile){return false;}infile>>total>>aveAge>>aveHeight>> aveMember>>ratio;infile.close();//关闭文件return true;}Member*FamilySystem::seek(string nam){ //若家谱树为空,返回空指针if(root==nullptr)return nullptr;//若root不为空,继续查找Member*store=nullptr;//存储返回的指针vector<Member*>genely;//存储这一代的指针genely.push_back(root);vector<Member*>next;//存储下一代的指针for(;;){//循环查找//在这一代中查找,若找到,跳到最后for(auto p:genely){if(p->name==nam){store=p;goto End;}}//判断下一代是否为空,若为空,跳到最后int jubge=0;for(auto p:genely){if(p->pson!=nullptr)++jubge;}if(jubge==0)goto End;//找到下一代for(auto p:genely){Member*temp=p->pson;if(temp==nullptr)continue;else{next.push_back(temp);while(temp->pbro!=nullptr){next.push_back(temp->pbro);temp=temp->pbro;}}}genely=next;next.clear();}End:return store;}bool FamilySystem::addMem(){cout<<"3.添加成员.\n";Member*temp=new Member;try{temp->setE();//输入成员信息}catch(int){return false;}//检查其父亲是否存在Member*jubge=seek(temp->father);if(root==nullptr)root=temp;else if(jubge==nullptr){cout<<"\n 家谱中没有此人父亲的信息!无法插入!";cout<<"\n 请确认此人是否此家族中的人!";}else{if(seek(temp->name)!=nullptr){cout<<"\n\n 此人已存在于家谱中!" <<endl;}else{cout<<" 按ENTER确定添加并返回菜单\n 按ESC取消添加并返回菜单";for(;;){int j=_getch();if(j==27){delete temp;break;}if(j==13){if(jubge->pson==nullptr)jubge->pson=temp;else{Member*p=jubge->pson;while(p->pbro!=nullptr)p=p->pbro;p->pbro=temp;}cout<<"\n 保存成功!\n";break;}}}}cout<<"\n按ESC键返回菜单";for(;;){if(_getch()==27)break;}return true;}bool FamilySystem::deleteMem(){cout<<"4.删除成员.\n\n";cout<<" 请输入姓名:";string na;try{istringstream sin(gets());sin>>na;}catch(int){goto end;}Member*temp=seek(na);if(temp==nullptr)cout<<"\n\n 家谱中没有此人!\n\n";else{if(temp->pson!=nullptr){cout<<"\n\n 此人有后代!若删除此人其后代将同时被删!";cout<<"\n\n 按ENTER继续\n 按ESC退出";for(;;){int j=_getch();if(j==27)return false;if(j==13)break;}}Member*p=seek(temp->father);if(p==nullptr)root=nullptr;else if(temp==p->pson)p->pson=nullptr;else{while(p->pbro!=temp){p=p->pbro;}p->pbro=nullptr;}cout<<"\n\n 删除成功!\n\n";}cout<<"\n按ESC键返回菜单";for(;;){if(_getch()==27)break;}end:return true;}bool FamilySystem::demandMem(){cout<<"1.查询成员.\n\n";cout<<" 请输入姓名:";string na;try{istringstream sin(gets());sin>>na;}catch(int){goto end;}Member*m=seek(na);if(m!=nullptr)cout<<*m;else cout<<"\n\n 对不起,家谱中没有此人的信息!\n\n";cout<<"\n按ESC键返回菜单";for(;;){if(_getch()==27)break;}end:return true;}void FamilySystem::calculate(){//若家谱树为空,将各总体值置零if(root==nullptr){total=0;aveAge=0;aveHeight=0;aveMember=0;ratio=0;return;}//若root不为空,继续vector<Member*>genely;//存储这一代的指针genely.push_back(root);vector<Member*>next;//存储下一代的指针int girl=0;//女性数int family=0;//家庭数total=0;aveAge=0;aveHeight=0;//initializefor(;;){//循环叠加各所需总体数据//在这一代中for(auto p:genely){++total;aveAge+=p->age;aveHeight+=p->height;if(p->sex=="female"||p->sex=="女")++girl;}//判断下一代是否为空,若为空,跳到最后int jubge=0;for(auto p:genely){if(p->pson!=nullptr){++jubge;++family;}}if(jubge==0)goto cal;//找到下一代for(auto p:genely){Member*temp=p->pson;if(temp==nullptr)continue;else{next.push_back(temp);while(temp->pbro!=nullptr){next.push_back(temp->pbro);temp=temp->pbro;}}}genely=next;//迭进下一代next.clear();//清空next}//计算最后结果cal:total=total;aveAge/=total;aveHeight/=total;if(family==0)family=1;aveMember=static_cast<float>(total)/ static_cast<float>(family);if(girl!=0)ratio=static_cast<float>(total-girl)/ static_cast<float>(girl);else ratio=0;//退出return;}bool FamilySystem::demandAve(){calculate();cout<<"2.查询家庭整体情况.\n";cout<<endl<<endl;cout<<setw(30)<<"家庭的整体情况如下:\t" <<endl<<endl<<endl;cout<<setw(30)<<"总人数:\t"<<total<< endl<<endl<<endl;cout<<setw(30)<<"平均年龄:\t"<<aveAge <<endl<<endl<<endl;cout<<setw(30)<<"平均身高:\t"<< aveHeight<<endl<<endl<<endl;cout<<setw(30)<<"家庭平均人数:\t"<< aveMember<<endl<<endl<<endl;cout<<setw(30)<<"男女比例:\t"<<ratio;if(ratio!=0)cout<<" : 1"<<endl;else cout<<endl;cout<<"\n\n按ESC键返回菜单";for(;;){if(_getch()==27)break;}return true;}bool FamilySystem::modifyMem(){cout<<"5.修改成员信息.\n\n";cout<<" 请输入姓名:";string na;try{istringstream sin(gets());sin>>na;}catch(int){goto rend;}Member*temp=seek(na);if(temp==nullptr){cout<<"\n\n 家谱中没有此人的信息!\n";goto end;}cout<<"\n 选择修改项:\n\n";cout<<" 1.姓名 2.出生地点 3.生日\n\n";cout<<" 4.性别 5.身高6.年龄\n\n";cout<<" 7.学历 8.工作\n\n";cout<<" 按ESC键退出修改\n\n";for(;;){int get=_getch();if(get==27)break;switch(get){case49:cout<<"\n 姓名原为:"<<temp->name;cout<<"\n 请输入更改:";cin>> temp->name;if(temp->pson==nullptr)break;else{string na=temp->name;temp=temp->pson;temp->father=na;while(temp->pbro!=nullptr){temp=temp->pbro;temp->father=na;}break;}case50:cout<<"\n 出生地点原为:"<< temp->birthPlace;cout<<"\n 请输入更改:";cin>> temp->birthDay;break;case51:cout<<"\n 生日原为:"<<temp->birthDay;cout<<"\n 请输入更改:";cin>> temp->birthDay;break;case52:cout<<"\n 性别原为:"<<temp->sex;cout<<"\n 请输入更改:";cin>>temp->sex;while(temp->sex!="male"&&temp->sex!= "female"&&temp->sex!="男"&&temp->sex!="女"){cout<<"输入错误,性别必须为male、female、男或女!\n请重新输入:";cin>>temp->sex;}break;case53:cout<<"\n 身高原为:"<<temp->height;cout<<"\n 请输入更改:";cin>> temp->height;break;case54:cout<<"\n 年龄原为:"<<temp->age;cout<<"\n 请输入更改:";cin>> temp->age;break;case55:cout<<"\n 学历原为:"<<temp->education;cout<<"\n 请输入更改:";cin>> temp->education;break;case56:cout<<"\n 工作原为:"<<temp->job;cout<<"\n 请输入更改:";cin>> temp->job;break;default:;}cout<<" 修改成功!";}end:cout<<"\n\n按ESC键返回菜单";for(;;){if(_getch()==27)break;}rend:return true;}void FamilySystem::display(Member*r,int n){ string blank="";for(int i=0;i!=n;++i)blank+=" ";cout<<blank<<r->name<<endl;if(r->pson!=nullptr)display(r->pson,n+6);if(r->pbro!=nullptr)display(r->pbro,n);return;}bool FamilySystem::showFamily(){cout<<"6.显示整个家谱.\n\n";if(root==nullptr)cout<<"\n\n 家谱为空!\n\n";else display(root,0);//escapecout<<"\n\n按ESC键返回菜单";for(;;){if(_getch()==27)break;}return true;}bool FamilySystem::saveFile(){ofstream outfile;//打开保存家庭信息的文件,并写入信息outfile.open("Wholes.txt",ios::out);if(!outfile){return false;}calculate();outfile<<total<<" "<<aveAge<<" "<<aveHeight<<" "<<aveMember<<" "<< ratio;outfile.close();//打开保存家庭成员信息的文件并写入信息outfile.open("Members.txt",ios::out);if(!outfile){return false;}vector<Member*>genely;//保存一代成员的指针genely.push_back(root);while(1){//输出这一代成员的信息for(auto p:genely){if(p!=nullptr){outfile<<p->name<<" "<<p->birthPlace<<" "<<p->birthDay<<" "<<p->sex<<" "<<p->height<<" "<<p->age<<" "<<p->job<<" "<<p->education<< " "<<p->father<<endl;}}//计算这一代成员的儿女的人数//若这一代都没有儿女,则退出int jubge=0;for(auto p:genely){if(p!=nullptr){if(p->pson!=nullptr)++jubge;}}if(jubge==0)break;//找到下一代的成员,即这一代的儿女vector<Member*>next;for(auto p:genely){Member*temp=p->pson;if(temp!=nullptr){next.push_back(temp);while(temp->pbro!=nullptr){next.push_back(temp->pbro);temp=temp->pbro;}}}genely=next;//迭进下一代next.clear();}return true;}主函数及欢迎界面的实现#include<time.h>#include"SystemClass.h"using std::cout;using std::endl;using std::flush;int main(){//显示系统欢迎界面void welcome();system("color 02");//将系统背景颜色置为黑色,前景暗绿色welcome();//画面停留3秒const time_t start=time(0);while(1){time_t current=time(0);if(current-start==3)break;}FamilySystem genealogy;//程序唯一的一个家谱对象//从文件中读取出家庭成员的信息,若读取不成功,则强制退出程序if(!genealogy.fileInit()){system("cls");//输出错误信息for(int i=0;i!=10;++i)cout<<"\n";string str=" ";cout<<str<<"读取文件时发生错误,程序将终止!\n\n"<<str<<"即将强制退出···"<<flush;//5秒后退出const time_t start=time(0);while(1){time_t current=time(0);if(current-start==5)exit(1);//异常退出}}//程序核心功能while(1){system("cls");//清屏system("color 02");int n=genealogy.menu();//显示菜单if(n==27)break;//按ESC键退出switch(n){case49:system("cls");genealogy.demandMem();break;//选择菜单项1case50:system("cls");genealogy.demandAve();break;//选择菜单项2 case51:system("cls");genealogy.addMem(); break;//选择菜单项2case52:system("cls");genealogy.deleteMem();break;//选择菜单项3 case53:system("cls");genealogy.modifyMem();break;//选择菜单项5 case54:system("cls");genealogy.showFamily();break;//选择菜单项6 default:;}}//保存信息到文件中,若发生错误,则当前所做修改不保存并强制退出程序if(!genealogy.saveFile()){system("cls");//输出错误信息for(int i=0;i!=12;++i)cout<<"\n";cout<<"保存文件时发生错误,所有工作将丢失!\n即将强制退出···"<<flush;//5秒后退出const time_t start=time(0);while(1){time_t current=time(0);if(current-start==5)exit(1);//异常退出}}//显示即将退出cout<<"\n\n 3秒后退出系统···";const time_t end=time(0);while(1){time_t current=time(0);if(current-end==3)break;}//正常退出return0;}void welcome(){//显示欢迎界面char*wel[]={"***********************************************************************\n","* *\n","* *\n","**\n","* ******** * * **** * ** ** *\n","* * * * * * * ** * * * *\n","* * * * * * ** * * * *\n","* ******* ******* * * ** * * *\n","* * * * * ** * * *\n","* * * * ** * * * *\n","* * * * ** *** ****** *** *\n","* *\n","* ******** ** ** ******** *************** * * *\n","* * * * * * * ** * * * * *\n","* * * * * ** * * * * *\n","* ******** * ******** ******** * * * *\n","* * * * ** * * * *\n","* * * * ** * * *\n","* ******** *** ******** ********** * * *\n","* *\n","* *\n","* *\n","***********************************************************************\n"};cout<<endl;for(const auto&i:wel)cout<<" "<<i;return;}。

数据结构家谱管理系统

数据结构家谱管理系统

数据结构家谱管理系统公司内部档案编码:[OPPTR-OPPT28-OPPTL98-OPPNN08]宁波大红鹰学院信息工程学院课程设计报告项目名称:家谱查询系统项目组长:白钰琦项目成员:徐程凯、徐海域、项鸿伟班级名称:10计科1班专业名称:计算机科学与技术完成时间: 2012年12月1日信息工程学院制目录一、案例描述...................................................1、总体描述................................................2、模块描述................................................二、设计思路...................................................三、程序设计...................................................1、数据结构描述............................................2、主函数及其流程图........................................3、源程序..................................................四、调试与分析.................................................1、主菜单..................................................2、显示家谱信息............................................3、显示家谱中第n代人所有信息..............................4、按姓名查找某人并相应输出................................5、按出生日期查找家谱成员信息..............................6、为家谱中成员添加孩子信息................................7、为家谱中成员添加妻子信息................................8、删除家谱中成员及其后代信息..............................9、修改家谱中成员信息......................................10、确定家谱中两个成员关系.................................11、按出生年月排序家谱.....................................五、设计总结...................................................1、完成情况................................................2、心得体会................................................一、案例描述1、总体描述家谱管理系统是查询家谱信息必不可少的一部分,利用家谱管理系统可以清楚的查询到家族成员的详细信息。

数据结构_家谱管理系统

数据结构_家谱管理系统

数据结构_家谱管理系统【数据结构_家谱管理系统】一、引言家谱是记录家族成员关系的重要文献,传统的家谱管理方式已经无法满足现代社会的需求。

为了更好地管理家族信息,提高家族成员之间的联系和交流,我们设计并开发了一款家谱管理系统。

本文将详细介绍该系统的设计和实现。

二、系统概述家谱管理系统是一个基于数据结构的软件应用,旨在帮助用户管理家族成员的信息,包括姓名、性别、出生日期、配偶、子女等。

系统提供了多种功能,包括添加、删除、修改、查询、统计等操作,方便用户对家谱信息进行维护和管理。

三、系统设计1. 数据结构选择在家谱管理系统中,我们选择了树这种数据结构来表示家族关系。

每个节点代表一个家庭成员,节点之间通过指针连接,形成家族的层级结构。

2. 数据模型设计家族成员的信息可以通过一个结构体来表示,包括姓名、性别、出生日期等字段。

每个节点除了包含成员信息外,还包含指向配偶的指针和指向子女的指针。

3. 系统功能设计家谱管理系统提供了以下功能:(1) 添加成员:用户可以输入成员信息,系统根据用户输入创建一个新的节点,并将其插入到适当的位置。

(2) 删除成员:用户可以指定要删除的成员,系统会删除该成员及其所有子孙节点。

(3) 修改成员信息:用户可以选择要修改的成员,然后输入新的信息进行更新。

(4) 查询成员信息:用户可以通过姓名、出生日期等条件查询成员信息。

(5) 统计家族人数:系统可以统计家族的总人数、男性人数、女性人数等信息。

四、系统实现1. 数据结构实现我们使用C语言来实现家谱管理系统。

通过定义一个节点结构体,使用指针来连接各个节点,实现家族关系的表示和管理。

2. 功能实现(1) 添加成员:根据用户输入的信息,创建一个新节点,并将其插入到适当的位置。

插入操作需要遍历树来找到合适的位置。

(2) 删除成员:根据用户指定的成员,删除该节点及其所有子孙节点。

删除操作需要递归地遍历树。

(3) 修改成员信息:根据用户选择的成员,更新其信息。

家谱管理系统数据结构(两篇)2024

家谱管理系统数据结构(两篇)2024

引言概述:家谱管理系统是一种用于管理和记录家族历史数据的工具。

它通过组织和存储家族成员的信息,包括个人资料、家庭关系和血统关系等数据,帮助家族成员更好地了解和维护其家族传统。

数据结构在家谱管理系统中起着重要的作用,它决定了系统的性能和效率。

在上一篇《家谱管理系统数据结构(一)》中我们介绍了家谱管理系统的基本数据结构,包括树和图。

在本文中,我们将深入研究家谱管理系统的数据结构,包括链表、数组、堆和哈希表,以及它们在家谱管理系统中的应用。

正文内容:一、链表1.链表的定义和基本操作,如插入、删除和查找节点等。

2.单向链表、双向链表以及循环链表的特点及适用场景。

3.在家谱管理系统中,链表可以用来存储家族成员的个人资料和家庭关系,形成一个有序的数据结构。

4.链表的优缺点分析,包括插入和删除速度快,但查找的效率低。

二、数组1.数组的定义和基本操作,包括插入、删除和查找元素等。

2.静态数组和动态数组的区别以及在家谱管理系统中的选择。

3.数组的存储方式和访问特点,以及对系统性能的影响。

4.数组的优缺点分析,包括查找速度快,但插入和删除的效率较低。

三、堆1.堆的定义和基本操作,如插入和删除堆顶元素等。

2.最大堆和最小堆的特点及适用场景。

3.在家谱管理系统中,堆可以用来维护家族成员之间的优先级关系,例如根据年龄进行排名。

4.堆的优缺点分析,包括快速找到最大(小)元素,但插入和删除的效率较低。

四、哈希表1.哈希表的定义和基本操作,如插入、删除和查找元素等。

2.哈希函数的设计原则和方法,以及冲突解决的技术。

3.在家谱管理系统中,哈希表可以用来快速查找家族成员的信息,例如根据姓名或者ID进行查找。

4.哈希表的优缺点分析,包括查找速度快,但对存储空间的利用率较低。

五、总结家谱管理系统作为一种用于管理和记录家族历史数据的工具,数据结构在其中起着重要的作用。

本文介绍了家谱管理系统中常用的数据结构,包括链表、数组、堆和哈希表,以及它们在系统中的应用。

数据结构家谱管理系统

数据结构家谱管理系统

////////////////////////////////////////////// /////////////////////////////////令狐采学//题目:家谱资料管理//要求:家谱用于记录某家族历代家族成员的情况与关系。

现编制一个家谱资料管理软件,//实现对一个家族所有的资料进行收集整理。

支持对家谱的增加,删除,更新,统计等。

/////////////////////////////////////////////////////// ////////////////////////#include <stdio.h>#include <stdlib.h>#include <string.h>int MATEFLAG=0;typedef struct TreeNode{int Num; //记录这个人拥有几个儿女char Name[20]; //记录这个人的姓名char Kind; //标示节点的种类有女G男Bstruct TreeNode * NextNode[20]; //记录这个人的儿女struct TreeNode * Parent; //记录这个节点的父节点}TreeNode;void CreatTree(TreeNode *Tree);void OutPutAll(TreeNode *Tree);TreeNode * SearchTree(TreeNode *Tree,char name[],int length); void MainMenue(TreeNode *Tree);void SubMenue1(TreeNode * Tree);void SubMenue2(TreeNode *Tree);void Change(TreeNode * Tree);void AddNew(TreeNode * Tree);void OutPutMessage(TreeNode * Tree,char name[],int length);//主函数void main(){TreeNode *Tree;Tree=(TreeNode *)malloc(sizeof(TreeNode));Tree->Parent =NULL;strcpy(Tree->Name,"0");MainMenue(Tree);}//添加新的成员void AddNew(TreeNode * Tree){SubMenue2(Tree);}//输出副菜单void SubMenue2(TreeNode *Tree){char c;int num;char name[20];TreeNode * NewNode;getchar();while(1){system("cls");printf("\t");printf("\n\n\t ---*****---请选择你的操作---****--- ");printf("\n\t---*---*---*---A:添加某个人的子女的信息---*---*---*---*---- ");printf("\n\t---*---*---*---B:添加某个人配偶的信息-*---*---*---*---*---- ");printf("\n\t---*---*---*---C:退出-*---*---*---*---*---*---*---*---*----\n\t");c=getchar();switch(c){case 'A':printf("\n\n\t请输入那个人的名字:\n\t");scanf("%s",name);Tree=SearchTree(Tree,name,20);if(Tree==NULL){printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n",name);break;}if(Tree->Parent==NULL&&Tree->NextNode[0]==NULL||Tree ->Parent!=NULL&&Tree->Name!=Tree->Parent->NextNode[0]->N ame){printf("\n\n\t%s至今还没有配偶请先添加配偶",Tree->Name);break;}if(Tree->Parent==NULL&&(Tree->Num>20||Tree->Num<0))Tree->Num=0;if(MATEFLAG==1)Tree=Tree->Parent;NewNode=(TreeNode *)malloc(sizeof(TreeNode));printf("\n\n\t请输入添加人员姓名:\n\t");scanf("%s",NewNode->Name);printf("\n\n\t请输入添加人员性别女G男B:\n\t");scanf("%1s",&NewNode->Kind);num=Tree->Num;NewNode->NextNode[0]=(TreeNode *)malloc(sizeof(TreeNode)); NewNode->NextNode[0]=NULL;NewNode->Num=0;NewNode->Parent=Tree;Tree->NextNode[num+1]=NewNode;Tree->Num=Tree->Num+1;printf("\n\n\t-------------子女的信息添加成功----------------"); break;case 'B':printf("\n\n\t请输入那个人的名字:\n\t");scanf("%s",name);Tree=SearchTree(Tree,name,20);if(Tree->Parent!=NULL&&strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0||Tree->NextNode[0]!=NULL) {printf("\n\n\t已经有了配偶");break;}if(Tree==NULL){printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n",name);break;}NewNode=(TreeNode *)malloc(sizeof(TreeNode));printf("\n\n\t请输入添加人员姓名:\n\t");scanf("%s",NewNode->Name);printf("\n\n\t请输入添加人员性别女G男B:\n\t");scanf("%1s",&NewNode->Kind);NewNode->Parent=Tree;Tree->NextNode[0]=NewNode;break;case 'C':printf("\n\n\t----------------本项服务到此结束-----------------");break;case '\n':break;default:printf("\n\n\t--------对不起!你的选择不在服务范围之内!--------- ");printf("\n\t-----------请您再次选择所需的服务项!------------- ");printf("\n\t------------------谢谢合作!----------------------\n\t");break;}if (c=='C'||c=='c') //??break;printf("\n\n\t--------------请按Enter键继续操作--------------");getchar();getchar();}}//修改某个人的信息void Change(TreeNode * Tree){char name[20];TreeNode * NewNode;printf("\n\t请输入你要修改的人的信息:\n\t");scanf("%s",name);NewNode=SearchTree(Tree,name,20);if(NewNode==NULL){printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n",name);return;}else{SubMenue1(NewNode);}}//输出副菜单void SubMenue1(TreeNode * Tree){char c;int flag,i;char name[20];char Parent[2][20];TreeNode * NewNode;getchar();while(1){system("cls");printf("\t");printf("\n\n\t ---*****---请选择你的操作---****--- ");printf("\n\t---*---*---*---A:修改个人的信息---*---*---*---*---*---*---- ");printf("\n\t---*---*---*---B:修改父母的信息---*---*---*---*---*---*---- ");printf("\n\t---*---*---*---C:修改兄弟姐妹的信息---*---*---*---*---*---- ");printf("\n\t---*---*---*---D:修改子女的信息---*---*---*---*---*---*---- ");printf("\n\t---*---*---*---E:修改配偶的信息---*---*---*---*---*---*---- ");printf("\n\t---*---*---*---F:退出-*---*---*---*---*---*---*---*---*----\n\t");c=getchar();switch(c){case 'A':printf("\n\n\t请输入修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t");scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Name,name);printf("\n\n\t是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续\n\t");scanf("%d",&flag);if (flag==1){if(Tree->Kind=='G'||Tree->Kind=='g')Tree->Kind='B';else Tree->Kind='G';}printf("\n\n\t个人信息修改成功");break;case 'B':if(Tree->Parent==NULL) //判断是不是头节点{printf("\n\t是这个家谱图里最顶端的人没有父母信息!",name);break;}if (MATEFLAG==1) //判断是不是入赘或加入此间的{if(Tree->Kind=='G'||Tree->Kind=='g'){printf("\n\n\t她是嫁入此间的所以父母信息不在家谱内包括");}else{printf("\n\n\t他是入赘此间的所以父母信息不在家谱内包括");}break;}if(Tree->Parent->Kind=='G'||Tree->Parent->Kind=='g'){strcpy(Parent[0],"母亲");strcpy(Parent[1],"父亲");}else{strcpy(Parent[0],"父亲");strcpy(Parent[1],"母亲");}printf("\n\n\t请输入%s要修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[0]);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Parent->Name,name);printf("\n\n\t请输入%s要修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[1]);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Parent->NextNode[0]->Name,name);printf("\n\n\t-------------父母的信息修改成功----------------");break;case 'C':NewNode=Tree->Parent;if(NewNode==NULL) //判断是不是头节点{printf("\n\t是这个家谱图里最顶端的人没有兄弟姐妹信息!",name);break;}if (MATEFLAG==1)//判断是不是入赘或加入此间的{if(Tree->Kind=='G'||Tree->Kind=='g'){printf("\n\n\t她是嫁入此间的所以兄弟姐妹信息不在家谱内包括");}else{printf("\n\n\t他是入赘此间的所以兄弟姐妹信息不在家谱内包括");}break;}if(NewNode->Num==1){printf("\n\n\t没有兄弟姐妹");break;}elsefor(i=1;i<=NewNode->Num;i++){if(NewNode->NextNode[i]->Name!=Tree->Name){printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",NewNode->NextNode[i]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(NewNode->NextNode[i]->Name,name);printf("\n\n\t是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续\n\t");scanf("%d",&flag);if (flag==1){if(NewNode->NextNode[i]->Kind=='G'||NewNode->NextNod e[i]->Kind=='g')NewNode->NextNode[i]->Kind='B';else NewNode->NextNode[i]->Kind='G';}}}printf("\n\n\t------------兄弟姐妹的信息修改成功-------------");break;case 'D':if(Tree->Num==0){printf("\n\n\t至今还没有子女");break;}if (Tree->Parent !=NULL)if (strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0) //如果他是入赘或者是嫁入的就需用配偶节点完成修改{Tree=Tree->Parent;}for(i=1;i<=Tree->Num;i++){printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Tree->NextNode[i]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->NextNode[i]->Name,name);printf("\n\n\t是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续\n\t");scanf("%d",&flag);if (flag==1){if(Tree->NextNode[i]->Kind=='G'||Tree->NextNode[i]->Kind= ='g')Tree->NextNode[i]->Kind='B';else Tree->NextNode[i]->Kind='G';}}printf("\n\n\t---------------子女的信息修改成功----------------");break;case 'E':if(Tree->Parent!=NULL){if(Tree->NextNode[0]==NULL&&strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)!=0){printf("\n\n\t至今还没有配偶");break;}if(strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0) {printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Tree->Parent->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->Parent->Name,name);}else{printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Tree->NextNode[0]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->NextNode[0]->Name,name);}}else{if(Tree->NextNode[0]==NULL)printf("\n\n\t至今还没有配偶");else{printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Tree->NextNode[0]->Name);scanf("%s",name);if(strcmp(name,"0")!=0)strcpy(Tree->NextNode[0]->Name,name);}}printf("\n\n\t---------------配偶的信息修改成功----------------");break;case 'F':printf("\n\n\t----------------本项服务到此结束-----------------");break;case '\n':break;default:printf("\n\n\t--------对不起!你的选择不在服务范围之printf("\n\t-----------请您再次选择所需的服务项!-------------");printf("\n\t------------------谢谢合作!----------------------\n\t");break;}if (c=='F'||c=='f')break;printf("\n\n\t--------------请按Enter键继续操作--------------");getchar();getchar();}}//输出主菜单void MainMenue(TreeNode *Tree){char c;char name[20];while(1){system("cls");printf("\t");printf("\n\n\t ---*****---请选择你的操作printf("\n\t--------------A:输入家谱信息建立多叉树----------------------");printf("\n\t--------------B:在家族中查找某人并输出他或(她)的相应信息----");printf("\n\t--------------C:添加新的成员--------------------------------");printf("\n\t--------------D:输出整个家谱信息----------------------------");printf("\n\t--------------E:修改某个人的信息----------------------------");printf("\n\t--------------F:退出整个程序--------------------------------\n\t");c=getchar();switch(c){case 'A':TreeNode * NewNode;NewNode=(TreeNode *)malloc(sizeof(TreeNode));printf("\n\t请输入姓名:\n\t");scanf("%s",Tree->Name);printf("\n\t请输入性别女G男B:\n\t");getchar();scanf("%c",&(Tree->Kind));Tree->Parent=NewNode;Tree->Parent=NULL;CreatTree(Tree);printf("\n\t--------------家谱图已经建立成功---------------\n\n");printf("\n\n\t--------------请按Enter键继续操作--------------");getchar();break;case 'B':if(strcmp(Tree->Name,"0")==0){printf("\n\t家谱图的多叉树尚未建立请先建立树\n");getchar();break;}printf("\n\t请输入你要查找的人的姓名:\n\t");scanf("%s",name);OutPutMessage(SearchTree(Tree,name,20),name,20);printf("\n\n\t-----*----*----*----*----*----*----*----*----*----*----\n\t");getchar();break;case 'C':if(strcmp(Tree->Name,"0")==0){printf("\n\t家谱图的多叉树尚未建立请先建立树\n"); getchar();break;}AddNew(Tree);getchar();break;case 'D':if(strcmp(Tree->Name,"0")==0){printf("\n\t家谱图的多叉树尚未建立请先建立树\n"); getchar();break;}printf("\n\n\t整个家谱的主要信息如下:"); OutPutAll(Tree);getchar();break;case 'E':if(strcmp(Tree->Name,"0")==0){printf("\n\t家谱图的多叉树尚未建立请先建立树\n");getchar();break;}Change(Tree);getchar();break;case 'F':printf("\n\n\t-----------------本次服务到此结束------------------");printf("\n\t------------------欢迎下次使用---------------------");printf("\n\t----------------------谢谢-------------------------\n\n");break;case '\n':break;default:printf("\n\n\t--------对不起!你的选择不在服务范围之内!-----------");printf("\n\t-----------请您再次选择所需的服务项!---------------");printf("\n\t------------------谢谢合作!------------------------\n\t");getchar();break;}if (c=='F'||c=='f')break;getchar();}}//创建树void CreatTree(TreeNode *Node){int i;TreeNode *NewNode;NewNode=(TreeNode *)malloc(sizeof(TreeNode));Node->NextNode[0]=NewNode;Node->NextNode[0]=NULL;//Node->Parent =NULL;printf("\n\t请输入%s的子女的数目:\n\t",Node->Name);scanf("%d",&(Node->Num));printf("\n\t请输入%s的配偶的姓名:\n\t",Node->Name);scanf("%s",NewNode->Name);if((Node->Num)==0&&strcmp(NewNode->Name,"0")==0)return ;if (Node->Kind=='G'||Node->Kind=='g')NewNode->Kind='B';elseNewNode->Kind='G';NewNode->Num=0;NewNode->NextNode[0]=NULL;Node->NextNode[0]=NewNode;Node->NextNode[0]->Parent=Node;for(i=1;i<=Node->Num;i++){NewNode=(TreeNode *)malloc(sizeof(TreeNode));printf("\n\t请输入%s的第%d子女的名字\n\t",Node->Name,i);scanf("%s",NewNode->Name);printf("\n\t请输入%s的第%d子女的性别女G男B:\n\t",Node->Name,i);getchar();scanf("%c",&NewNode->Kind);NewNode->Num=0;NewNode->Parent=Node;Node->NextNode[i]=NewNode;CreatTree(Node->NextNode[i]);}}//遍历并输出树中的内容void OutPutAll(TreeNode *Tree){int i, flag=0;printf("\n\t---****---***---***---***---***---***---***---***---***---");printf("\n\t姓名:%s 性别:",Tree->Name);if (Tree->Kind=='G'||Tree->Kind=='g'){flag=1;printf("女");}elseprintf("男");if (!(Tree->NextNode[0])){printf("\n\t至今没有配偶和子女\n");return;}if(flag==1)printf("\n\t丈夫姓名:%s",Tree->NextNode[0]->Name);elseprintf("\n\t妻子姓名:%s",Tree->NextNode[0]->Name);for(i=1;i<=Tree->Num;i++){printf("\n\t第%d个子女的姓名:%s 性别:",i,Tree->NextNode[i]->Name,Tree->NextNode[i]->Kind);if(Tree->NextNode[i]->Kind=='G'||Tree->NextNode[i]->Kind=='g') printf("女");elseprintf("男");}printf("\n\t");for(i=1;i<=Tree->Num;i++){OutPutAll(Tree->NextNode[i]);}}//在树中经过遍历查找某个人TreeNode * SearchTree(TreeNode *Tree,char name[],int length) {int i;TreeNode *NewNode;if(strcmp(Tree->Name,name)==0){if(length==0)MATEFLAG=1;elseMATEFLAG=0;return Tree;}if(Tree->NextNode[0]==NULL)return NULL;for(i=0;i<=Tree->Num;i++){if (i==0)NewNode=SearchTree(Tree->NextNode[i],name,0);elseNewNode=SearchTree(Tree->NextNode[i],name,20);if (NewNode!=NULL)return NewNode;return NULL;}//输出已经查找到的人的信息void OutPutMessage(TreeNode * Tree,char name[],int length){int flag=0,i;TreeNode *NewNode;printf("\n\n\t-----*----*----*----*----*----*----*----*----*----*----");if(Tree==NULL){printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n",name);return;}printf("\n\n\t您所要找的人已经找到信息如下所示:");printf("\n\n\t姓名:%s\t性别:",name);if (Tree->Kind=='G'||Tree->Kind=='g'){flag=1; //标记他(她)的性别printf("女");elseprintf("男");NewNode=Tree->Parent;if (MATEFLAG==1){if(flag==1){printf("\n\n\t她是嫁入此间的所以父母信息不在家谱内包括");printf("\n\t丈夫姓名:%s",NewNode->Name);}else{printf("\n\n\t他是入赘此间的所以父母信息不在家谱内包括");printf("\n\t妻子姓名:%s",NewNode->Name);}if ((NewNode->Num)>0) //判断他(她)是否有孩子{printf("\n\t的孩子的信息如下:"); //输出他(她)的孩子的信息for(i=1;i<=NewNode->Num;i++){printf("\n\t姓名:%s 性别:",NewNode->NextNode[i]->Name);if(NewNode->NextNode[i]->Kind=='G'||NewNode->Kind=='g') printf("女");elseprintf("男");}}return;}if(NewNode==NULL) //判断它是不是根节点如果是的话就没有父母兄弟信息printf("\n\t是这个家谱图里最顶端的人没有父母和兄弟姐妹信息!",name);else{if (NewNode->Kind=='G'||NewNode->Kind=='g') //判断父亲节点是父亲还是母亲{ //输出他(她)的父母亲的信息printf("\n\t母亲姓名:%s",NewNode->Name);printf("\n\t父亲姓名:%s",NewNode->NextNode[0]->Name);}else{printf("\n\t母亲姓名:%s",NewNode->NextNode[0]->Name);printf("\n\t父亲姓名:%s",NewNode->Name);}if (NewNode->Num>1) //判断他(她)是否有兄弟姐妹{ //输出他(她)的兄弟姐妹的信息printf("\n\t%s的兄弟姐妹信息如下:",name);for(i=1;i<=NewNode->Num;i++){if(NewNode->NextNode[i])printf("\n\t%s姓名:%s 性别:",NewNode->NextNode[i]->Name,NewNode->NextNode[i]->Na me);if (NewNode->NextNode[i]->Kind=='G'||Tree->Kind=='g')printf("女");elseprintf("男");}}elseprintf("\n\t%s没有兄弟姐妹!",Tree->Name);}if(Tree->NextNode[0]!=NULL) //判断他(她)是否有配偶{ //输出他(她)的配偶的信息if(flag==1)printf("\n\t丈夫姓名:%s",Tree->NextNode[0]->Name);elseprintf("\n\t妻子姓名:%s",Tree->NextNode[0]->Name);if (Tree->Num>0) //判断他(她)是否有孩子{printf("\n\t的孩子的信息如下:"); //输出他(她)的孩子的信息for(i=1;i<=Tree->Num;i++){printf("\n\t姓名:%s 性别:",Tree->NextNode[i]->Name);if (Tree->NextNode[i]->Kind=='G'||Tree->Kind=='g')printf("女");elseprintf("男");}}elseprintf("\n\t%s至今还没有孩子",name);}elseprintf("\n\t%s至今还没有配偶和孩子\n",Tree->Name); }。

数据结构_家谱管理系统

数据结构_家谱管理系统

数据结构_家谱管理系统家谱是记录一个家族的血缘关系和历史的重要文化遗产。

传统的家谱管理方式通常是以纸质形式存在,随着科技的发展,数字化的家谱管理系统逐渐兴起。

本篇文章将介绍一个基于数据结构的家谱管理系统的设计与实现。

一、需求分析家谱管理系统的主要功能包括:1. 家族成员的添加、删除和修改;2. 家族成员之间的关系建立与维护;3. 家族成员信息的查询与展示;4. 家族历史的记录与维护。

二、系统设计1. 数据结构选择在设计家谱管理系统时,我们可以选择不同的数据结构来存储家族成员的信息和关系。

常见的数据结构有链表、树和图等。

考虑到家族成员之间具有明确的父子关系,我们选择使用树这一数据结构来存储家族成员的信息。

2. 树的设计与实现家谱管理系统中的树可以采用多叉树的结构,每一个节点表示一个家族成员,节点之间的边表示父子关系。

每一个节点包含成员的基本信息,如姓名、性别、出生日期等。

此外,我们可以添加一些额外的字段来记录其他相关信息,如职业、教育背景等。

3. 树的操作家谱管理系统需要实现一些基本的树操作,包括:- 添加成员:根据家族成员的父子关系,在树中添加新的节点。

- 删除成员:删除指定节点及其子节点。

- 修改成员信息:更新指定节点的信息。

- 查询成员信息:根据成员的姓名或者其他关键字,在树中进行遍历查找。

- 显示家族树:以树的结构展示整个家族的成员关系。

三、系统实现家谱管理系统可以使用编程语言来实现,如Java、Python等。

以下是一个简单的Java代码示例:```javaclass FamilyMember {String name;String gender;String birthdate;// 其他成员信息字段List<FamilyMember> children;public FamilyMember(String name, String gender, String birthdate) { = name;this.gender = gender;this.birthdate = birthdate;this.children = new ArrayList<>();}public void addChild(FamilyMember child) {this.children.add(child);}// 其他成员操作方法}class FamilyTree {FamilyMember root;public FamilyTree(FamilyMember root) {this.root = root;}// 其他树操作方法}public class GenealogyManagementSystem {public static void main(String[] args) {// 创建家族成员FamilyMember grandpa = new FamilyMember("Grandpa", "Male", "1950-01-01");FamilyMember father = new FamilyMember("Father", "Male", "1975-01-01");FamilyMember mother = new FamilyMember("Mother", "Female", "1980-01-01");FamilyMember child1 = new FamilyMember("Child1", "Male", "2000-01-01");FamilyMember child2 = new FamilyMember("Child2", "Female", "2005-01-01");// 建立成员关系grandpa.addChild(father);grandpa.addChild(mother);father.addChild(child1);father.addChild(child2);// 创建家族树FamilyTree familyTree = new FamilyTree(grandpa);// 其他操作}}```四、系统扩展与优化1. 数据存储:可以将家族成员的信息存储在数据库中,以便实现更复杂的查询和统计功能。

数据结构_家谱管理系统

数据结构_家谱管理系统

引言概述:数据结构是计算机科学中非常重要的一部分,它涉及到如何组织、存储和管理数据以及实现各种基本操作的技术和方法。

家谱管理系统是一种将家族成员关系及相关信息进行组织和管理的系统。

本文将详细介绍数据结构在家谱管理系统中的应用,包括树、图、链表、哈希表和堆等数据结构的使用,以及各个数据结构之间的比较和选择。

正文内容:1.树的应用:1.1家族族谱的表示:家族族谱可以被看作是一棵树,其中每个节点表示一个家族成员,边表示家族成员之间的关系,如父子关系、兄弟关系等。

树的遍历算法可以用来查询家族成员的相关信息,比如查找某个成员的父亲、孩子、兄弟等。

1.2家族成员的添加和删除:通过树的插入和删除操作,可以方便地对家族成员进行增删操作。

例如,可以通过插入操作添加新的家族成员,通过删除操作删除家族成员。

1.3家族成员关系的查询:通过树的搜索算法,可以快速找到家族成员之间的关系。

例如,可以通过深度优先搜索算法找到某个成员的祖先、后代等。

2.图的应用:2.1家族成员的关系复杂性:家族成员之间的关系往往是复杂的,不仅涉及到父子关系,还可能涉及到配偶关系、外戚关系等。

图可以更好地表示这种复杂的关系。

2.2家族成员关系的可视化:通过图的可视化技术,可以直观地展示家族成员之间的关系,帮助用户更好地了解和使用家谱管理系统。

例如,可以用不同颜色和形状的节点表示不同的家族成员,用边表示他们之间的关系。

2.3关系网络的分析:通过图的分析算法,可以进一步研究和分析家族成员之间的关系。

例如,可以计算家族成员的亲密度、距离等,为家族成员提供更多的服务和帮助。

3.链表的应用:3.1成员信息的存储:家族成员的相关信息可以通过链表来存储,每个节点表示一个家族成员,节点中包含该成员的姓名、性别、出生日期等信息。

通过链表的插入和删除操作,可以方便地对成员信息进行增删操作。

3.2成员关系的维护:通过链表中的指针关系,可以方便地维护家族成员之间的关系。

家谱管理系统数据结构

家谱管理系统数据结构

家谱管理系统数据结构1.引言本章节介绍家谱管理系统的概述,包括背景、目的和范围。

2.功能需求本章节了家谱管理系统的功能需求,包括:2.1 家族成员管理:包括添加、删除、查询、修改家族成员的基本信息。

2.2 家族关系管理:包括建立、编辑、删除成员之间的家族关系。

2.3 家谱展示:提供家谱的可视化展示,方便用户浏览和查看。

2.4 数据统计分析:对家族成员的数据进行统计和分析,提供相关报表和图表。

3.数据结构设计本章节描述了家谱管理系统的数据结构设计,包括:3.1 家族成员的数据结构:包括成员编号、姓名、性别、出生日期、死亡日期等字段。

3.2 家族关系的数据结构:包括与该成员相关的父母、配偶、子女等字段。

3.3 家族树的数据结构:使用树状结构来表示家谱关系,包括树节点和指针等字段。

4.数据库设计本章节描述了家谱管理系统的数据库设计,包括:4.1 数据表设计:包括成员表、关系表、家谱树表等表的设计。

4.2 数据库关系图:展示了各个数据表之间的关系和连接方式。

5.界面设计本章节描述了家谱管理系统的界面设计,包括:5.1 登录界面:提供用户登录和注册功能。

5.2 主页界面:显示家族成员列表和家谱展示。

5.3 成员管理界面:提供添加、删除、查询、修改等功能。

5.4 关系管理界面:提供建立、编辑、删除家族关系的功能。

5.5 统计分析界面:展示家族成员数据的统计和分析结果。

6.系统性能本章节描述了家谱管理系统的性能要求,包括响应时间、并发用户数、数据处理能力等方面。

7.部署与维护本章节描述了家谱管理系统的部署和维护要求,包括硬件环境、软件环境、数据备份等方面。

8.文档本章节包括对本文档的修改记录和说明。

附件:本文档涉及的附件包括数据库设计图、界面原型图等。

法律名词及注释:1.法律名词1:注释说明。

2.法律名词2:注释说明。

数据结构家谱管理系统(二叉链表)

数据结构家谱管理系统(二叉链表)
8
char life; //是否健在 };
3、 二叉树结点结构体 struct Node { Information data; //个人信息 Node* child; //第一个孩子 Node* brother; //兄弟 };
4、 家谱类(二叉树结构、左孩子,右兄弟) class FamilyTree { private:
2、 更新模块 (1) 创建家谱、增加成员、删除成员、成员改名 (2) 主要函数: Node* Creat( ); //构造函数调用 void AddNewPeople(Node *root,string FatherName,string NAme); // 增加新的家族成员 int DeletePeople(Node *root,string FatherName,string Deletepeople); //删除家族成员
7
数据结构实现: 1、 生日结构体
struct BirthDay { int year; int month; int day; friend istream& operator>>(istream &is,BirthDay &b); friend ostream& operator<<(ostream &os,const BirthDay &b); };
2、 信息结构体(家族成员的基本信息) struct Information { string name; //姓名 string birthPlace; //出生地 BirthDay birthDay; //生日 string sex; //性别 string education; //学历 string job; //工作 string father; //父亲 string spouse; //配偶

数据结构课设-家谱管理系统

数据结构课设-家谱管理系统

数据结构课程设计——家谱管理系统一、问题描述问题名称:电子家谱问题内容:用树形的形式表示某家族的家谱,每个树结点表示一个家族成员,成员基本信息如下,具体属性自行确定。

1、姓名2、性别3、出生地4、配偶5、电话6、家庭住址7、职业8、简历9、其他系统实现功能:1、家谱信息1.1、输入1.2、修改1.3、删除2、查询2.1、某家谱成员的所有子孙的集合2.2、某家谱成员的所有祖先的集合2.3、某家谱成员的所有同辈成员的集合2.4、求某家谱成员的所有上一辈成员的集合2.5、给出两个家谱成员,确定他们的关系2.6、其他查询3、统计功能3.1、统计家谱成员的总人数3.2、统计从事某种职业的人数3.3、综合统计其他功能要求:1、用文件保存家谱信息2、图形方式显示家谱2二、系统总体设计(模块结构图)建立家谱读取文件保存家谱添加结点修改结点删除结点程序入口输出家谱统计基本查询关系查询祖先列表两人关系三、算法和数据结构设计数据结构的设计:使用兄弟孩子父亲表示法数据结构由如下的结构体组成1.1、日期的结构struct Date{int year; //年int month; //月int day; //日};1.2、成员信息的结构struct Info{char name[max_char_num];//姓名char birthplace[max_char_num];//出生地点Date birthdate;//结构date定义的出生日期Date deathdate;//结构date定义的死亡日期char sex[max_char_num];//性别char wife_or_husband[max_char_num];//配偶char phone[max_array_num];//电话char address[max_char_num];//家庭住址char resume[max_char_num];//简历//其他信息如下int height;//高度char occupation[max_char_num];//职业3char education[max_char_num];//受教育程度char top_headship[max_char_num];//最高职位char parentname[max_char_num];//父亲姓名,用于添加节点时用int Depth;//二叉树深度,输出二叉树时用};1.3、结点的结构typedef struct CSNode{Info data; //个人信息类型结构CSNode *firstchild,*nextsibling,*parent; //csnode的第一个孩子节点,下一个兄弟节点,双亲节点}*person;数据结构设计体会:使用树的按层遍历的方法找出某人的祖先的集合,但在从文件重建家谱的部分又碰到了困难,如何保存文件可是既节省空间又节省重建家谱的时间。

家谱管理系统数据结构大作业

家谱管理系统数据结构大作业

家谱管理系统数据结构大作业
家谱管理系统的数据结构可以采用树的数据结构来实现。

每一个人都可以看做是树的一个节点,节点之间的关系可以表示为父子关系。

具体实现时,可以定义一个Person类,其中包含以下属性:
- 姓名(name)
- 性别(gender)
- 出生日期(birth)
- 父亲(father)
- 母亲(mother)
- 子女列表(children)
然后,可以定义一个FamilyTree类,其中包含以下方法:
- 添加人员:根据提供的信息创建一个Person对象,并将其添加到家谱树中。

- 查找人员:根据姓名查找对应的Person对象。

- 添加父母关系:根据提供的信息,将两个Person对象之间建立父母关系。

- 添加子女关系:根据提供的信息,将一个Person对象添加到另一个Person对象的子女列表中。

- 删除人员:根据提供的姓名,删除对应的Person对象以及其在家谱树中的所有关系。

这样,通过FamilyTree类的方法,可以对家谱进行增加、删除、查询等操作。

家谱树的根节点可以作为整个家谱的入口。

家谱管理系统 -数据结构大作业

家谱管理系统 -数据结构大作业

家谱管理系统 -数据结构大作业家谱管理系统数据结构大作业在当今数字化的时代,信息管理系统在各个领域都发挥着重要作用。

家谱作为家族历史和传承的重要记录,也需要一个高效、便捷的管理系统来保存、整理和查询相关信息。

本次数据结构大作业,我将深入探讨家谱管理系统的设计与实现。

一、需求分析家谱管理系统的主要用户包括家族成员和对家族历史感兴趣的研究者。

系统需要满足以下基本需求:1、能够存储家族成员的详细信息,如姓名、出生日期、逝世日期、籍贯、职业等。

2、支持家族关系的建立和维护,如父子、母子、夫妻等关系。

3、提供便捷的查询功能,用户可以根据姓名、出生日期、关系等条件快速找到所需的家族成员信息。

4、支持家谱的可视化展示,以清晰呈现家族成员之间的关系结构。

5、具备数据的添加、删除和修改功能,以保证家谱信息的及时更新。

二、数据结构选择为了有效地存储和管理家谱数据,我们需要选择合适的数据结构。

考虑到家谱中家族成员之间的层次关系,树结构是一个理想的选择。

在这里,我们可以使用二叉树来表示家族关系。

每个节点代表一个家族成员,节点中存储成员的相关信息。

父节点与左子节点表示父子关系,父节点与右子节点表示父女关系。

另外,为了提高查询效率,我们还可以结合哈希表来存储家族成员的信息。

通过哈希函数将成员的关键信息(如姓名)映射到哈希表中的特定位置,从而实现快速的查找和访问。

三、系统功能模块设计1、数据录入模块提供友好的用户界面,方便用户输入家族成员的信息。

对输入的数据进行合法性检查,确保信息的准确性和完整性。

2、数据存储模块利用选择的数据结构(二叉树和哈希表)将家族成员的信息进行存储。

确保数据的安全存储,防止数据丢失或损坏。

3、查询模块支持多种查询条件,如按姓名、出生日期、关系等进行查询。

快速返回查询结果,并以清晰的方式展示给用户。

4、关系维护模块允许用户添加新的家族成员,并建立其与其他成员的关系。

支持修改和删除家族成员的信息及关系。

数据结构家谱管理系统范本

数据结构家谱管理系统范本

数据结构家谱管理系统范本在当今数字化的时代,管理和保存家族信息变得越来越重要。

一个高效的数据结构家谱管理系统能够帮助我们更好地记录家族成员的关系、个人信息以及家族的历史。

接下来,让我们详细探讨一下这样一个系统的范本。

首先,让我们来明确一下这个系统的主要目标和功能。

其核心目标是提供一个集中、准确且易于维护的平台,用于存储和查询家族信息。

主要功能应包括:家族成员信息的录入与编辑、成员之间关系的定义和展示、家族历史事件的记录、以及强大的查询和搜索功能。

在设计数据结构时,我们需要考虑如何有效地存储家族成员的信息。

可以创建一个“家族成员”表,其中包含诸如姓名、出生日期、出生地、逝世日期(若有)、照片(路径)等基本字段。

为了表示成员之间的关系,我们可以再创建一个“关系”表,记录每个成员与其亲属(如父母、配偶、子女等)的关联。

对于界面设计,应追求简洁明了、易于操作的风格。

首页可以展示家族树的概览,以直观的方式呈现家族成员之间的关系。

用户点击某个成员节点,能够查看该成员的详细信息,并可以进行编辑或添加新的信息。

在录入家族成员信息时,系统应提供友好的输入界面,并进行必要的数据验证,以确保输入信息的准确性和完整性。

例如,出生日期的格式应该符合规范,姓名不能为空等。

为了方便查询,系统应支持多种查询方式。

用户可以通过姓名、出生日期范围、籍贯等条件进行搜索,快速找到所需的家族成员信息。

在家谱管理系统中,数据的安全性和备份也是至关重要的。

用户的登录和操作权限应该得到严格控制,只有授权人员能够进行数据的修改和删除。

同时,定期对数据进行备份,以防止数据丢失。

此外,系统还可以提供一些扩展功能,比如生成家族报告,以图表或文档的形式展示家族的人口分布、年龄结构等信息;或者与社交媒体平台集成,方便与家族成员分享家族历史和最新动态。

在实际开发过程中,选择合适的编程语言和数据库管理系统也非常关键。

常见的编程语言如 Java、Python 等都能够胜任,而数据库可以选择 MySQL、SQL Server 等。

数据结构家谱管理系统报告书

数据结构家谱管理系统报告书

数据结构大作业说明文档一、题目的选择这次数据结构的大作业,我的选题是家谱管理系统的设计与实现。

由于平时疏于编程——针对我得个人实际——我把主要的目标定位在完成家谱管理系统得基本要求。

(基本要求大纲中有,就不浪费版面了)二、设计的思路接到这个题目,我的总体设计思路是先为程序搭建好一个结构框架,再跟据时间的宽裕程度和其它的要求逐步增强程序的性能。

关于IO的设计:考虑到题目要求家谱信息以树形的形式一次读入内存,而个人的各种资料现在虽然条目不多,但随着程序的升级,以后可能变得越来越大。

我把树形结构和个人信息记录的文档分为两个文件保存在外存中,一个文件串行化地记录家谱树的结构信息,保存少量个人信息作为识别标志;另一个文件保存完整的个人信息,所有的个人信息以线性记录的方式记录在其中。

当程序运行要读入家谱结构时,只读入保存少量记录的文件并建立起树形结构。

索引时,以树形中的少量信息为依据在另一个文件中找到全部的各人信息资料。

这样的好处主要有两点:1. 由于树形结构是串行化记录于外存,一个节点记录多次,信息大量冗余,如果树形节点中保留全部信息,必将造成大量的空间浪费;只保存作为索引的少量信息在树形结构中,节约了空间。

2. 由于结构的精简,在家谱初始化时读入内存需要的时间相应减少,节约了装载时间。

这样做存在的问题:每次执行修改,添加,删除,查询时都要直接访问外存来取得或写入数据。

内外存访问上的巨大时间差的存在,使得进行这些操作相对来说并不显得很高效。

关于树形的结构:在树形结构的选择上,根据实际中多子女的现象选择一般树,考虑到家谱中成员可能存在的不定成员数问题,抛弃了以数组为基础的一般树方案,决定用链表来实现。

树形结构的外存保存。

为了提高效率,树形结构在程序初始化时由外存文件一次读入内存,此后不管插入还是修改,删除都不再对外存的树结构保存文件进行操作,只在内存中处理,程序退出时对外存树结构文件进行一次更新。

也就是说,不管在程序运行中中对家谱结构进行多少种,多少次的操作,外存的树结构文件始终只会被程序访问两次。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/* 家谱管理系统任务:实现具有下列功能的家谱管理系统功能要求:1). 输入文件以存放最初家谱中各成员的信息,成员的信息中均应包含以下内容:姓名、出生日期、婚否、地址、健在否、死亡日期(若其已死亡),也可附加其它信息、但不是必需的。

2). 实现数据的存盘和读盘。

3). 以图形方式显示家谱。

4). 显示第n 代所有人的信息。

5). 按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。

6). 按照出生日期查询成员名单。

7). 输入两人姓名,确定其关系。

8). 某成员添加孩子。

9). 删除某成员(若其还有后代,则一并删除)。

10).修改某成员信息。

11).按出生日期对家谱中所有人排序。

12).打开一家谱时,提示当天生日的健在成员。

要求:建立至少30个成员的数据,以较为直观的方式显示结果,并提供文稿形式以便检查。

界面要求:有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。

存储结构:学生自己根据系统功能要求自己设计,但是要求相关数据要存储在数据文件中。

测试数据:要求使用1、全部合法数据;2、局部非法数据。

进行程序测试,以保证程序的稳定。

测试数据及测试结果请在上交的资料中写明;*/#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>#include"map.h"#define MAXN 100#define MAXMEM 100#define Elemtype char==============================//树typedef struct BiTNode{int mark;//标记int level;char name[50];//姓名char birthday[50];//生日char address[MAXN];//住址bool marriage;//婚否(true表示结婚,false表示没结婚)bool live;//建在(true表示活着,false表示过世)bool sex;//性别(true表示男,false表示女)char livemassage[50];//死亡日期(如果其已经死亡)Elemtype data;//struct BiTNode *lc,*rc;}BiTNode,*BiTree;//树的相关操作char nametemp[50];//姓名char birthdaytemp[50];//生日char addresstemp[MAXN];//住址bool marriagetemp;//婚否(true表示结婚,false表示没结婚)bool livetemp;//建在(true表示或者,false表示过世)bool sextemp;char livemassagetemp[MAXN];//死亡日期(如果其已经死亡)char ch;//额外使用int leveltemp;//人的代数int Nth;//显示第n代人时要用char searchdata[50];char searchname[50];int count;//计数int choice;//各种选择int use;BiTree temp;struct BiTNodeList{BiTree data;BiTNodeList *next;};BiTNodeList *List;//-----------void CreatBiTree(BiTree &T,FILE *in)//建立双链二叉树{fscanf(in,"%c",&ch);//printf("%c\n",ch);if(ch == '@'){T = NULL;fscanf(in,"%c",&ch);}else{T = (BiTree)malloc(sizeof(BiTNode));//fscanf(in,"%s%s%s%d%d",nametemp,birthdaytemp,addresstemp,&marriagetemp,&livet emp);fscanf(in,"%s",nametemp);strcpy(T->name,nametemp);fscanf(in,"%s",birthdaytemp);strcpy(T->birthday,birthdaytemp);fscanf(in,"%s",addresstemp);strcpy(T->address,addresstemp);fscanf(in,"%d%d%d%d",&marriagetemp,&livetemp,&leveltemp,&sextemp);T->marriage = marriagetemp;T->live = livetemp;T->level = leveltemp;T->sex = sextemp;//printf("%s %s %s %d %d\n",nametemp,birthdaytemp,addresstemp,marriagetemp,livetemp);if(!livetemp){fscanf(in,"%s",livemassagetemp);//printf("%s\n",livemassagetemp);}if(!T->live)strcpy(T->livemassage,livemassagetemp);fscanf(in,"%c",&ch);CreatBiTree(T->lc,in);CreatBiTree(T->rc,in);}}void PrintInfo(BiTree T){printf("%-10s出生于:%-10s%-10s",T->name,T->birthday,T->address);if(T->marriage)printf("\t已婚");if(!T->marriage)printf("\t未婚");printf("\t男");if(!T->sex)printf("\t女");if(T->live)printf("\t健在\n");if(!T->live)printf("\t去世于:%s\n",T->livemassage);}void PreOrderTraverse_recursion(BiTree T)//递归先序遍历(检查建树是否正确) {//printf("PreOrderTraverse_recursion\n");if(T){/*printf("%-10s出生于:%-10s%-10s",T->name,T->birthday,T->address);if(T->marriage)printf("\t已婚");if(!T->marriage)printf("\t未婚");if(T->sex)printf("\t男");printf("\t女");if(T->live)printf("\t健在\n");if(!T->live)printf("\t去世于:%s\n",T->livemassage);*/ PrintInfo(T);PreOrderTraverse_recursion(T->lc);PreOrderTraverse_recursion(T->rc);}}void ShowFamilyTree(BiTree T)//以图形的方式显示家谱{int i,lev;BiTree p;p = T;if(T){lev = T->level;for(i=0; i<lev; i++)printf("\t");printf("%-5s ",p->name);if(p->lc){p = T->lc;printf("★*★%5s%\n",p->name);if(p->rc){p = p->rc;ShowFamilyTree(p);}}elseprintf(" (未婚)\n");}if(T->rc){p = T->rc;ShowFamilyTree(p);}}void ShowNth(BiTree T)//显示第n代所有人的信息{if(T){if(T->level == Nth){PrintInfo(T);//printf("%-10s%-10s%-10s%5d%5d%5d\n",T->name,T->birthday,T->address,T->marriag e,T->live,T->sex);count++;}ShowNth(T->lc);ShowNth(T->rc);}}void SearchByName(BiTree T)//按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。

不能查询祖先信息{if(T){if(T->lc){if(T->lc->rc){temp = T->lc->rc;while(temp){if(strcmp(temp->name,searchname) == 0){count++;printf("\n此人的信息为: \n");PrintInfo(temp);//printf("%-10s%-10s%-10s%5d%5d%5d\n\n",temp->name,temp->birthday,temp->addres s,temp->marriage,temp->live,temp->sex);printf("此人父母的信息为: \n");PrintInfo(T);PrintInfo(T->lc);//printf("%-10s%-10s%-10s%5d%5d%5d\n",T->name,T->birthday,T->address,T->marriage,T->live,T->sex);//printf("%-10s%-10s%-10s%5d%5d%5d\n\n",T->lc->name,T->lc->birthday,T->lc->addres s,T->lc->marriage,T->lc->live,T->lc->sex);if(!temp->livemassage)printf("此人还没有妻室\n");else{printf("此人妻子的信息为: \n");PrintInfo(temp->lc);//printf("%-10s%-10s%-10s%5d%5d%5d\n\n",temp->lc->name,temp->lc->birthday,temp->lc->address,temp->lc->marriage,temp->lc->live,temp->lc->sex);if(temp->lc->rc){printf("此人孩子的信息为: \n");temp = temp->lc->rc;while(temp){PrintInfo(temp);//printf("%-10s%-10s%-10s%5d%5d%5d\n",temp->name,temp->birthday,temp->address,temp->marriage,temp->live,temp->sex);temp = temp->rc;}}}return;}elsetemp = temp->rc;}}}SearchByName(T->lc);SearchByName(T->rc);}}void SearchByBirthday(BiTree T)//按照出生日期查询成员名单{if(T){if(strcmp(T->birthday,searchdata) == 0){PrintInfo(T);//printf("%-10s%-10s%-10s%5d%5d%5d\n",T->name,T->birthday,T->address,T->marriag e,T->live,T->sex);count++;}SearchByBirthday(T->lc);SearchByBirthday(T->rc);}}void AddChild(BiTree &T)//某成员添加孩子{if(T){if(strcmp(T->name,searchname) == 0){count++;if(!T->lc){printf("该成员还没有结婚,不能添加孩子\n");return;}if(!T->sex){printf("不能为该家谱中的女性添加孩子\n");return;}else{temp = (BiTree)malloc(sizeof(BiTNode));printf("请输入添加孩子的姓名\n");scanf("%s",temp->name);printf("请输入添加孩子的出生年月(格式形如: 2010-1-1)\n");scanf("%s",temp->birthday);printf("请输入添加孩子的家庭住址\n");scanf("%s",temp->address);printf("请输入添加孩子的婚姻状况0/1 (0表示未婚,1表示已婚)\n");scanf("%d",&temp->marriage);printf("请输入添加孩子的在世情况0/1 (0表示去世,1表示在世)\n");scanf("%d",&temp->live);if(!temp->live){printf("请输入添加孩子的去世时间(格式形如: 2010-1-1)\n");scanf("%s",temp->livemassage);}printf("请输入添加孩子的性别0/1 (0表示女,1表示男)\n");scanf("%d",&temp->sex);temp->level = T->level+1;temp->rc = T->lc->rc;temp->lc = NULL;T->lc->rc = temp;printf("孩子添加成功\n");return;}}AddChild(T->lc);AddChild(T->rc);}}void AddWife(BiTree &T)//某成员添加妻子{if(T){if(strcmp(T->name,searchname) == 0){count++;if(T->lc){printf("该成员已有妻子,可以通过修改的方式替换该妻子\n");return;}else{temp = (BiTree)malloc(sizeof(BiTNode));printf("请输入添加妻子的姓名\n");scanf("%s",temp->name);printf("请输入添加妻子的出生年月(格式形如: 2010-1-1)\n");scanf("%s",temp->birthday);printf("请输入添加妻子的家庭住址\n");scanf("%s",temp->address);printf("请输入添加妻子的婚姻状况0/1 (0表示未婚,1表示已婚)\n");scanf("%d",&temp->marriage);printf("请输入添加妻子的在世情况(0表示去世,1表示在世)\n");scanf("%d",&temp->live);if(!temp->live){printf("请输入添加妻子的去世时间(格式形如: 2010-1-1)\n");scanf("%s",temp->livemassage);}printf("请输入添加妻子的性别0/1 (0表示女,1表示男)\n");scanf("%d",&temp->sex);temp->level = T->level;temp->lc = NULL;temp->rc = NULL;T->lc = temp;T->marriage = true;printf("妻子添加成功\n");return;}}AddWife(T->lc);AddWife(T->rc);}}void DeleteByName(BiTree &T)//删除某成员(若其还有后代,则一并删除){//printf("PreOrderTraverse_recursion\n");if(T){if(strcmp(T->name,searchname) == 0){count++;T = NULL;return;}//printf("%-10s%-10s%-10s%5d%5d%5d\n",T->name,T->birthday,T->address,T->marriag e,T->live,T->sex);DeleteByName(T->lc);DeleteByName(T->rc);}}void FixLevel(BiTree T){if(T){if(strcmp(T->name,searchname) == 0){count = T->level;}FixLevel(T->lc);FixLevel(T->rc);}}void FixRelation(BiTree T)//输入两人姓名,确定其关系{int levo,levt;char levone[50],levtwo[50];printf("请输入第一个人的姓名\n");scanf("%s",searchname);strcpy(levone,searchname);FixLevel(T);levo = count;if(levo == -1){printf("家谱无此人,请从新进入\n");return;}printf("请输入第二个人的姓名\n");scanf("%s",searchname);strcpy(levtwo,searchname);FixLevel(T);levt = count;if(levt == -1){printf("家谱无此人\n");return;}if(levo < levt)printf("%s 比%s 大%d 辈\n",levone,levtwo,levt-levo);else if(levo > levt)printf("%s 比%s 大%d 辈\n",levtwo,levone,levo-levt);else if(levo == levt)printf("%s 和%s 平辈\n",levone,levtwo);}void ShowAmend(){printf("1.修改姓名\n");printf("2.修改出生年月\n");printf("3.修改家庭住址\n");printf("4.修改婚姻状况\n");printf("5.修改在世情况\n");printf("6.修改性别\n");printf("7.返回上一级\n");printf("请输入选项(1-7): ");}void DoAmend(BiTree &T){while(1){system("cls");ShowAmend();scanf("%d",&choice);switch(choice){case 1:printf("请输入修改后的姓名: ");scanf("%s",T->name);break;case 2:printf("请输入修改后的出生年月: ");scanf("%s",T->birthday);break;case 3:printf("请输入修改后的住址: ");scanf("%s",T->address);break;case 4:printf("请输入修改后的婚姻状况: ");scanf("%d",&T->marriage);break;case 5:printf("请输入修改后的在世情况: ");scanf("%d",&T->live);if(!T->live){printf("请输入本人的过世时间: ");scanf("%s",T->livemassage);}break;case 6:printf("请输入修改后的性别(1表示男,0表示女): ");scanf("%d",&T->sex);case 7:return;default:printf("输入非法,请重新输入\n");break;}}}void AmendInfo(BiTree &T)//修改某成员信息。

相关文档
最新文档