家谱的设计与实现(树,查找)家谱的设计主要是实现对家庭成员信息的建立、查找、插入、修改、删除等功能。
可。
基本功能如下:(1)家谱中每个成员的信息包括:姓名、性别。
(2)家谱祖先数据的录入(树的根结点)。
(3)家庭成员的添加:即添加某人的儿女(包括姓名和性别),儿女的数目由控制台端给出,然后输入相应的儿女姓名和性别(此处所有儿女的姓名不能重名)。
(4)家庭成员的修改:可以修改某一成员的姓名。
(5)家庭成员的查询:查询某一成员在家族中的辈分(第几代),并能查询此成员的所有子女及这一辈的所有成员。
(6)家庭成员的删除:删除此成员时,若其有后代,将删除其所有后代成员。
#include <stdio.h>#include <malloc.h>#include <string>#include <stdlib.h>#define MAX 10typedef struct node{ //定义data存储结构char name[MAX]; //姓名char sex; //性别int generation;//代目typedef struct ft{ //创建结构体struct node l; //家谱中直系家属struct ft *brother;//用来指向兄弟struct ft *child;//用来指向孩子}ft;ft *root; //root是结构体ft的指针ft *search(ft *p,char ch[]) // 搜索指针函数{ft *q;if(p==NULL)return NULL;//没有家谱,头指针下为空if(strcmpi(p->,ch)==0)return p;//家谱不为空,头指针下有这个人if(p->brother){q=search(p->brother,ch);//在兄弟中找if(q)return q;//找到if(p->child){q=search(p->child,ch);//在孩子中找if(q!=NULL)return q;}return NULL;//没有找到}ft *parent(ft *p,ft *q,int *flag) //通过parent函数得到双亲结点。
用flag标志,-1为左孩子,1为右孩子{if(p==NULL)return NULL;//没有家谱,头指针下为空if(p->child==NULL){flag=0;return NULL;}else{if(p->brother==q){*flag=1;return p;}else{if(p->child==q){*flag=-1;return p;}else{if(p->brother!=NULL){parent(p->brother,q,*&flag);}if(p->child!=NULL){parent(p->child,q,*&flag);}}}}}int generation(ft *p,char ch[]) // 获得搜索到的成员的代目的返回值{ft *q;if(p==NULL) return NULL;if(strcmpi(p->,ch)==0) return p->l.generation;//家谱不为空,头指针下有这个人if(p->brother){q=search(p->brother,ch);//在兄弟中找if(q) return q->l.generation;//找到}if(p->child){q=search(p->child,ch);//在孩子中找if(q!=NULL) return q->l.generation;}return NULL;}void saves(ft *p,char b[],char c,int d)//建立家谱孩子结点创建结点并对l赋值保存{for(int i=0;i<MAX;i++)p->[i]=b[i];p->l.sex=c;p->l.generation=d;}void disp(ft *n) //搜索到数据的输出{ft *t=NULL;printf("此人姓名:%s 性别%c 为第%d代\n",n->,n->l.sex,n->l.generation);printf("\n");printf("此人的子女:"); //子女输出if(n->child==NULL){printf("此人无子女!");}else{if(n->child->brother==NULL){printf("姓名:%s 性别:%c\t",n->child->,n->child->l.sex);} else{printf("姓名:%s 性别:%c\t",n->child->,n->child->l.sex);t=n->child->brother;while(t!=NULL){printf("姓名:%s 性别:%c\t",t->,t->l.sex);t=t->brother;}}}printf("\n");printf("\n");printf("此人的同辈成员:"); //同辈输出if(n->brother==NULL){printf("此人无同辈成员!");}else{if(n->brother->brother==NULL){printf("姓名:%s 性别:%c\t",n->brother->,n->brother->l.sex);}else{printf("姓名:%s 性别:%c\t",n->brother->,n->brother->l.sex);t=n->brother->brother;while(t!=NULL){printf("姓名:%s 性别:%c\t",t->,t->l.sex);t=t->brother;}}}printf("\n");}void InitTree() //初始化{char b[MAX],c;int a;printf(" 请输入始祖的姓名性别:");free(root); //释放root (ft)空间root=(ft *)malloc(sizeof(ft)); // 创建一个ft结构体大小的空间然后强制转换为ft *类型的指针然后赋值给root // 这时root指向一个struct dictree结构体大小的新空间scanf("%s %c",&b,&c);a=1;//输入姓名,性别root->child=NULL; //清空左右孩子root->brother=NULL;saves(root,b,c,a);//存入结构printf("家谱重构成功!\n");}void Manu(){printf(" *********************************************\n");printf(" ***** 请选择对家谱的操作: *****\n");printf(" ***** 0.退出*****\n");printf(" ***** 1.添加*****\n");printf(" ***** 2.查找*****\n");printf(" ***** 3.修改*****\n");printf(" ***** 4.删除*****\n");printf(" ***** 5.重构*****\n");printf(" *********************************************\n"); }void Add() //添加{ft *n,*m,*t=NULL;char b[MAX],c,d[MAX];int i;printf("请输入要添加子女的上一辈的姓名:\n");//判断是否有重名scanf("%s",&d);n=search(root,d);int a=generation(root,d);while(n==NULL){printf("此人不在家谱内,请重新输入姓名:\n");scanf("%s",&d);n=search(root,d);}//孩子信息添加if(n->child==NULL){printf("孩子姓名与性别输入:\n");scanf("%s %c",&b,&c);a++;m=search(root,b);if(m!=NULL){printf("出现重名,添加失败!\n");}else{n->child=(ft *)malloc(sizeof(ft));n->child->brother=NULL;n->child->child=NULL;saves(n->child,b,c,a);printf("添加成功!\n");}}else{n=n->child;while(n->brother!=NULL)n=n->brother;printf("孩子姓名与性别输入:\n");scanf("%s %c",&b,&c);a++;m=search(root,b);if(m!=NULL) printf("出现重名,添加失败!\n");else{t=(ft *)malloc(sizeof(ft));saves(t,b,c,a);t->brother=NULL;t->child=NULL;n->brother=t;printf("添加成功!\n");}}}void Search() //查询{ft *n;char d[MAX];printf("输入姓名,查找相关信息:\n");scanf("%s",&d);n=search(root,d);while(n==NULL){printf("此人不存在,请再次输入:\n");scanf("%s",&d);n=search(root,d);}disp(n);}void Change() //修改{char a[MAX],r[MAX],c;ft *n;printf("请输入要修改人的姓名:");scanf("%s",&a);n=search(root,a);while(n==NULL){printf("此人不存在,请重新输入姓名:\n");scanf("%s",&a);n=search(root,a);}printf("此人存在,请输入新信息:");scanf("%s %c",&r,&c);for(int i=0;i<MAX;i++)n->[i]=r[i];n->l.sex=c;printf("修改成功!\n");void Del() //删除{ft *n,*m;int flag;char d[MAX],a[MAX];printf("请输入要删除人的姓名:");scanf("%s",a);n=search(root,a);while(n==NULL){printf("此人不存在,请重新输入姓名:\n");scanf("%s",&a);n=search(root,a);}printf("\n");printf("此人已找到!\n");printf("\n");m=parent(root,n,&flag);if(flag>0){ m->brother=n->brother;printf("删除成功!\n");} else if(flag<0){ m->child=n->brother; printf("删除成功!\n");} }int main(){InitTree();for(;;){system("pause");system("cls");Manu();int choice;scanf("%d",&choice);switch(choice){case 0:exit(0); break;//退出case 1:Add(); break;//添加case 2:Search(); break;//查找case 3:Change(); break;//修改case 4:Del(); break;//删除case 5:InitTree(); break;//初始化}}return 0;}。