人类族谱管理系统设计报告.docx

上传人:b****6 文档编号:3388077 上传时间:2022-11-22 格式:DOCX 页数:29 大小:1.42MB
下载 相关 举报
人类族谱管理系统设计报告.docx_第1页
第1页 / 共29页
人类族谱管理系统设计报告.docx_第2页
第2页 / 共29页
人类族谱管理系统设计报告.docx_第3页
第3页 / 共29页
人类族谱管理系统设计报告.docx_第4页
第4页 / 共29页
人类族谱管理系统设计报告.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

人类族谱管理系统设计报告.docx

《人类族谱管理系统设计报告.docx》由会员分享,可在线阅读,更多相关《人类族谱管理系统设计报告.docx(29页珍藏版)》请在冰豆网上搜索。

人类族谱管理系统设计报告.docx

人类族谱管理系统设计报告

 

人类族谱管理系统设计报告

 

 

软件学院

综合训练项目报告书

 

课程名称数据结构

项目名称人类家谱管理系统

专业班级软件13-3班

组别第五组

成员张伟竹王雨柔何惠民

任课教师孙宁

 

1.设计时间………………………………………………………………1

2.设计任务………………………………………………………………1

3.设计内容………………………………………………………………1

3.1问题分析…………………………………………………………….1

3.2程序设计……………………………………………………………3

3.3测试与分析………………………………………………………..10

3.3.1测试………………………………………………………..……10

3.3.2分析………………………………………………………..……14

3.4代码………………………………………………………………..14

4.总结与展望………………………………………………………….21

5.参考文献…………………………………………………………….22

1设计时间

12月16日——1月6日

2设计任务

树形结构是一种非常重要的非线性结构,它用于描述数据元素之间的层次关系,人类家谱是树形结构的典型体现,经过此项训练让学生掌握树形结构的知识;使学生重点掌握树与二叉树的转换,二叉树的存储和遍历;此项训练要求构造一棵家谱树,并完成任意成员的查找。

3设计内容

3.1问题分析

1.程序所能达到的功能,见功能模块图(图3-1)。

(1)输入家族始祖信息,初始化(或创立)一个家族族谱树。

(2)输入要添加人信息,插入新的家族成员。

(3)输入要查找人姓名,对家族成员进行查找。

(4)输入要修改人姓名,修改某一个家族成员信息。

2.输入的形式和输出的形式。

输入和输出的姓名能够是中文也能够是英文,变量名为char类型,且最多不得多余20字符,对于某一个人所处代数为数字,变量名为int类型,对输入输出的性别,本设计要求是M或F表示,故必须是英文,为char类型的变量。

3.存储结构设计思想。

本项目设计采用孩子兄弟链表(二叉链表)方式存储信息,包含一个data域和两个指针域,其中data域又为一个结构体类型,存储某一个人的信息,而对于指针域,一个为child域,指向此人的孩子,另一个为brother域,指向此人的兄弟姐妹,形成如下存储结构,见图3-2。

4.测试数据。

首先,创立一个家谱,输入始祖的姓名及性别,然后根据菜单要求输入要选择的步骤,本次测试以三代人的家谱为例,输入三代人的姓名及性别,三代人各查找一次,修改某一代人姓名(或性别)后,查找修改人信息,以验证本程序是否正确,最后退出族谱管理系统。

当家谱中成员存在时,显示初始化、添加、修改成功等信息。

当家谱中不存在此成员时,系统提示信息有误,要求重新输入所要添加、查找或修改人的信息。

图3-1功能模块图

图3-2存储结构图

3.2程序设计

1.本程序中用到的所有抽象数据类型的定义及实现。

(1)定义一个data存储结构,存放个人信息。

typedefstructnode

{

charname[MAX];//姓名

charsex;//性别

intgeneration;//代

}node;

(2)此处采用孩子兄弟链表法,定义一个结构体存放各代人信息。

typedefstructtreenode

{

structnodel;//家谱中直系家属

structtreenode*brother;//用来指向兄弟

structtreenode*child;//用来指向孩子

}treenode;

(3)定义一个指针变量,为treenode类型,指向各代人信息。

treenode*root;//root是指向结构体treenode的指针

