资源描述
洛阳理工学院
课程设计报 告
数据结构课程设计
课程名称 ___________________________________
家谱管理系统
设计题目 ___________________________________
计算机科学与技术
专 业 ___________________________________
B150405
班 级 ___________________________________
B15080822
学 号 ___________________________________
宋士龙
姓 名 ___________________________________
2016年12月30日
完成日期 ___________________________________
课 程 设 计 任 务 书
设计题目:家谱管理系统
设计内容与要求:
【问题描述】:实现具有下列功能的家谱管理系统
1)。 输入文件以存放最初家谱中各成员的信息,成员的信息中均应包含以下内容:
姓名、出生日期、婚否、地址、健在否、死亡日期(若其已死亡),也可附加其它信息、但不是必需的。
2). 实现数据的存盘和读盘。
3)。 显示家谱。
4)。 按照出生日期查询成员名单。
5)。 按照姓名查询,输出成员信息(包括其本人、父亲、孩子的信息)。
6). 修改某成员信息。
【基本要求】:
界面要求:有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。
存储结构:学生自己根据系统功能要求自己设计,但是要求相关数据要存储在数据文件中.
测试数据:要求使用1、全部合法数据;2、局部非法数据.进行程序测试,以保证程序的稳定。
测试数据及测试结果请在上交的资料中写明。
指导教师:_______________
年 月 日
课 程 设 计 评 语
成绩:
指导教师:_______________
年 月 日
洛 阳 理 工 学 院 课 程 设 计 报 告
一、 算法思想
本程序是一个管理家谱的系统,通过这个系统可以对家族成员进行创建、显示、查找
、修改、以及保存家谱和读取家谱功能.该系统分为以下几个模块,分别是:创建家谱,显示家谱、按姓名和生日查找家庭成员、修改家谱、存盘、读盘以及退出系统。本程序用到的存储形式为多叉树,因为家谱中每个人既有父母又有孩子,而且孩子的个数并不确定,所以用多叉树来存储最为合适.用多叉树来存储,就用用到多叉树的递归创建及递归遍历.因为是多叉树,所以遍历时用广度优先搜索合适。本函数最主要的思想就是递归调用,每个子函数中都会用到递归。定义结构体时给定指针数组的最大容量,来规定家谱中最多可以存多少人。定义一个家族树的指针变量用来当每个子函数的参数,从而将其返回到主函数中。
以下时算法思想流程图:
家谱管理系统
创建家谱
显示家谱
修改家谱
查找成员
读写家谱
按照姓名
按照生日
修改本人
修改父母
修改孩子
存盘
读盘
退出系统
二、 模块划分
1. int main():主函数
2. void CreatTree(TreeNode *Tree):创建家族树
3. void OutPutAll(TreeNode *Tree):显示家谱
4. void Menue(TreeNode *Tree):主菜单
5. void SubMenue1(TreeNode * Tree):副菜单(修改选项菜单)
6. void Change(TreeNode * Tree):修改家谱
7. TreeNode * SearchTree(TreeNode *Tree,char name[],int length):按照姓名查找家谱成员
8. TreeNode * SearchTree1(TreeNode *Tree,char birth[],int length):按照生日查找家谱成员
9. void OutPutMessage(TreeNode * Tree,char name[],int length):输出按姓名查找到的家谱成员
10. void OutPutMessage1(TreeNode * Tree,char birth[],int length):输出按生日查找到的家谱成员
11. void SaveFamily(TreeNode *root):保存家谱
12. void ReadFamily(TreeNode **root):读取家谱
三、 数据结构
typedef struct TreeNode
{
int ChildNum; //记录这个人拥有几个儿女
char Name[20];//记录这个人的姓名
char birthday[20];//生日
int marriage;//婚否(1表示结婚,0表示没结婚)
int death;//生死(1表示活着,0表示过世)
char Kind;//标示节点的种类有女G男B
char address[100];//住址
char livemassage[50];//死亡日期(如果其已经死亡)
struct TreeNode *NextNode[20]; //记录这个人的儿女
struct TreeNode *Parent; //记录这个节点的父节点
}TreeNode,*tree;
四、 测试
第一组数据为:
爷爷,奶奶,爸爸,妈妈,我,二叔,二婶,姐姐,三叔,三婶,弟弟一共三代11个人。
其中爷爷是根节点,奶奶为爷爷的配偶,同时也是爷爷的第一个后继节点.爸爸,二叔,三叔为爷爷的子女。爸爸的配偶是妈妈,爸爸的子女是我.二叔的配偶是二婶,子女是姐姐。三叔的的配偶是三婶,三叔的的子女是弟弟.
进入程序之后,首先进行创建家谱,然后进行存盘,之后进行修改和查询等步骤.退出程序在进入程序时,进行读盘。之后在进行其他操作,程序完成之后退出即可.
爷爷
爸爸
二叔
奶奶
三叔
妈妈
二婶
三婶
我
姐姐
弟弟
图1 家族树
第一组数据测试截图为:
图2 显示家谱
图3 按照姓名查找家族成员
图4 存盘
第二组数据为:
王老
王大
刘老
王二
李大
张二
王小一
王小二
图4 王家家族树
第二组数据测试截屏为:
图5 修改家族成员的信息
图6 修改某个人的具体信息
图7 按照生日查找某人
图8 读盘
五、 源程序
#include 〈stdio。h〉
#include 〈stdlib。h>
#include 〈string.h〉
#ifdef WIN32
#define CLEAR system("cls")
#define TipForSaveFilePosition printf(”\t\t输入文件名及保存位置(eg: D:\\\\example.txt): ”)
#define TipForReadFilePosition printf(”\t\t文件名及其路径(eg: D:\\\\example.txt): ”)
#else
#define CLEAR system(”clear")
#define TipForSaveFilePosition printf(”\t\t输入文件名及保存位置(eg: /home/xiong/example。txt): ")
#define TipForReadFilePosition printf(”\t\t文件名及其路径(eg: /home/xiong/example。txt): ”)
#endif
#define maxFileNameLen 50 //保存的文件名的最大长度
int FLAG=0;
int a=1;
typedef struct TreeNode
{
int ChildNum; //记录这个人拥有几个儿女
char Name[20];//记录这个人的姓名
char birthday[20];//生日
int marriage;//婚否(1表示结婚,0表示没结婚)
int death;//生死(1表示活着,0表示过世)
char Kind;//标示节点的种类有女G男B
char address[100];//住址
char livemassage[50];//死亡日期(如果其已经死亡)
struct TreeNode *NextNode[20]; //记录这个人的儿女
struct TreeNode *Parent; //记录这个节点的父节点
}TreeNode,*tree;
void CreatTree(TreeNode *Tree);
void OutPutAll(TreeNode *Tree);
void Menue(TreeNode *Tree);
void SubMenue1(TreeNode * Tree);
void SubMenue2(TreeNode *Tree);
void Change(TreeNode * Tree);
void AddNew(TreeNode * Tree);
TreeNode * SearchTree(TreeNode *Tree,char name[],int length);
TreeNode * SearchTree1(TreeNode *Tree,char birth[],int length) ;
void OutPutMessage(TreeNode * Tree,char name[],int length);
void OutPutMessage1(TreeNode * Tree,char birth[],int length);
void SaveFamily(TreeNode *root);
void ReadFamily(TreeNode **root);
int main()//主函数
{
TreeNode *Tree;//TreeNode **Tree1;
//Tree1=&(*Tree);
Tree=(TreeNode *)malloc(sizeof(TreeNode));
Tree->Parent =NULL;
strcpy(Tree-〉Name,"0”);
Menue(Tree);
return 0;
}
void Menue(TreeNode *Tree)//输出主菜单
{
/*TreeNode **Tree1;
Tree1=&Tree;*/
char c;
char name[20];
char birth[20];
while(1)
{
system(”cls”);
printf(”\t”);
printf(”\n\n\t\t**********欢 迎 使 用 家 族 管 理 系 统**********\n\n”);
printf("\n\t\t A:输入家谱信息建立树 ”);
printf("\n\t\t B:输出整个家谱信息 ”);
printf(”\n\t\t C:按出生日期查找某人 ”);
printf("\n\t\t D:按姓名查找某人 ");
printf("\n\t\t E:修改某个人的信息 ");
printf("\n\t\t F:存盘 ”);
printf(”\n\t\t G:读盘 ”);
printf(”\n\t\t H:退出整个程序 \n\t");
c=getchar();
switch(c)
{
case 'A':
TreeNode * NewNode;
NewNode=(TreeNode *)malloc(sizeof(TreeNode));
printf("\n\t请输入姓名:");
scanf(”%s",Tree-〉Name);
printf("\n\t请输入性别女G男B:”);
getchar();
scanf("%c",&(Tree-〉Kind));
Tree—〉Parent=NewNode;
Tree—〉Parent=NULL;//
CreatTree(Tree); //
printf(”\n\t—-———-————-—-—家谱图已经建立成功-—--———-—-—-———\n\n”);
printf(”\n\n\t—---——-——————-请按Enter键继续操作-------———————”);
getchar();
break;
case ’B’:
if(strcmp(Tree—>Name,”0")==0)
{
printf("\n\t家谱图的多叉树尚未建立请先建立树\n");
getchar();
break;
}
printf("\n\n\t整个家谱的主要信息如下:");
OutPutAll(Tree);
getchar();
break;
case ’C':
if(strcmp(Tree—〉birthday,"0”)==0)
{
printf(”\n\t家谱图的多叉树尚未建立请先建立树\n”);
getchar();
break;
}
printf(”\n\t请输入你要查找的出生日期:”);
scanf("%s”,birth);
OutPutMessage1(SearchTree1(Tree,birth,20),birth,20);
printf(”\n\n\t-—--—*—--—*-—--*————*-—--*————*————*—--—*—--—*---—*—-——\n\t");
getchar();
break;
case ’D':
if(strcmp(Tree-〉Name,”0")==0)
{
printf("\n\t家谱图的多叉树尚未建立请先建立树\n”);
getchar();
break;
}
printf(”\n\t请输入你要查找的人的姓名:\n\t”);
scanf(”%s”,name);
OutPutMessage(SearchTree(Tree,name,20),name,20);
printf(”\n\n\t----—*—-——*————*—---*—-—-*—---*————*-—-—*-—--*-—-—*————\n\t");
getchar();
break;
case 'E’:
if(strcmp(Tree—〉Name,"0")==0)
{
printf(”\n\t家谱图的多叉树尚未建立请先建立树\n”);
getchar();
break;
}
Change(Tree);
getchar();
break;
case ’F’:
if(strcmp(Tree->Name,”0")==0)
{
printf("\n\t家谱图的多叉树尚未建立请先建立树\n”);
getchar();
break;
}
SaveFamily(Tree);
getchar();
break;
case 'G':
/*if(strcmp(Tree—〉Name,"0")==0)
{
printf(”\n\t家谱图的多叉树尚未建立请先建立树\n”);
getchar();
break;
}*/
ReadFamily(&Tree);
getchar();
break;
case ’H':
printf("\n\n\t——--———-———-—-—--本次服务到此结束-—--—-——————-—————”);
printf("\n\t-——-————---—-—-—-—欢迎下次使用-———-——----—---—-——--”);
printf(”\n\t-———-——----———-———-—-—谢谢--—--———--————————-———---\n\n");
break;
case '\n’:
break;
default:
printf(”\n\n\t—--—-———对不起!你的选择不在服务范围之内!—-—-——--———”);
printf("\n\t--———-——-—-请您再次选择所需的服务项!——---———--——-—-”);
printf(”\n\t—--—-————————-————谢谢-—-———————————--———-—---\n\t");
getchar();
break;
}
if (c==’H'||c==’f’)
break;
getchar();
}
}
void CreatTree(TreeNode *Node) //创建树
{
int i;
TreeNode *NewNode;
NewNode=(TreeNode *)malloc(sizeof(TreeNode));
Node—〉NextNode[0]=NewNode;
Node->NextNode[0]=NULL;
printf(”\n\t请输入出生日期:");
scanf(”%s",Node—>birthday);
printf("\n\t请输入家庭住址:");getchar();
scanf(”%s”,Node->address);
printf(”\n\t请输入是否建在(1—是或0-否):”);
scanf(”%d”,&(Node—〉death));
if(Node-〉death==0)
{
printf(”\n\t请输入去世日期:”);
scanf(”%s",Node-〉livemassage);
}
else if(Node-〉death=='1')
printf(”\n\t仍然建在");
printf(”\n\t请输入%s的配偶的姓名(输入0代表没结婚):”,Node-〉Name);
scanf(”%s",NewNode->Name);
if(strcmp(NewNode—〉Name,”0”)!=0)
{printf(”\t请输入配偶的出生日期:");
scanf("%s”,NewNode—〉birthday);
printf(”\n\t请输入家庭住址:");getchar();
scanf("%s”,NewNode—>address);
printf(”\n\t请输入是否建在(1—是或0-否):”);
scanf("%d”,&(NewNode—〉death));
if(NewNode—〉death==0)
{
printf(”\n\t请输入去世日期:");
scanf(”%s”,NewNode->livemassage);
}
else if(NewNode->death==’1’)
printf(”\n\t仍然建在”);}
printf(”\n\t请输入%s的子女的数目(当子女输入0时便停止输入该成员有关信息):”,Node—〉Name);
scanf(”%d”,&(Node—〉ChildNum));
if((Node—〉ChildNum)==0&&strcmp(NewNode->Name,”0”)==0)
return ;
if(Node—〉Kind==’G’||Node—>Kind=='g')
NewNode—〉Kind=’B’;
else
NewNode—〉Kind=’G’;
NewNode-〉ChildNum=0;
NewNode—〉NextNode[0]=NULL;
Node—〉NextNode[0]=NewNode;
Node->NextNode[0]-〉Parent=Node;//孩子的父母
for(i=1;i〈=Node->ChildNum;i++)
{
NewNode=(TreeNode *)malloc(sizeof(TreeNode));a++;
printf(”\n\t请输入%s的第%d子女的名字:",Node—>Name,i);
scanf(”%s",NewNode->Name);
printf(”\n\t请输入%s的第%d子女的性别女G男B:”,Node-〉Name,i);
getchar();
scanf(”%c",&NewNode—>Kind);
NewNode—>ChildNum=—1;
NewNode—>Parent=Node;
Node—〉NextNode[i]=NewNode;
CreatTree(Node—>NextNode[i]); //从子女的数目开始
}
}
void OutPutAll(TreeNode *Tree)
{
int i, flag=0;
printf("\n\t—--****-—-***—--***—-—***-——***-——***——-***———***-——***———");
printf("\n\t姓名:%s 出生日期:%s 家庭住址:%s 性别: %c",Tree-〉Name,Tree—>birthday,Tree—〉address,Tree—〉Kind);
if (Tree—〉Kind==’G'||Tree—>Kind=='g’)
{
flag=1;
printf("女”);
}
else
printf(”男");
printf(”\t是否健在(1—健在,0—去世):”);
if(Tree-〉death==1) printf(”1”);
else if(Tree-〉death==0) printf(”0”);
if (!(Tree—〉NextNode[0]))
{
printf("\n\t至今没有配偶和子女\n”);
return;
}
if(flag==1)
printf(”\n\t丈夫 姓名:%s”,Tree-〉NextNode[0]—〉Name);
else
printf(”\n\t妻子 姓名:%s”,Tree—>NextNode[0]—〉Name);
printf(”\t是否健在(1-健在,0—去世):”);
if(Tree—〉death==1) printf("1”);
else if(Tree—〉death==0) printf("0”);
for(i=1;i<=Tree—>ChildNum;i++)
{
printf("\n\t第%d个子女的姓名:%s 出生日期:%s 家庭住址:%s 性别%c",i,Tree->NextNode[i]—〉Name,Tree—〉NextNode[i]—〉birthday,Tree—〉NextNode[i]—〉address,Tree-〉NextNode[i]—〉Kind);
if (Tree—>NextNode[i]->Kind=='G'||Tree-〉NextNode[i]->Kind==’g’)
printf(”女");
else
printf("男”);
printf(”\t是否健在(1—健在,0—去世):”);
if(Tree-〉death==1) printf("1");
else if(Tree->death==0) printf(”0”);
}
printf("\n\t");
for(i=1;i〈=Tree—>ChildNum;i++)
{
OutPutAll(Tree-〉NextNode[i]);
}
}
TreeNode * SearchTree(TreeNode *Tree,char name[],int length)
{
int i;
TreeNode *NewNode;
if(strcmp(Tree—>Name,name)==0)
{
if(length==0)
FLAG=1;
else
FLAG=0;
return Tree;
}
if(Tree—〉NextNode[0]==NULL)
return NULL;
for(i=0;i<=Tree—>ChildNum;i++)
{
if (i==0)
NewNode=SearchTree(Tree->NextNode[i],name,0);
else
NewNode=SearchTree(Tree—>NextNode[i],name,20);
if (NewNode!=NULL)
return NewNode;
}
return NULL;
}
void OutPutMessage(TreeNode * Tree,char name[],int length)
{
int flag=0,i;
TreeNode *NewNode;
printf(”\n\n\t-————*————*——-—*————*————*——-—*————*——-—*———-*-——-*—-——");
if(Tree==NULL)
{
printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n”,name);
return;
}
printf(”\n\n\t您所要找的人已经找到信息如下所示:”);
printf(”\n\n\t姓名:%s出生日期:%s 家庭住址:%s 性别:%c",name,Tree—〉birthday,Tree->address,Tree—〉Kind);
if (Tree-〉Kind==’G’||Tree—〉Kind==’g’)
{
flag=1; //标记他(她)的性别
printf(”女”);
}
else
printf(”男");
printf("\t是否健在(1—健在,0-去世):”);
if(Tree—〉death==1) printf("1”);
else if(Tree—〉death==0) printf(”0”);
NewNode=Tree—〉Parent;
if (FLAG==1)
{
if(flag==1)
{
printf(”\n\n\t她是嫁入此家族的所以亲生父母信息不在家谱内包括”);
printf(”\n\t丈夫 姓名:%s”,NewNode-〉Name);
}
else
{
printf("\n\n\t他是入赘此家族的所以亲生父母信息不在家谱内包括");
printf(”\n\t妻子姓名:%s”,NewNode—〉Name);
}
if ((NewNode—〉ChildNum)>0) //判断他(她)是否有孩子
{
printf(”\n\t的孩子的信息如下:"); //输出他(她)的孩子的信息
for(i=1;i〈=NewNode—>ChildNum;i++)
{
printf(”\n\t姓名:%s 性别:",NewNode-〉NextNode[i]—>Name);
if (NewNode-〉NextNode[i]-〉Kind==’G’||NewNode—>Kind==’g')
printf("女”);
else
printf(”男”);
printf("\t是否健在(1—健在,0—去世):”);
if(Tree—>death==1) printf(”1”);
else if(Tree-〉death==0) printf("0”);
}
}
return;
}
if(NewNode==NULL)//判断它是不是根节点如果是的话就没有父母兄弟信息
printf(”\n\t是这个家谱图里最年长的人”,name);
else
{
if (NewNode—〉Kind==’G’||NewNode->Kind==’g’) //判断父亲节点是父亲还是母亲
{
printf("\n\t母亲 姓名:%s”,NewNode—〉Name);//输出他(她)的父母亲的信息
printf("\n\t父亲 姓名:%s”,NewNode—〉NextNode[0]—>Name);
}
else
{
printf("\n\t母亲 姓名:%s",NewNode—〉NextNode[0]->Name);
printf("\n\t父亲 姓名:%s”,NewNode—〉Name);
}
if(Tree—〉NextNode[0]!=NULL) //判断他(她)是否有配偶
{
if(flag==1)//输出他(她)的配偶的信息
printf(”\n\t丈夫 姓名:%s”,Tree-〉NextNode[0]—〉Name);
else
printf(”\n\t妻子 姓名:%s”,Tree->NextNode[0]->Name);
if (Tree—〉ChildNum>0) //判断他(她)是否有孩子
{
printf("\n\t的孩子的信息如下:”); //输出他(她)的孩子的信息
for(i=1;i〈=Tree—>ChildNum;i++)
{
printf(”\n\t姓名:%s 性别:",Tree—>NextNode[i]—>Name);
if (Tree—〉NextNode[i]-〉Kind==’G’||Tree—〉Kind==’g’)
printf(”女”);
else
printf(”男”);
printf("\t是否健在(1-健在,0—去世):”);
if(Tree-〉death==1) printf(”1");
else if(Tree-〉death==0) printf("0”);
}
}
else
printf("\n\t%s至今还没有孩子",name);
}
else
printf("\n\t%s至今还没有配偶和孩子\n”,Tree—>Name);
}
}
TreeNode * SearchTree1(TreeNode *Tree,char birth[],int length)
{
int i;
TreeNode *NewNode;
if(strcmp(Tree-〉birthday,birth)==0)
{
if(length==0)
FLAG=1;
else
FLAG=0;
return Tree;
}
if(Tree—>NextNode[0]==NULL)
return NULL;
for(i=0;i<=Tree—〉ChildNum;i++)
{
if (i==0)
NewNode=SearchTree1
展开阅读全文