C++语言实现的族谱管理系统

文章描述了一个基于文本文件的蒙古帝国族谱管理系统的设计,采用树形结构存储数据,包括Person类的详细设计,如姓名、生卒年、亲属关系等属性。系统支持初始化、显示、添加、修改、删除成员以及多种查询功能。通过兄弟孩子链式存储结构实现成员的增删改查,并提供了相应的算法实现。此外,文章还包含了测试用例和程序运行结果,展示了系统操作的实例。
摘要由CSDN通过智能技术生成

1. 课题简介和设计要求

孛儿只斤●铁木真(1162年5月31 日-1227年8月25日) ,蒙古帝国可汗,尊号“成吉思汗”意为“拥有海洋四方”。世界史上杰出的政治家、军事家。1206年春天建立大蒙古国.此后多次发动对外征服战争,征服地域西达中亚、东欧的黑海海滨。1227年在征伐西夏的时候去世,之后被密葬。除了一生征战,亦创建蒙古文字、颁布文法、采取开明的宗教政策,是一位在历史上具有颇多争议的枭雄。其后代传承对普通百姓而言,扑朔迷离.....

现在需要设计一个族谱管理系统,使用户能够方便地维护和查询族谱信息

2. 总体设计

根据需求,我设计出以下系统功能:

初始化系统:读取族谱数据文件(txt文件),建立初始族谱。族谱数据文件预先手工建立。

显示族谱:输出族谱。

添加成员:提示输入成员信息,在族谱中添加成员。

修改成员提示输入成员姓名,修改成员信息。

删除成员:提示输入成员姓名,Y从族谱中删除成员。

查询:根据指定条件查询数据并输出。

保存:保存当前族谱数据到文件(txt文件)。

退出:退出系统。

为了实现这些功能,我设计了以下功能菜单:

系统功能模块图如下:

输入5查找时,会有如图所示五种查找方式可选择,界面如下:

 

3. 详细设计

对详细设计的过程进行介绍,包括:

3.1 结点类型的设计

为了表示族谱信息,我设计了一个Person类,该类包含以下数据项:

姓名:表示该人的姓名。

生年:表示该人的出生年份

卒年:表示该人的死亡年份

父亲:表示该人的父亲,使用一个Person指针表示

孩子:表示该人年龄最小的孩子,使用一个Person指针表示

兄长:表示该人年龄最小的兄长,使用一个Person指针表示。

 

3.2 采用的逻辑结构

为了满足系统功能的设计要求,我考虑使用树形结构来存储族谱信息。树形结构的每个节点表示一个人,边表示父子关系。这样就可以方便地查询某个人的父亲、孩子等信息。

3.3 采用的存储结构

我选择使用兄弟孩子链式存储结构来实现树形结构。在Person类中定义一个children指针,表示该结点的孩子结点。同时,在Person类中定义一个siblings指针,表示该节点的兄弟节点,并且,为了便于查询该结点的父亲,还定义了一个father指针,表示该结点的父亲。

存储结构示意图:

 

代码:

 

3.4 相关算法

为了实现系统的功能,需要设计哪些相关的算法,给出这些算法的思想和处理流程图。

  • 初始化系统:读取族谱数据文件(txt文件),建立初始族谱。族谱数据文件预先手工建立。

为了实现这个功能,我定义了一个全局函数impotData,首先使用getline函数读取一行的数据,再将这一行数据根据空格拆分输出到name birth death father四个变量中,然后调用添加函数,将结点添加到树中

 

  • 显示族谱:输出族谱。

由于children指针指向年龄最小的那个孩子,考虑到需要长幼有序进行输出,年长的一般先输出,所以需要先输出当前人的兄长的信息,然后输出当前人的信息,最后输出当前人的子女的信息。代码如下:

 

参数person指向要输出家谱树的人,参数indentation表示这个人在家谱树中的层级,每个层级输出信息前需要先输出一个tab。

首先使用了一个if语句来判断传入的参数是否为空,如果为空,就返回。

然后递归调用自身函数,并将当前人的兄弟作为参数,层级不变。这样就会先输出所有兄弟的信息。