(4)主要函数列表及说明,见表3-1。

表3-1主要函数列表及说明

函数名及其类型

函数功能

参数及其类型

参数功能

InitTree

void型,无返回值

创立一个家族族谱

charb[MAX],c

inta

数组参数b[MAX]存放姓名;参数c代表性别;参数a代表此人是第几代人

Add

void型,无返回值

添加家谱新成员

inta

Treenode*m,*n

Treenode*t

参数a接收搜索到的代数;m,n,t为三个treenode类型的指针变量,将搜索到的个人信息赋给m,n,t

Search

void型,无返回值

查找家谱成员信息

chard[MAX]

treenode*n

数组参数d[MAX]用于存放姓名;n为treenode类型的指针变量,将搜索到的个人信息赋给n

Change

void型,无返回值

修改家谱成员信息

chara[MAX],c

charr[MAX]

treenode*n

inti

数组参数a[MAX]存放要修改人的姓名;数组参数r[MAX]存放修改后的姓名;c代表修改的性别;n为treenode类型的指针变量,将搜索到的个人信息赋给n

 

2.主程序的流程图及函数的调用关系图。

(1)主函数流程图,见图3-3。

图3-3主函数流程图

 

(2)创立函数流程图,见图3-4。

图3-4创立函数流程图

(3)查找函数流程图,见图3-5。

图3-5查找函数流程图

 

(4)添加函数流程图,见图3-6。

图3-6添加函数流程图

 

(5)修改函数流程图,见图3-7。

图3-7修改函数流程图

(6)函数关系调用图,见图3-8。

图3-8函数关系调用图

3.主要函数伪码算法。

(1)创立函数伪码。

begin

free(root)

root(treenode*)malloc(sizeof(treenode))

print“输入始祖姓名及性别:

inputb,c

1=>a

NULL=>root->child

NULL=>root->brother

children(root,b,c,a)

print“家谱初始化成功!

end

(2)添加函数伪码。

begin

print“请输入要添加子女的上一代人姓名:

inputd

search(root,d)=>n

generation(root,d)=>a

while(n==NULL)

{

print“此人不存在,请重新输入!

inputd

search(root,d)

}

if(n->child==NULL)

