二叉树的应用:利用C语言编写简单的家谱管理系统
2017-07-11 23:07
1226 查看
/*采用树型结构实现如下系统功能: 1)输入文件以存放最初家谱中各成员的信息。 成员的信息中均应包含以下内容: 姓名、出生日期、婚否、地址、健在否、死亡日期(若其已死亡)也可附加其它信息、但不是必需的。 2)实现数据的存盘和读盘。 3)以图形方式显示家谱。 4)显示第n代所有人的信息。 5)按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。 6)按照出生日期查询成员名单。 7)输入两人姓名,确定其关系。 8)某成员添加孩子。 9)删除某成员(若其还有后代,则一并删除)。 10)修改某成员信息。 11)按出生日期对家谱中所有人排序。 12)打开一家谱时,提示当天生日的健在成员。 测试要求: 1)建立至少10个成员的数据,以较为直观的方式显示结果,并提供文稿形式以便检查。 2)对界面的要求是:有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 注:有关文件的操作我做的不好,另外图形化界面做的不太好,增加孩子的时候空格不好控制,这是CodeBlocks的硬伤 */ #include<iostream> #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> #include<fstream> #define MAXSIZE 100 using namespace std; typedef struct Infomation{ char name[20]; char birth[20]; int wedding; char add[20]; int health; char death_date[20]; }Info; typedef struct bnode{ Info person; struct bnode *lchild,*rchild; }BNode,*BiTree; typedef struct{ //循环队列的定义 BiTree queue[MAXSIZE]; int front,rear; }Queue; void InitQ(Queue &Q) //初始化 { Q.front=Q.rear=0; } void EnQueue(Queue &Q,BiTree e) //入队 { Q.rear=(Q.rear+1)%MAXSIZE; Q.queue[Q.rear]=e; } void DeQueue(Queue &Q,BiTree &e) //出队 { Q.front=(Q.front+1)%MAXSIZE; e=Q.queue[Q.front]; } int QEmpty(Queue Q) //判队空 { return Q.front==Q.rear; } int QFull(Queue Q) //判队满 { if((Q.rear+1)%MAXSIZE==Q.front) return 1; return 0; } void new_left(BiTree p,Info info) { BiTree q=(BiTree)malloc(sizeof(BNode)); q->person=info; q->lchild=q->rchild=NULL; p->lchild=q; } void new_right(BiTree p,Info info) { BiTree q=(BiTree)malloc(sizeof(BNode)); q->person=info; q->lchild=q->rchild=NULL; p->rchild=q; } BiTree create() { struct Infomation human[11]={{"John","19000511",1,"nefu",0,"19800401"}, {" 4000 Jack","19200721",1,"hit",0,"19900402"}, {"Mary","19230526",1,"mit",0,"19981221"}, {"Tom","19440501",1,"bit",0,"20080419"}, {"Lily","19480711",0,"nefu",0,"20010201"}, {"Ben","19480505",1,"hit",0,"20070401"}, {"June","19490541",1,"baidu",0,"20141111"}, {"Mark","19600430",0,"nefu",1,"I am alive!"}, {"Lucy","19760301",0,"jingdong",1,"I am alive!"}, {"Steven","19770519",1,"alibaba",1,"I am alive!"}, {"Ann","20000101",0,"nefu",1,"I am alive!"}}; BiTree bt; bt=(BiTree)malloc(sizeof(BNode)); bt->person=human[0]; bt->lchild=bt->rchild=NULL; new_left(bt,human[1]); new_right(bt,human[2]); new_left(bt->lchild,human[3]); new_right(bt->lchild,human[4]); new_left(bt->rchild,human[5]); new_right(bt->rchild,human[6]); new_left(bt->lchild->lchild,human[7]); new_right(bt->lchild->lchild,human[8]); new_left(bt->rchild->rchild,human[9]); new_right(bt->rchild->rchild->lchild,human[10]); return bt; } void output(BiTree p)//输出某结点的信息 { printf("%-7s%-7s%7d%12s%10d%17s\n",p->person.name,p->person.birth,p->person.wedding,p->person.add,p->person.health,p->person.death_date); } void level(BiTree t) //层次遍历家谱图 { BiTree q[20],p; int front,rear; front=rear=0; printf("姓名 出生日期 婚否 地址 健在否 死亡日期\n"); if(t) { rear++; q[rear]=t; while(front!=rear) { front=(front+1)%20; p=q[front]; output(p); if((rear+1)%20!=front&&p->lchild!=NULL) { rear=(rear+1)%20; q[rear]=p->lchild; } if((rear+1)%20!=front&&p->rchild!=NULL) { rear=(rear+1)%20; q[rear]=p->rchild; } } } } void show_which_level(BiTree p,int n) //层次遍历家谱的第n层 { static int depth=0; depth++; if(p) { if(depth==n) { output(p); } show_which_level(p->lchild,n); show_which_level(p->rchild,n); } depth--; } BiTree Parent(BiTree bt,BiTree p) //找到结点p的双亲并返回 { BiTree l_result,r_result; if (!bt||bt==p) return NULL; if (bt->lchild==p||bt->rchild==p) return bt; else { l_result=Parent(bt->lchild,p); r_result=Parent(bt->rchild,p); return l_result?l_result:(r_result?r_result:NULL); } } BiTree search_name(BiTree bt,char na[]) //通过名字找到结点并返回 { BiTree l_result,r_result; if(!bt) return NULL; if(strcmp(bt->person.name,na)==0) return bt; else { l_result=search_name(bt->lchild,na); r_result=search_name(bt->rchild,na); return l_result?l_result:(r_result?r_result:NULL); } } void search_child(BiTree p,BiTree child[]) //找到结点p的孩子存到指针数组child[]中 { child[0]=child[1]=NULL; if(p->lchild!=NULL) child[0]=p->lchild; if(p->rchild!=NULL) child[1]=p->rchild; } void search_3dai(BiTree bt) //显示三代的信息 { char na[20]; BiTree parent,node,child[2]; printf("请输入你想查找的那个人的姓名:\n"); scanf("%s",na); node=search_name(bt,na); parent=Parent(bt,node); search_child(node,child); printf("你查找的这个人的信息为:\n\n"); printf("姓名 出生日期 婚否 地址 健在否 死亡日期\n"); output(node); printf("他的父亲结点的信息为:\n"); output(parent); if(child[0]!=NULL) { printf("他的左孩子的信息为:\n"); output(child[0]); } if(child[1]!=NULL) { printf("他的右孩子的信息为:\n"); output(child[1]); } } BiTree search_birth(BiTree bt,char bir[]) //通过生日找到结点并返回 { BiTree l_result,r_result; if(!bt) return NULL; if(strcmp(bt->person.birth,bir)==0) return bt; else { l_result=search_birth(bt->lchild,bir); r_result=search_birth(bt->rchild,bir); return l_result?l_result:(r_result?r_result:NULL); } } void search_birthday(BiTree bt) //输出生日信息 { BiTree p; char bir[20]; printf("请输入你想查找的那个人的生日:\n"); scanf("%s",bir); p=search_birth(bt,bir); printf("你想查找的那个人的信息为:\n"); printf("姓名 出生日期 婚否 地址 健在否 死亡日期\n"); output(p); } int is_the_same_father(BiTree bt,BiTree p,BiTree q) //判断结点p和q是否是同一个爸爸,如果是返回1,否则返回0 { BiTree f1,f2; f1=Parent(bt,p); f2=Parent(bt,q); if(f1==f2) return 1; else return 0; } void ralationship(BiTree bt) //判断两个人的关系 { char name1[20],name2[20]; BiTree s1,s2,f1,f2; printf("请输入第一个人的姓名:\n"); scanf("%s",name1); printf("请输入第二个人的姓名:\n"); scanf("%s",name2); s1=search_name(bt,name1); s2=search_name(bt,name2); f1=Parent(bt,s1); f2=Parent(bt,s2); if(is_the_same_father(bt,s1,s2)==1) printf("他们是亲兄弟关系\n"); else if(is_the_same_father(bt,f1,f2)==1) printf("他们是堂兄弟关系\n"); else if(s1->lchild==s2) printf("%s是%s的左孩子\n",s2->person.name,s1->person.name); else if(s1->rchild==s2) printf("%s是%s右孩子\n",s2->person.name,s1->person.name); else if(s2->lchild==s1) printf("%s是%s的左孩子\n",s1->person.name,s2->person.name); else if(s2->rchild==s1) printf("%s是%s的右孩子\n",s1->person.name,s2->person.name); else printf("这两个人关系太远啦!\n"); } void add(BiTree &bt) //让一个结点拥有孩子 { char na[20]; int i; BiTree p; Info new_child; printf("请输入你想让其拥有孩子的那个人的名字:\n"); scanf("%s",na); p=search_name(bt,na); printf("你是想让他有左孩子呀,还是右孩子呀?左孩子请按1,右孩子请按0:\n"); scanf("%d",&i); switch(i) { case 1: if(p->lchild!=NULL) { printf("添加失败!人家已经有左孩子了!\n"); break; } else { printf("请输入新孩子的姓名:\n"); scanf("%s",new_child.name); printf("请输入新孩子的出生日期:\n"); scanf("%s",new_child.birth); printf("新孩子结婚了吗,结婚请按1,没有结婚请按0:\n"); scanf("%d",&new_child.wedding); printf("请输入新孩子的地址:\n"); scanf("%s",new_child.add); printf("新孩子健在吗?健在请按1,死了请按0:\n");\ scanf("%d",&new_child.health); printf("如果新孩子死了,请输入死亡日期,不然请输入-1:\n"); scanf("%s",new_child.death_date); if(strcmp(new_child.death_date,"-1")==0) strcpy(new_child.death_date,"I am alive!"); new_left(p,new_child); } break; case 2: if(p->rchild!=NULL) { printf("添加失败!人家已经有右孩子了!\n"); break; } else { printf("请输入新孩子的姓名:\n"); scanf("%s",new_child.name); printf("请输入新孩子的出生日期:\n"); scanf("%s",new_child.birth); printf("新孩子结婚了吗,结婚请按1,没有结婚请按0:\n"); scanf("%d",&new_child.wedding); printf("请输入新孩子的地址:\n"); scanf("%s",new_child.add); printf("新孩子健在吗?健在请按1,死了请按0:\n");\ scanf("%d",&new_child.health); printf("如果新孩子死了,请输入死亡日期,不然请输入-1:\n"); printf("%s",new_child.death_date); if(strcmp(new_child.death_date,"-1")==0) strcpy(new_child.death_date,"I am alive!"); new_right(p,new_child); } break; default: printf("你的输入有误!\n"); break; } } void delete_name(BiTree &bt) //删除一个结点和他的孩子们孙子们 { char na[20]; BiTree p,f; printf("请输入你想删除的那个人的姓名,删除之后他的孩子孙子们也将一并删除!\n"); scanf("%s",na); p=search_name(bt,na); f=Parent(bt,p); if(f!=NULL) { if(f->lchild==p) { f->lchild=NULL; free(p); } if(f->rchild==p) { f->rchild=NULL; free(p); } } else { bt=NULL; } } void show_family(BiTree bt) //显示家谱 { Queue Q1,Q2; int i=0; BiTree e; InitQ(Q1); InitQ(Q2); if(bt!=NULL) { EnQueue(Q1,bt); while(!QEmpty(Q1)) { while(!QEmpty(Q1)) { DeQueue(Q1,e); EnQueue(Q2,e); } i++; if(i==1) printf("第%d代: ",i); if(i==2) printf("第%d代: ",i); if(i==3) printf("第%d代: ",i); if(i==4) printf("第%d代:",i); if(i==5) printf("第%d代: ",i); while(!QEmpty(Q2)) { DeQueue(Q2,e); printf("%s ",e->person.name); if(!QFull(Q1)&&e->lchild!=NULL) EnQueue(Q1,e->lchild); if(!QFull(Q1)&&e->rchild!=NULL) EnQueue(Q1,e->rchild); } puts(""); } } } void update(BiTree bt) { char na[20]; BiTree p; printf("请输入你想修改孩子的姓名:\n"); scanf("%s",na); p=search_name(bt,na); printf("请输入修改过后的姓名:\n"); scanf("%s",p->person.name); printf("请输入修改过后的出生日期:\n"); scanf("%s",p->person.birth); printf("请问修改过后的那个人结婚了吗?结婚请输入1,没结婚请输入0:\n"); scanf("%d",&p->person.wedding); printf("请输入修改过后的住址:\n"); scanf("%s",p->person.add); printf("请问修改过后的那个人健在吗?健在请输入1,死了请输入0:\n"); scanf("%d",&p->person.health); printf("如果修改过后那个人死了,请输入死亡日期,否则请输入-1:\n"); scanf("%s",p->person.death_date); if(strcmp(p->person.death_date,"-1")==0) strcpy(p->person.death_date,"I am alive!"); } void transport(BiTree bt,char bir[][20],int &x) //把家谱中所有人的生日传参给二维数组bir[][] { if(bt) { strcpy(bir[x++],bt->person.birth); transport(bt->lchild,bir,x); transport(bt->rchild,bir,x); } } void sort_birth(BiTree bt,char bir[][20],int n)//将二维数组升序排序并输出 { char t[20]; int i,j; BiTree p; for(i=0;i<n-1;i++) for(j=i+1;j<n;j++) if(strcmp(bir[i],bir[j])>0) { strcpy(t,bir[i]); strcpy(bir[i],bir[j]); strcpy(bir[j],t); } for(i=0;i<n;i++) { p=search_birth(bt,bir[i]); output(p); } puts(""); } void menu() { printf("\n1.从文件读取家族信息并显示\n"); printf("2.保存家族信息并存盘\n"); printf("3.显示家谱图\n"); printf("4.层次遍历家谱图\n"); printf("5.显示第n代人的所有信息\n"); printf("6.按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)\n"); printf("7.按照出生日期查询成员名单\n"); printf("8.输入两人姓名,确定其关系\n"); printf("9.给某成员添加孩子\n"); printf("10.删除某成员(若其还有后代,则一并删除)\n"); printf("11.修改某成员信息\n"); printf("12.按出生日期对家谱中所有人排序\n"); printf("13.退出系统\n"); } int main() { BiTree bt; int wedding1,health1,i,j,n,x=0; char bir[20][20],name1[20],birth1[20],add1[20],death_date1[20]; printf("欢迎来到家谱管理系统!\n"); bt=create(); LL1:menu(); printf("\n请输入你的选择:\n"); scanf("%d",&i); switch(i) { case 1: { ifstream fin("zupu.txt"); printf("从文件里读出来的信息是:\n"); printf("姓名 出生日期 婚否 地址 健在否 死亡日期\n"); for(j=0;j<11;j++) { fin>>name1>>birth1>>wedding1>>add1>>health1>>death_date1; printf("%-7s%-7s%7d%12s%10d%17s\n",name1,birth1,wedding1,add1,health1,death_date1); } fin.close(); goto LL1; break; } case 2: { ofstream fout("zupu.txt"); struct Infomation man[11]={{"John","19000511",1,"nefu",0,"19800401"}, {"Jack","19200721",1,"hit",0,"19900402"}, {"Mary","19230526",1,"mit",0,"19981221"}, {"Tom","19440501",1,"bit",0,"20080419"}, {"Lily","19480711",0,"nefu",0,"20010201"}, {"Ben","19480505",1,"hit",0,"20070401"}, {"June","19490541",1,"baidu",0,"20141111"}, {"Mark","19600430",0,"nefu",1,"I_am_alive!"}, {"Lucy","19760301",0,"jingdong",1,"I_am_alive!"}, {"Steven","19770519",1,"alibaba",1,"I_am_alive!"}, {"Ann","20000101",0,"nefu",1,"I_am_alive!"}}; for(j=0;j<11;j++) fout<<man[j].name<<" "<<man[j].birth<<" "<<man[j].wedding<<" "<<man[j].add<<" "<<man[j].health<<" "<<man[j].death_date<<endl; fout.close(); printf("保存成功!\n"); goto LL1; break; } case 3:show_family(bt); goto LL1; break; case 4: level(bt); goto LL1; break; case 5: printf("你想查找第几代的信息呀?\n"); scanf("%d",&n); show_which_level(bt,n); goto LL1; break; case 6: search_3dai(bt); goto LL1; break; case 7: search_birthday(bt); goto LL1; break; case 8: ralationship(bt); goto LL1; break; case 9: add(bt); show_family(bt); level(bt); goto LL1; break; case 10: delete_name(bt); show_family(bt); level(bt); goto LL1; break; case aa57 11: update(bt); show_family(bt); level(bt); goto LL1; break; case 12: transport(bt,bir,x); sort_birth(bt,bir,x); goto LL1; break; case 13: printf("谢谢你的使用,再见啦!\n"); exit(0); default: printf("你的输入有误,请重新输入!\n"); goto LL1; break; } }
相关文章推荐
- C语言编写的简单的学生成绩管理系统
- 简单的学籍管理系统(C语言编写)
- C语言编写的简单的电话本管理系统
- C语言编写的简单的学生成绩管理系统
- c语言编写的简单信息管理系统
- 单链表的应用:用C语言实现简单的员工管理系统(新建、增、删、改、查、排序)
- 《C语言编写 学生成绩管理系统》
- c语言题目----请编写一个小型学生管理系统
- 用c++编写简单的图书管理系统怎么弄
- 用C语言编写的商品库存管理系统
- 利用Smarty编写新闻管理后台系统
- 学生管理系统(线性链表的简单应用)
- 学生信息管理系统简单模拟(C语言实现)
- 利用 Enterprise Library 改善你的应用系统2——应用系统的配置管理
- 编写一个简单的用户管理系统(工厂代理模式)
- 用c语言编写学生成绩管理系统
- 教务处管理系统(数据结构的简单应用)
- C#编写简单的系统服务管理器
- c语言实现的简单的员工工资管理系统
- 利用XML配置实现增删改查的.net快速开发架构 简单的构建信息管理系统架构