然后,使用了一个for循环,在每个人的信息前输出层级个tab,表示这个人的层级。最后输出当前人的信息(名字、出生年份和死亡年份)。

最后,再次调用自身函数,并将当前人的子女作为参数,并将层级加1。这样就会输出所有子女的信息。

  • 添加成员:提示输入成员信息,在族谱中添加成员。

添加成员要注意长幼有序的问题,children指针必须指向年纪最小的孩子。代码如下:

 

 

首先使用了一个if语句来判断这个人是否已经在家谱树中。如果已经在家谱树中了,就输出一条信息。

然后创建一个新的Person对象,并将其保存在指针newPerson中。这个对象的名字、出生日期、死亡日期和父亲指针都被设置为传入的参数。

接下来,使用了一个if语句来判断新添加的人的父亲的名字是否为空。如果为空,则说明新添加的人是家谱树的根结点。如果根结点还没有被设置,则将root指针设置为新创建的Person对象。

否则,就说明新添加的人有一个父亲。那么就使用函数findPerson来查找这个父亲所在的节点,并将查找到的父亲节点保存在指针parent中。

接下来,如果这个父亲没有子女(即parent->children为空指针),则新添加的人成为这个父亲的第一个子女。否则,就需要考虑将新添加的人按照出生日期的顺序插入到父亲的子女链表中。年龄大的在前面,年龄小的在后面。

为了找到新添加的人应该插入的位置,使用一个while循环和一个临时变量temp。每次循环中,都会将temp指向父亲的子女链表中的下一个节点。然后比较这个节点的出生日期和新添加的人的出生日期。如果新添加的人的出生日期比这个节点的出生日期小,则继续循环;否则,就找到了新添加的人应该插入的位置。

最后,将新添加的人插入到这个位置。

  • 修改成员提示输入成员姓名,修改成员信息。

需要实现的功能为:首先输入需要修改的成员的姓名 Oname,如果成员不存在,则输出 "查无此人"。如果存在,则输入需要修改的信息,输入birth修改生年,输入death修改卒年。代码如下:

还需要注意的是,如果是 "birth",需要判断生年是否大于当前节点的卒年,如果是 "death",则判断生年是否小于当前节点的卒年。代码如下:

 

 

  • 删除成员:提示输入成员姓名,Y从族谱中删除成员。

输入成员姓名时,如果不存在该成员,就会提示”查无此人“,并且为了避免误删,删除时需要输入Y确认后才会进行删除操作。

删除成员时,如果这个人有孩子,则孩子也需要全部删除。删除铁木真时,整个族谱都会被删除。

代码如下:

 

 

current:指向当前结点的指针,parent:指向当前结点的父亲结点的指针,name:表示要删除的人的名字

首先,如果当前结点current 为空,则直接返回。

如果不为空,则先检查当前结点的名字是不是要删除的人的名字,如果不是则先到当前结点的孩子里查找,然后再到兄弟里查找。

直到当前结点就是要删除的结点。然后判断这个结点是不是根结点,如果是直接将根结点置为空就可以。否则,则需要先找到指向这个结点的指针。

这里有两种情况,一是要删的人是其父亲最小的孩子,此时让父亲的children指针指向要删结点的兄弟结点就好了。

如果不是最小的孩子,则需要先找到指向待删的人的指针temp,然后让temp的兄弟指针指向待删的人的兄弟指针就可以了。

  • 查询:根据指定条件查询数据并输出。

按姓名查找:

从根结点开始,先查看当前结点是不是要找的成员,然后递归地到孩子和兄弟里查找。代码如下:

按代查找成员:

person:指向当前结点的指针,generation:要搜索的代数,current:当前结点的代数

如果当前结点为空,则直接返回。如果当前结点的代数已经大于要搜索的代数,也直接返回。否则,如果当前结点的代数等于要搜索的代数,则输出当前结点的名字。接下来,递归地去兄弟和孩子中查找代数为generation的结点。以当前结点的子结点为根结点搜索时,代数要加1,以当前结点的兄弟结点为根结点搜索时,代数不变。代码如下:

 

 

查询孩子:

输入某人名字,输出这个人的所有孩子。

首先需要检查这个人是否存在,不存在需要提示此人不存在。