{

print“输入孩子的姓名及性别:

inputb,c

a+1=>a

search(root,b)=>m

if(m!

=NULL)

print“出现重名,添加失败!

else

{

(treenode*)malloc(sizeof(treenode))=>n->child

NULL=>n->child->brother

NULL=>n->child->child

children(n->child,b,c,a)

print“家谱成员添加成功!

}

else

{

n->child=>n

while(n->brother!

=NULL)

{

n->brother=>n

print“输入孩子的姓名及性别:

inputb,c

a+1=>a

search(root,b)=>m

if(m!

=NULL)

print“出现重名,添加失败!

else

{

(treenode*)malloc(sizeof(treenode))=>t

children(t,b,c,a)

NULL=>t->brother

NULL=>t->child

t=>n->brother

print“家谱成员添加成功!

}

}

}

end

(3)查找函数伪码。

begin

print“输入要查找人姓名:

inputd

search(root,d)=>n

while(n==NULL)

{

print“此人不存在,请重新输入姓名:

inputd

search(root,d)=>n

}

output(n)

end

(4)修改函数伪码。

begin

print“输入要修改人的姓名:

inputa

search(root,a)=>n

while(n==NULL)

{

print“此人不存在,请重新输入姓名:

inputa

search(root,a)=>n

}

inputr,c

0=>i

while(i

{

r[i]=>r->l.name[i]

i+1=>i

}

c=>n->l.sex

print“家谱成员信息修改成功!

end

3.3测试与分析

3.3.1测试

1.开始

进入菜单选择界面

2.运行过程

(1)当输入信息正确时

初始化(创立)一个家谱

 

添加家族成员

查找家族成员信息

修改家族成员信息

查找修改的成员信息

(2)当输入错误信息时,系统做出提示,请求重新输入成员信息

 

添加输入错误信息时

查找输入错误信息时

修改输入错误信息时

查找修改人原名,系统提示不存在

3.结束

退出系统

3.3.2分析

从算法的设计、效率以及实用性上来说:

总的来讲,设计不是很严谨,实际生活中的人类家族族谱是有配偶信息的,而且个人信息中不但包含姓名、性别、双亲、子女,还应该有出生日期、死亡日期、籍贯等信息的。

可是在本程序中,大部分信息没有记录族谱中,这是本设计的缺陷所在,故实用性并不高。

可是,本设计也有其优点所在,就是有错误信息提示,不论是在添加成员信息,还是查找、修改成员信息时,当输入姓名不存在时,系统会给出错误信息提示,要求重新输入此人姓名。

另外,本程序设计了指针搜索函数,便于搜索孩子和双亲信息

从改进设想上:

本程序设计的设计思想是很简单的,为了能够将家族成员信息记录全面,在存放个人信息的结构体中添加一部分信息,比如此人的出生日期、死亡日期、籍贯等,在存放各代人信息时,添加一个结构体类型的变量,用于存放配偶的信息,以便实现对此人配偶信息的存储,提高实用性。

3.4代码

#include

#include

#include

#include

#defineMAX10

typedefstructnode//定义data存储结构,存放个人信息

{

charname[MAX];//姓名

charsex;//性别

intgeneration;//代

}node;

typedefstructtreenode//创立结构体

{

structnodel;//家谱中直系家属

structtreenode*brother;//用来指向兄弟

structtreenode*child;//用来指向孩子

}treenode;

treenode*root;//root是指向结构体treenode的指针

treenode*search(treenode*p,charch[])//搜索指针函数,搜索需要修改和获得的结点,输入头指针,姓名

{

treenode*q;

if(p==NULL)returnNULL;//没有家谱,头指针下为空

if(strcmpi(p->l.name,ch)==0)//比较姓名,看是否重名或是否存在

returnp;//家谱不为空,头指针下有这个人

if(p->brother)

{

q=search(p->brother,ch);//在兄弟中找

if(q)

returnq;//找到

}

if(p->child)

{

q=search(p->child,ch);//在孩子中找

if(q!

=NULL)

returnq;//找到

}

returnNULL;//没有找到

}

treenode*parent(treenode*p,treenode*q,int*flag)//搜索双亲的指针函数,经过parent函数得到双亲结点。

用flag标志,-1为左孩子,1为右孩子

{

if(p==NULL)returnNULL;//没有家谱,头指针下为空

if(p->child==NULL)

{

flag=0;

returnNULL;

}

else

{

if(p->brother==q)

{

*flag=1;

returnp;

}

else

{

if(p->child==q)

{

*flag=-1;

returnp;

}

else

{

if(p->brother!

=NULL)

{

parent(p->brother,q,*&flag);

}

if(p->child!

=NULL)

{

parent(p->child,q,*&flag);

}

}

}

}

returnp;

}

intgeneration(treenode*p,charch[])//获得搜索到的成员的代的返回值

{

treenode*q;

if(p==NULL)return0;

if(strcmpi(p->l.name,ch)==0)//比较姓名,看是否重名或是否存在

returnp->l.generation;//家谱不为空,头指针下有这个人

if(p->brother)

{

q=search(p->brother,ch);//在兄弟中找

if(q)

returnq->l.generation;//找到

}

if(p->child)

{

q=search(p->child,ch);//在孩子中找

if(q!

=NULL)

returnq->l.generation;//找到

}

return0;

}

voidchildren(treenode*p,charb[],charc,intd)//建立家谱孩子结点,创立结点并对l赋值保存

{

inti;

for(i=0;i

p->l.name[i]=b[i];

p->l.sex=c;

p->l.generation=d;

}

voidoutput(treenode*n)//搜索到数据的输出

{

treenode*t=NULL;

printf("此人姓名:

%s性别%c为第%d代\n",n->l.name,n->l.sex,n->l.generation);

printf("\n");

printf("此人的子女:

");//子女输出

if(n->child==NULL)

{

printf("此人无子女!

");

}

else

{

if(n->child->brother==NULL)

{

printf("姓名:

%s性别:

%c\t",n->child->l.name,n->child->l.sex);

}

else

{

printf("姓名:

%s性别:

%c\t",n->child->l.name,n->child->l.sex);

t=n->child->brother;

while(t!

=NULL)

{

printf("姓名:

%s性别:

%c\t",t->l.name,t->l.sex);

t=t->brother;

}

}

}

printf("\n");

printf("此人的同辈成员:

");//同辈输出

if(n->brother==NULL)

{

printf("此人无同辈成员!

");

}

else

{

if(n->brother->brother==NULL)

{

printf("姓名:

%s性别:

%c\t",n->brother->l.name,n->brother->l.sex);

}

else

{

printf("姓名:

%s性别:

%c\t",n->brother->l.name,n->brother->l.sex);

t=n->brother->brother;

while(t!

=NULL)

{

printf("姓名:

%s性别:

%c\t",t->l.name,t->l.sex);

t=t->brother;

}

}

}

}

voidInitTree()//初始化(创立)

{

charb[MAX],c;

inta;

printf("请输入始祖的姓名性别:

");

free(root);//释放root(ft)空间

root=(treenode*)malloc(sizeof(treenode));//创立一个treenode结构体大小的空间

//然后强制转换为treenode*类型的指针然后赋值给root

scanf("%s%c",&b,&c);//输入姓名,性别

a=1;

root->child=NULL;//清空左右孩子

root->brother=NULL;

children(root,b,c,a);//存入结构

printf("家谱初始化成功!

\n");

}

voidAdd()//添加

{

treenode*n,*m,*t=NULL;

charb[MAX],c,d[MAX];

inta;

printf("请输入要添加子女的上一辈的姓名:

");

scanf("%s",&d);

n=search(root,d);

a=generation(root,d);

while(n==NULL)//判断是否有重名

{

printf("此人不在家谱内,请重新输入姓名:

");

scanf("%s",&d);

n=search(root,d);

}

if(n->child==NULL)//孩子信息添加

{

printf("孩子姓名与性别输入:

");

scanf("%s%c",&b,&c);

a++;

m=search(root,b);

if(m!

=NULL)

{

printf("出现重名,添加失败!

\n");

}

else

{

n->child=(treenode*)malloc(sizeof(treenode));

n->child->brother=NULL;

n->child->child=NULL;

children(n->child,b,c,a);

printf("添加成功!

\n");

}

}

else

{

n=n->child;

while(n->brother!

=NULL)//添加另一个孩子

n=n->brother;

printf("孩子姓名与性别输入:

");

scanf("%s%c",&b,&c);

a++;

m=search(root,b);

if(m!

=NULL)

printf("出现重名,添加失败!

\n");

else

{

t=(treenode*)malloc(sizeof(treenode));

children(t,b,c,a);

t->brother=NULL;

t->child=NULL;

n->brother=t;

printf("添加成功!

\n");

}

}

}

voidSearch()//查找

{

treenode*n;

chard[MAX];

printf("输入姓名,查找相关信息:

");

scanf("%s",&d);

n=search(root,d);

while(n==NULL)

{

printf("此人不存在,请再次输入:

");

scanf("%s",&d);

n=search(root,d);

}

output(n);

printf("\n");

}

voidChange()//修改

{

chara[MAX],r[MAX],c;

treenode*n;

inti;

printf("请输入要修改人的姓名:

");

scanf("%s",&a);

n=search(root,a);

while(n==NULL)

{

printf("此人不存在,请重新输入姓名:

");

scanf("%s",&a);

n=search(root,a);

}

printf("此人存在,请输入新信息:

");

scanf("%s%c",&r,&c);

for(i=0;i

n->l.name[i]=r[i];

n->l.sex=c;

printf("修改成功!

\n");

}

intmain()

{

intchoice;

for(;;)

{

system("pause");

printf("请选择对家谱的操作:

\n");

printf("1.初始化(创立)\n");

printf("2.添加\n");

printf("3.查找\n");

printf("4.修改\n");

printf("5.退出\n");

scanf("%d",&choice);

switch(choice)

{

case1:

InitTree();break;//初始化

case2:

Add();break;//添加

case3:

Search();break;//查找

case4:

Change();break;//修改

case5:

exit(0);break;//退出

}

}

return0;

}

4总结与展望

在这次项目设计过程中遇到过一些问题,但经过不懈努力,解决了部分,还有的现在不能解决,留待日后思考和解决。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 材料科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1