家谱管理系统-数据结构大作业
发布时间:2019-05-15 03:04:56
发布时间:2019-05-15 03:04:56
/* 家谱管理系统
任务:实现具有下列功能的家谱管理系统
功能要求:
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,livete
mp);
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; i
printf("\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->m
arriage,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->add
ress,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++;
}
SearchByBirthday(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->n
ext->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->s
ex);
printf(" 他妻子的信息为 : \n");
printf("%-10s%-10s%-10s%5d%5d%5d\n",T->lc->name,T->lc->birthday,T->lc->address,T->lc->marri
age,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->ma
rriage,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;
}
}
}