如果这个人存在,先定义一个指针child指向此人的最小的孩子,将其输出,如果他最小的孩子有兄长,则再将其兄长也输出,直到输出所有兄长为止。

查询父亲:

首先输入名字,一样的需要先判断此人是否存在,再判断此人的父亲是否存在,如果存在直接输出其父亲的名字就好了。

 

查询兄弟:

输入姓名,输出此人的所有兄弟。

只需要先找到此人的父亲,然后除了此人外,输出父亲的最小的孩子children和children的所有兄长即可。

 

  • 保存:保存当前族谱数据到文件(txt文件)。

首先写入当前结点信息,然后再递归地写入当前结点的所有兄长的信息,最后再写入当前结点的孩子结点的信息。

这样可以有效地避免父亲还没有写入文件,就先写入了孩子的情况。代码如下:

  • 退出:退出系统。

输出感谢使用再见后退出while循环,代码如下:

 

 

4. 编码设计

对已经确定采用的存储结构准备设计哪些类,对涉及到的每一个类给出以下内容:

  • 类名

Person类,FamilyTree类

  • 数据成员的定义

Person类:

姓名:表示该人的姓名。

生年:表示该人的出生年份

卒年:表示该人的死亡年份

父亲:表示该人的父亲,使用一个Person指针表示

孩子:表示该人年龄最小的孩子,使用一个Person指针表示

兄长:表示该人年龄最小的兄长,使用一个Person指针表示。

 

FamilyTree类:

表示家谱的根结点

Person *root; // 家谱的根结点

  • 成员函数的设计

具体代码及实现如上述3.4

FamilyTree类:

 

Person类:

分别为构造函数和输出打印函数

测试

5.1 测试用例

  1. 添加成员测试用例:

(1)姓名:斡儿答 1204 1280 术赤

(2)姓名:阔端 1206 1251 窝阔台

  1. 修改成员测试用例:

(1)姓名:扯忽

(2)姓名:旭烈兀 修改生年为:1214

(3)姓名:旭烈兀 修改卒年为:1210

3:删除成员测试用例:

(1)姓名:扯忽

(2)姓名:忽察

(3)姓名:旭烈兀

(4)姓名:铁木真

4:查询测试用例:

(1)按姓名查询:扯忽,忽必烈

(2)按代查询:1,7,3,9

(3)查询孩子:扯忽,拖雷

(4)查询父亲:扯忽,明理帖木儿

(5)查询兄弟:扯忽,忙哥剌

5.2 程序运行结果

1、显示族谱

  • 添加成员

 

  • 修改成员

 

  • 删除成员
  •  

 

删除前:

删除后:

 

 

 

  • 查找成员

不保存,回到初始化的状态。

  • 按姓名查找成员

  

  • 按代查找成员

 

 

 

 

  • 查询孩子

 

 

  • 查询父亲

 

  • 查询兄弟

 

 

 

  • 保存

 

  • 退出系统

 

6.收获与体会

做完这个项目让我更加了解了使用孩子兄弟链表的存储方式的树的结构和操作,更加熟练地掌握了树的增删改查等操作。

在这个项目中,我也学到了如何使用文件来读取并存储家庭树信息,并对文件操作的相关知识掌握地更牢固了。

做完这个项目之后,我对自己的编码能力有了更大的信心,并且更加了解了自己的不足之处,有了进一步提高的动力。

