数据结构_家谱管理系统

/*7、家谱管理系统 (4)
任务:实现具有下列功能的家谱管理系统
功能要求:
1). 输入文件以存放最初家谱中各成员的信息,成员的信息中均应包含以下内容:
姓名、出生日期、婚否、地址、健在否、死亡日期(若其已死亡),也可附加其它信息、但不是必需的。
2). 实现数据的存盘和读盘。
3). 以图形方式显示家谱。
4). 显示第n 代所有人的信息。
5). 按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。
6). 按照出生日期查询成员名单。
7). 输入两人姓名,确定其关系。
8). 某成员添加孩子。
9). 删除某成员(若其还有后代,则一并删除)。
10).修改某成员信息。
11).按出生日期对家谱中所有人排序。
12).打开一家谱时,提示当天生日的健在成员。
要求:建立至少30个成员的数据,以较为直观的方式显示结果,并提供文稿形式以便检查。
界面要求:有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。
存储结构:学生自己根据系统功能要求自己设计,但是要求相关数据要存储在数据文件中。
测试数据:要求使用1、全部合法数据;2、局部非法数据。进行程序测试,以保证程序的稳定。
测试数据及测试结果请在上交的资料中写明;
*/

#include
#include
#include
#include
#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,&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;
//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未婚");
if(T->sex)
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男");
if(!T->sex)
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; iprintf("\t");
printf("%-5s ",p->name);
if(p->lc)
{
p = T->lc;
printf("★*★ %5s%\n",p->name);
if(p->rc)
{
p = p->rc;
ShowFamilyTree(p);
}
}
else
printf(" (未婚)\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->marriage,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->address,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->address,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;

}
else
temp = 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->marriage,T->live,T->sex);
count++;
}
Search

ByBirthday(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->marriage,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)//修改某成员信息。
{
if(T)
{
if(strcmp(T->name,searchname) == 0)
{
count++;
DoAmend(T);
return;
}
AmendInfo(T->lc);
AmendInfo(T->rc);
}
}

void Sequence(BiTree T)//按出生日期对家谱中所有人排序。
{
if(T)
{
BiTNodeList *temp;
BiTNodeList *p;
temp = (BiTNodeList *)malloc(sizeof(BiTNodeList));
temp->data = T;
//p = List;
//while(p->)
for(p=List; (p->next!=NULL)&&(strcmp(p->next->data->birthday,temp->data->birthday)<0); p=p->next);
temp->next = p->next;
p->next = temp;
Sequence(T->lc);
Sequence(T->rc);
}
}

void PrintSequence(BiTree T)
{
BiTNodeList *p;
p = List;
Sequence(T);
printf("\t\t\t\t排序结果\n\n");
PrintLine();
printf("\n");
while(p->next != NULL)
{
printf(" ");
PrintInfo(p->next->data);
//printf("\t%-10s%-10s%-10s%5d%5d%5d\n",p->next->data->name,p->next->data->birthday,p->next->data->address,p->next->data->marriage,p->next->data->live,p->next->data->sex);
p = p->next;
}
printf("\n");
PrintLine();
}

void LocateTime()
{
time_t t=time(0);
strftime(birthdaytemp,64,"%Y-%m-%d",localtime(&t));
}

void BirthToday(BiTree T)//打开一家谱时,提示当天生日的健在成员。
{
if(T)
{
if(strcmp(T->birthday,birthdaytemp) == 0)
{
count++;
printf("%s\n",T->name);
}
BirthToday(T->lc);
BirthToday(T->rc);
}
}

void ShowMenu()
{
PrintBat();
printf("\n");
PrintLine();
printf("\n");
printf("\t\t\t欢迎进入家谱管理系统\n\n");
printf(" 1.显示今天生日成员 2.显示家谱\n");
printf(" 3.显示第n代所有人的信息 4.按姓名查找成员\n");
printf(" 5.按出生日期查找成员 6.为成员添加孩子\n");
printf(" 7.为成员添加妻子 8.

删除成员\n");
printf(" 9.修改成员信息 10.确定两个人的关系\n");
printf(" 11.按出生年月排序家谱成员 12.退出程序\n");
printf("\n");
PrintLine();
printf("\n");
printf(" 已经从文件读入初始家谱信息,请输入您的操作(1-12): ");
}

int main(void)
{
int choice;
FILE *in;
in = fopen("7.out","r");
BiTree T;
CreatBiTree(T,in);
//PreOrderTraverse_recursion(T);
while(1)
{
system("cls");
ShowMenu();
scanf("%d",&choice);
getchar();
system("cls");
switch(choice)
{
case 1:
LocateTime();
count = 0;
BirthToday(T);
if(count == 0)
printf("今天家谱中没有成员过生日\n");
system("pause");
break;
case 2:
ShowFamilyTree(T);
system("pause");
break;
case 3:
printf("请输入需要查询第几代人: ");
count = 0;
scanf("%d",&Nth);
ShowNth(T);
if(count == 0)
printf("第%d代尚未有人。\n",Nth);
system("pause");
break;
case 4:
printf("请输入要查询人的姓名: ");
scanf("%s",searchname);
if(strcmp(T->name,searchname) == 0)
{
printf("此人为家谱的祖先,其信息为:\n");
printf("%-10s%-10s%-10s%5d%5d%5d\n",T->name,T->birthday,T->address,T->marriage,T->live,T->sex);
printf("他妻子的信息为: \n");
printf("%-10s%-10s%-10s%5d%5d%5d\n",T->lc->name,T->lc->birthday,T->lc->address,T->lc->marriage,T->lc->live,T->lc->sex);
temp = T->lc;
if(temp->rc)
{
printf("他孩子的信息为:\n");
temp = temp->rc;
while(temp)
{
printf("%-10s%-10s%-10s%5d%5d%5d\n",temp->name,temp->birthday,temp->address,temp->marriage,temp->live,temp->sex);
temp = temp->rc;
}
}
}
else
{
count = 0;
SearchByName(T);
if(count == 0)
printf("对不起,不能检测这个人的信息\n");
}
system("pause");
break;
case 5:
printf("请输入要查询人的生日: ");
count = 0;
scanf("%s",searchdata);
SearchByBirthday(T)

;
if(count == 0)
printf("%s 没有人过生日。\n",searchdata);
system("pause");
break;
case 6:
count = 0;
printf("请输入要添加孩子成员的姓名: ");
scanf("%s",searchname);
AddChild(T);
if(count == 0)
printf("没有这个人\n");
system("pause");
break;
case 7:
count = 0;
printf("请输入要添加妻子成员的姓名: ");
scanf("%s",searchname);
AddWife(T);
if(count == 0)
printf("没有这个人\n");
system("pause");
break;
case 8:
count = 0;
printf("请输入要删除成员的姓名: ");
scanf("%s",searchname);
DeleteByName(T);
if(count == 0)
printf("没有这个人\n");
system("pause");
break;
case 9:
count = 0;
printf("请输入要修改人的姓名: ");
scanf("%s",searchname);
AmendInfo(T);
if(count == 0)
printf("没有这个人\n");
system("pause");
break;
case 10:
FixRelation(T);
system("pause");
break;
case 11:
count = 0;
List = (BiTNodeList *)(malloc(sizeof(BiTNodeList)));
List->next = NULL;
PrintSequence(T);
system("pause");
break;
case 12:
return;
system("pause");
break;
default:
printf("输入数据有误,请重新输入\n");
break;
}
}
}

相关文档
最新文档