#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<conio.h>
typedef char TElemType;
typedef int status;
typedef struct BiTPNode
{
TElemType data[10];
struct BiTPNode *parent,*lchild,*rchild;//父亲及左右孩子指针
}BiTPNode,*BiPTree;
BiPTree P;
BiPTree T;
//家谱的创建
int Cre()
{
system("cls");
FILE *fp;//声明指向文件的指针
char filename[40],str[10];
printf("请输入家谱名称");
getchar();
gets(filename);//输入家谱名称
while(filename==NULL)
{
printf("家谱名不能为空,请重新输入:");
gets(filename);
}
if((fp-fopen (filename,"w"))==NULL)
{
printf("%s家谱创建失败!\n",filename);
return 0;
}
printf("请输入家谱内容:\n");
while (strlen(gets(str))>0)
{
fprintf(fp, "%s\n",str);
}
fclose(fp);//关闭文件
printf("按任一键继续!");
getch();
return 1;
}
status loc(BiPTree T,BiPTree P,TElemType name[10])
{
if(T)
{
P=T;//字符串的比较
if(!strcmp(name,T->data))return 1;
if(loc(T->lchild,P,name)) return 1;
if(loc(T->rchild,P,name)) return 1;
}
else
return 0;
}
//构造二叉树
status inittree(BiPTree T)
{
T=(BiTPNode*)malloc(sizeof(BiTPNode));
if(T)
return 0;
T->lchild=NULL;
T->rchild=NULL;
T->parent=NULL;
return 1;
}
//载入家谱
status Crt(BiPTree T)
{
FILE *fp;
BiPTree Q,R,M,N;
char filename[40],name[10];
system("cls");//清屏
R=(BiTPNode *)malloc(sizeof (BiTPNode));//分配存储空间
M=(BiTPNode *)malloc(sizeof(BiTPNode));
N=(BiTPNode *)malloc(sizeof(BiTPNode));
printf("请输入家谱名:");
getchar();
gets(filename);
while(filename[0]==NULL)
{
printf("家谱名不能为空,请重新输入:");
gets (filename);
}
if((fp-fopen (filename,"r"))==NULL)
{
printf("%s家谱打开失败!\n",filename);
return 0;
}
inittree(T);
fscanf(fp,"%s",&name);//从文件读入姓名
strcpy(T->data,name);
T->lchild=NULL;
T->rchild=NULL;
T->parent=NULL;
fclose(fp);
if((fp=fopen(filename,"r"))==NULL)
{
printf("%家谱打开失败!\n",filename);
return 0;
}
fscanf(fp,"%s",name);
while(!feof(fp))
{
if(loc(T,P,name))
{
fscanf(fp,"%s",name);
Q=(BiTPNode*)malloc(sizeof(BiTPNode));
strcpy(Q->data,name);
P->lchild=Q;//构建孩子
Q->parent=P;
Q->lchild=NULL;
Q->rchild=NULL;
N=P;
}
else if(!loc(T,P,name))
{
Q=(BiTPNode*)malloc(sizeof(BiTPNode));
R=N;
R=R->lchild;
while(R)
{
M=R;
R=R->rchild;
}
strcpy(Q->data,name);
M->rchild=Q;
Q->parent=M;
Q->lchild=NULL;
Q->rchild=NULL;
}
fscanf(fp,"%s",name);
}
printf("信息载入成功,按任一键继续!");
getch();
return 1;
}
//添加成员
status in(BiPTree T)
{
char father [10],name[10];
BiPTree Q,M;
system("cls");
printf("请输入要添加到该家谱中的人的父亲的姓名:");
getchar();
gets(father);
while(!loc(T,P,father))
{
printf("%s 不在该家谱中!请重新输入:",father);
gets(father);
}
printf("请输入要添加到该家谱中的人的姓名:");
gets(name);
Q=(BiTPNode*)malloc(sizeof(BiTPNode));
M=(BiTPNode*)malloc(sizeof(BiTPNode));
strcpy(Q->data,name);
Q->lchild=NULL;
Q->rchild=NULL;
if(!P->lchild)
{
P->lchild=Q;
Q->parent=P;
}
else
{
P=P->lchild;
while(P)
{
M=P;
P=P->rchild;
}
M->rchild=Q;
Q->parent=M;
}
printf("成员添加成功,按任一键继续!");
getch();
return 1;
}
//删除成员
status de(BiPTree T)
{
char name[10];
system("cls");
printf("请输入要删除的人的姓名:");
getchar();
gets(name);
while(!loc(T,P,name))
{
printf("%s不在该家谱中!请重新输入:",name);
gets(name);
}
if(!P->rchild)
{
if(P->parent->lchild==P)
P->parent->lchild==NULL;
else
P->parent->rchild=NULL;
free(P);
}
else if(P->rchild)
{
if(P->parent->lchild==P)
P->parent->lchild=P->rchild;
else
P->parent->rchild=P->rchild;
free(P);
}
printf("成员删除成功,按任一键继续!");
getch();
return 1;
}
status Show(TElemType e[10])
{
printf("%s ",e);
return 1;
}
//二叉树的遍历
status pre(BiPTree T,status(*visit)(TElemType[10]))
{
if(T)
{
if((*visit)(T->data))
if (pre(T->lchild,visit)) return 1;
return 0;
}
else return 1;
}
//家族成员查询
status Sea(BiPTree T)
{
char name[10];
BiPTree N;
N=(BiTPNode *)malloc(sizeof (BiTPNode));
system("cls");
printf("请输入要查寻的人的姓名:");
getchar ();
gets(name);
while(!loc(T,P,name))
{
printf("%s 不在该家谱中!请重新输入:",name);
gets(name);
}
N=P;
if(P==T)
printf("%s 的父亲在该家谱中没有记载!\n:",P->data);
else
{
while(N->parent->rchild==N)
N=N->parent;
printf("%s 的父亲是:%s\n",P->data,N->parent->data);
}
N=P;
if(P==T)
printf("%s 没有兄弟!\n",P->data);
else if(!P->rchild&&P->parent->rchild!=P)
printf("%s 没有兄弟!\n",P->data);
else
{
printf("%s 的兄弟有:\n",name);
while(N->rchild)
{
printf("%s *",N->rchild->data);
N-N->rchild;
}
N=P;
while(N->parent->rchild==N)
{
printf("%s",N->parent->data);
N-N->parent;
}
printf("\n");
}
if(P==T)
printf("%s的祖先在该家谱中没有记载!\n",name);
else
printf("%s 的祖先是:%sn",name,T->data);
N=P;
if(!P->lchild)
{
printf("%s 没有孩子!\n",name);
printf("%s 没有后代\n",name);
}
else
{
printf("%s 的孩子有:\n",name);
printf("*%s",P->lchild->data);
N=N->lchild;
while(N->rchild)
{
printf("%s ",N->rchild->data);
N-N->rchild;
}
printf("\n");
printf("%s 的后代有:\n",name);
pre(P->lchild,Show);
printf("\n");
}
printf("按任一键继续!");
getch();
return 1;
}
//文件的创建
status write(BiPTree T,char filename[40]){
FILE *fp;
if((fp=fopen(filename,"a+"))==NULL)
{
printf("%s 文件创建失败!\n",filename);
return 0;
}
fprintf(fp,"%s",T->data);
T=T->lchild;
while(T)
{
fprintf(fp,"%s",T->data);
T-T->rchild;
}
fprintf(fp,"\n");//输出
fclose(fp);
//felose(fp);
return 1;
}
status prewrite(BiPTree T,status(*visit)(BiPTree,char[40]),char filename[40])
{
if(T)
{
if (T->rchild)
(*visit)(T,filename);
prewrite(T->lchild,visit,filename);
prewrite(T->rchild,visit,filename);
return 1;
}
else return 1;
}
status wrong()
{
char a;
scanf("%c",&a);
printf("无此选项,请重新选择!(按任一键继续!)");
getch();
return 1;
}
//家谱的存储
status Sav(BiPTree T)
{
FILE *fp;
char filename[40];
system("cls");
printf("请输入新的文件名:");
getchar ();
gets(filename);
while(filename==NULL)
{
printf("家谱名不能为空,请重新输入:");
gets(filename);
}
prewrite(T,write,filename);
printf("%s 家谱保存成功,按任一键继续!",filename);
getch();
return 1;
}
//修改家谱
status Upd()
{
system("cls");
int xz;
while(1)
{
system("cls");
printf("\n\n\n\n");
printf(" 家族成员的添加与制除操作 \n");
printf(" 请选择 \n");
printf(" 1.添加成员. \n");
printf(" 2.删除成员. \n");
printf(" 3.返回上一级. \n");
printf(" 请选择:");
scanf("%d",&xz);
switch(xz)
{
case 1 : in(T);break;
case 2 : de(T);break;
case 3 : return 0;
default:
wrong();
break;
}
}
}
int main()
{
BiPTree P;
P=(BiTPNode*)malloc(sizeof(BiTPNode));
int xz;
while(1)
{
system("cls");
printf("\n\n\n\n");
printf(" 家族关系查询系统 \n");
printf(" 具体操作如下 \n");
printf(" 1.创建家谱 \n");
printf(" 2.载入家谱 \n");
printf(" 3.修改家谱 \n");
printf(" 4.查寻成员 \n");
printf(" 5.保存家谱 \n");
printf(" 6.退出程序 \n");
printf(" 请选择操作:");
scanf("%d",&xz);
switch(xz)
{
case 1:
Cre();
break;
case 2:
Crt(T);
break;
case 3:
Upd();
break;
case 4:
Sea(T);
break;
case 5:
Sav(T);
break;
case 6:
return 0;
default:
wrong();
break;
}
}
return 0;
}