7.参考文献

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
家谱软件是应海峡姓氏研究之约开发族谱管理软件。 该软件是最新开发和上市的族谱管理软件,经过专业人士的指导和专业团队的开发,是目前国内性价比很高的专业族谱管理软件。 该软件具有管理大家族的能力,扩充能力在千万、亿级别,适合修全国统谱。可以谱修全国各个姓氏的族谱,对管理姓氏无限制。在同一软件上可以管理本家族和其他家族的资料,例可以管理外亲等家族的同步资料。 经过近三年的专业团队开发已经具有完善的族谱管理功能,可以帮助专业的谱修人士完成建谱、调谱、出谱等复杂的工作。该软件已经经过专业人士的测试,指导,能够完成大部分人的修谱需求。 该软件采用最先进的开发技术,采用国外最强大的单机版数据库技术,具有无限扩充能力和功能完善能力,该数据库支持的是上亿级别的数据处理。其技术为微软的开发平台支持,是其他族谱软件所无法比拟的平台和技术支撑。采用微软的visual studio开发技术,该技术是微软的最先进开发技术,从微软创办至今一直完善的一个技术支撑。 单机版本,数据库为单一文件,不是其他族谱软件的一堆数据文件。该数据库文件可以自己备份管理,可以拷贝到其他机器硬盘等来备份。 该程序可以脱网来使用,不需要上网,完全属于自己的软件,放心,安全,不受任何网络和第三方的控制。 该软件是目前市场上唯一直接对树操作的族谱管理软件,可以在树世系图上任意增加族人,选择某一族人后可以增加兄弟或子女。增加族人人数无限制。使用鼠标右键操作,符合大家的操作习惯。可以任意修改族人在树上的位置,方便在填错父亲的情况下将其修改回原来在树上的位置。在树上的位置可以整个分支改挂到另外一个分支,调整族人分支很方便。适合先建族人后修改父亲等需求。 该软件一改以往修谱软件的特点,增加了输出word文档的功能,方便在打印前对出谱资料的二次修改,具有很强的可修改性。另外,可以将族人图形资料输出到word文档,和族人资料一起一并打印。可以打印输出族人的图形等可见信息。 可以在数据库内保存家族和族人的语音、视频、扫描资料等重要资料,由于保存在数据库内,所以具有保密性。家谱资料在数据库内可以删除查看,方便整个家族资料的管理和完备性。 可以将世系树的结构输出到文本文档,对于家族的分支结构在树上得到很好的诠释。由于文本文档不具有格式性, 所以可以输出无限大的世系图,可以将整个家族的世系图完整输出 。 具有输出部分世系图分支的功能,可以分段输出世系图,便于将世系图分段保存和管理。配合整个世系图和分段世系图,对于某一分支可以了解自家分支的世系全貌。 可以管理多个配偶信息,配偶信息的输出是附加在族人后面,对于家庭的完整性得到很好的体现。配偶信息资料全,可以了解配偶在自家的排行、兄弟姐妹等情况。 自定义家谱输出格式,方便输出古代的五代格式。五代输出按大排行方式输出,符合大家的排行习惯。 族人输出按照大排行的顺序输出,例子老大的儿子输出要排在老二儿子的前边, 老大的孙子输出也要排在老二孙子的前边,以此类推。 可以管理家族的历史事件,历史人物,可以任意增加历史事件和历史人物,来阐述家族曾经出得辉煌。增加的人物和事件无限制。
功能介绍】 1.该族谱管理系统一改以往修谱系统的特点,增加了输出word文档的功能,方便在打印前对出谱资料的二次修改,具有很强的可修改性。另外,可以将族人图形资料输出到word文档,和族人资料一起一并打印。可以打印输出族人的图形等可见信息。 2.可以在数据库内保存家族和族人的语音、视频、扫描资料等重要资料,由于保存在数据库内,所以具有保密性。家谱资料在数据库内可以删除查看,方便整个家族资料的管理和完备性。 3.可以将世系树的结构输出到文本文档,对于家族的分支结构在树上得到很好的诠释。由于文本文档不具有格式性, 所以可以输出无限大的世系图,可以将整个家族的世系图完整输出 。 4.具有输出部分世系图分支的功能,可以分段输出世系图,便于将世系图分段保存和管理。配合整个世系图和分段世系图,对于某一分支可以了解自家分支的世系全貌。 5.可以管理多个配偶信息,配偶信息的输出是附加在族人后面,对于家庭的完整性得到很好的体现。配偶信息资料全,可以了解配偶在自家的排行、兄弟姐妹等情况。 6.自定义家谱输出格式,方便输出古代的五代格式。五代输出按大排行方式输出,符合大家的排行习惯。 7.族人输出按照大排行的顺序输出,例子老大的儿子输出要排在老二儿子的前边, 老大的孙子输出也要排在老二孙子的前边,以此类推。 8.可以管理家族的历史事件,历史人物,可以任意增加历史事件和历史人物,来阐述家族曾经出得辉煌。增加的人物和事件无限制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值