#include<stdio.h>
#include<string.h>
#include<malloc.h>
struct node;
node *creat();//建立祖先
int add_child(node *head);//添加家庭成员
int add_brother(node *head);//添加兄弟成员
void print(node *head,char *x);//输出指定家庭成员
int beifen(node *p,char *x);//确定成员辈分
void print1(node *head);//先序遍历 输出家庭成员
void chengyuan(node *head,int s);//输出相应辈分成员
node *shanchu(node *head,char *s);//删除成员
struct node//结构体变量
{
char data[20];//家庭成员
int n;//辈分
node *lchild,*rchild;//左孩子是孩子,右孩子是兄弟
};
node *creat()//建立祖先
{
node *head;
head=(node *)malloc(sizeof(node));//分配存储空间
char s[20];
printf("输入祖先名字:");
scanf("%s",&s);
strcpy(head->data,s);// 赋值
head->n=1;//分配辈分
printf("祖先载入成功!\n");
return head;//返回祖先节点(根节点)
}
int add_child(node *head)//添加家庭成员 非递归法
{
char y[20],x[20];
node *p,*q;//定义新变量
q=head;
printf("输入加入父节点姓名:");
scanf("%s",&x);//输入父节点
p=(node *)malloc(sizeof(node));//动态分配存储空间
printf("输入要添加的孩子:");
scanf("%s",&y);//输入孩子信息
strcpy(p->data,y);//赋值到节点
p->lchild=NULL;//新节点左孩子为空
p->rchild=NULL;//新节点右孩子为空
while(q!=NULL)//循环左孩子查找
{
if(strcmp(x,q->data)==0)//比较
{
if(q->lchild==NULL)//如果此结点没有孩子则添加到左孩子
{
p->n=q->n+1;//孩子为父节点的辈分加1
q->lchild=p;//新节点为父节点的左孩子节点
return 1;
}
else//如果此结点有孩子,则找到孩子,再找到最后一个兄弟,并添加到后面
{
q=q->lchild;
while(q->rchild!=NULL)//循环到最后一个
{
q=q->rchild;//兄弟指向右孩子
}
p->n=q->n;//兄弟辈分相同
q->rchild=p;//新节点为父节点的左孩子节点
return 1;
}
}
q=q->lchild;//指向左孩子
}
q=head;
while(q!=NULL)//循环右孩子查找
{
if(strcmp(x,q->data)==0)//比较
{
if(q->lchild==NULL)//如果此结点没有孩子则添加到左孩子
{
p->n=q->n+1;//孩子为父节点的辈分加1
q->lchild=p;//新节点为父节点的左孩子节点
return 1;
}
else//如果此结点有孩子,则找到孩子,再找到最后一个兄弟,并添加到后面
{
q=q->lchild;
while(q->rchild!=NULL)//循环到最后一个
{
q=q->rchild;//兄弟指向右孩子
}
p->n=q->n;//兄弟辈分相同
q->rchild=p;//新节点为父节点的左孩子节点
return 1;
}
}
q=q->rchild;//指向右孩子
}
}
int add_brother(node *head)//添加兄弟成员 非递归法
{
node *p,*s; //定义新变量
char y[20],x[20];
p=head;
s=(node *)malloc(sizeof(node));//动态分配存储空间
printf("输入加入兄弟节点姓名");
scanf("%s",&x);//输入兄弟节点姓名
printf("请输入要添加的兄弟:");
scanf("%s",&y);//输入添加信息
strcpy(s->data,y);//赋值
s->lchild=NULL;//新节点左孩子为空
s->rchild=NULL;//新节点右孩子为空
while(1)//循环左孩子查找
{
if(strcmp(p->data,x)==0)//比较
{
if(p->rchild==NULL)//如果兄弟节点为空,赋给兄弟节点
{
s->n=p->n;//兄弟辈分相同
p->rchild=s;//兄弟为右孩子
return 1;
}
else//否则找到最后一个兄弟,在其后添加结点
{
while(p->rchild!=NULL)//循环到最后节点
{
p=p->rchild;//指向下一个右孩子
}
s->n=p->n;//兄弟辈分相同
p->rchild=s;//兄弟为右孩子
return 1;
}
}
p=p->lchild;//指向左孩子
}
p=head;
while(1)//循环右孩子查找
{
if(strcmp(p->data,x)==0)//比较
{
if(p->rchild==NULL)//如果兄弟节点为空,赋给兄弟节点
{
s->n=p->n;//兄弟辈分相同
p->rchild=s;//兄弟为右孩子
return 1;
}
else//否则找到最后一个兄弟,在其后添加结点
{
while(p->rchild!=NULL)//循环到最后节点
{
p=p->rchild;//指向下一个右孩子
}
s->n=p->n;//兄弟辈分相同
p->rchild=s;//兄弟为右孩子
return 1;
}
}
p=p->rchild;//指向右孩子
}
}
void print(node *head,char *x)//输出指定家庭成员 递归法
{
if(head!=NULL)
{
if(strcmp(head->data,x)==0)//查找
{
if(strcmp(head->data,"0")!=0)//比较
printf("%s-",head->data);//找到后先输出该成员,再调用函数输出其子孙
if(head->lchild!=NULL)
{
head=head->lchild;
print1(head);//调用函数,输出孩子节点
}
}
print(head->lchild,x);//递归
print(head->rchild,x);//递归
}
}
int beifen(node *p,char *x)//确定成员辈分 递归法
{
if(p!=NULL)
{
if(strcmp(p->data,x)==0&&strcmp(p->data,"0")!=0)//如果找到且不为字符 0 则输出
{
printf("%d",p->n);//输出
return 1;
}
beifen(p->lchild,x);//递归
beifen(p->rchild,x);//递归
}
}
void print1(node *head)//先序遍历 输出家庭成员 递归法
{
if(head!=NULL)
{
if(strcmp(head->data,"0")!=0)//判断是否为空
printf("-%s-",head->data);//输出
print1(head->lchild);//递归
print1(head->rchild);//递归
}
}
void chengyuan(node *head,int s)//输出相应辈分成员 递归法
{
if(head!=NULL)
{
if(head->n==s)//找到后且该成员未被删除 则输出
{
if(strcmp(head->data,"0")!=0)//查找
printf("-%s-",head->data);//输出
}
chengyuan(head->lchild,s);//递归
chengyuan(head->rchild,s);//递归
}
}
node *shanchu(node *head,char *s)//其实未删除,只是将其姓名设为字符 0 递归法
{
if(head!=NULL)
{
if(strcmp(head->data,s)==0)//比较找到
strcpy(head->data,"0");//值归0
shanchu(head->lchild,s);//递归
shanchu(head->rchild,s);//递归
}
}
void caidan()//菜单
{
printf("* 1.设立家谱祖先 *\n");
printf("* 2.添加家庭成员(孩子) *\n");
printf("* 3.添加家庭成员(兄弟) *\n");
printf("* 4.输出指定家庭成员 *\n");
printf("* 5.确定成员辈分 *\n");
printf("* 6.输出指定辈的所有成员 *\n");
printf("* 7.删除家庭成员 *\n");
printf("* 0.退出 *\n");
}
int main()//主函数
{
node *head;//定义头节点
int n,m;
char s[20];
printf("\n******家谱(孩子兄弟表示法)********\n");
while(1)
{
caidan();
printf("输入选项:");
scanf("%d",&m);//输入选项
if(m==1)//创建祖先
{
head=creat();//调用函数
}
if(m==2)//添加孩子
{
add_child(head);//调用函数
}
if(m==3)//添加兄弟
{
add_brother(head);//调用函数
}
if(m==4)//输出一个家庭成员
{
printf("请输入父亲节点:");
scanf("%s",&s);
printf("\n成员为: ");
print(head,s);//调用函数
printf("\n");
}
if(m==5)//确定某人辈分
{
printf("请输入姓名:");
scanf("%s",&s);
printf("辈分为:");
beifen(head,s);//调用函数
printf("\n");
}
if(m==6)//输出指定辈分中所有人
{
printf("请输入辈分:");
scanf("%d",&n);
printf("\n成员为: ");
chengyuan(head,n);//调用函数
printf("\n");
}
if(m==7)//删除成员
{
printf("请输入要删除的成员:");
scanf("%s",&s);
shanchu(head,s);//调用函数
}
if(m==0)//退出
{
printf("谢谢使用家谱系统!\n");
break;
}
}
}