数据结构家谱管理系统报告书

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据结构大作业说明文档

一、题目的选择

这次数据结构的大作业,我的选题是家谱管理系统的设计与实现。由于平时疏于编程——针对我得个人实际——我把主要的目标定位在完成家谱管理系统得基本要求。(基本要求大纲中有,就不浪费版面了)

二、设计的思路

接到这个题目,我的总体设计思路是先为程序搭建好一个结构框架,再跟据时间的宽裕程度和其它的要求逐步增强程序的性能。

关于IO的设计:

考虑到题目要求家谱信息以树形的形式一次读入内存,而个人的各种资料现在虽然条目不多,但随着程序的升级,以后可能变得越来越大。我把树形结构和个人信息记录的文档分为两个文件保存在外存中,一个文件串行化地记录家谱树的结构信息,保存少量个人信息作为识别标志;另一个文件保存完整的个人信息,所有的个人信息以线性记录的方式记录在其中。当程序运行要读入家谱结构时,只读入保存少量记录的文件并建立起树形结构。索引时,以树形中的少量信息为依据在另一个文件中找到全部的各人信息资料。

这样的好处主要有两点:

1. 由于树形结构是串行化记录于外存,一个节点记录多次,信息大量冗余,如果树形节点中保留全部信息,必将造成大量的空间浪费;只保存作为索引的少量信息在树形结构中,节约了空间。

2. 由于结构的精简,在家谱初始化时读入内存需要的时间相应减少,节约了装载时间。

这样做存在的问题:

每次执行修改,添加,删除,查询时都要直接访问外存来取得或写入数据。内外存访问上的巨大时间差的存在,使得进行这些操作相对来说并不显得很高效。

关于树形的结构:

在树形结构的选择上,根据实际中多子女的现象选择一般树,考虑到家谱中成员可能存在的不定成员数问题,抛弃了以数组为基础的一般树方案,决定用链表来实现。

树形结构的外存保存。为了提高效率,树形结构在程序初始化时由外存文件一次读入内存,此后不管插入还是修改,删除都不再对外存的树结构保存文件进行操作,只在内存中处理,程序退出时对外存树结构文件进行一次更新。也就是说,不管在程序运行中中对家谱结构进行多少种,多少次的操作,外存的树结构文件始终只会被程序访问两次。

关于功能的设计(以基本要求为准):

1.插入:用户按提示输入资料,在树形中插入节点,在个人完整记录文

件中添加插入人的所有信息并保存。

2.删除:用户输入被删除人的识别关键字(即名字),在树形结构中删

除此人,在个人记录文件中不处理。

3.修改:用户输入被删除任的识别关键字(即名字),从个人完整记录

文件中读出该人所有信息供用户进行修改,然后写回。

4.查询:完成了关键字查找部分和关系查找部分,读出个人全部信息并

显示。

关于个人资料单元:

由于树形节点要涉及到大量的逻辑操作,要用到一些运算符的重载,个人资料在树形单元定义为class类,而写入文件的单元存萃是数据,定义为简单的struct 类。

定义为struct和class类,使得不管是树形结构插入删除还是IO都是对整个结构体进行的操作,这样,如果要往结构体中添加若干个新信息条目或取消一些不必要的信息条目,需要修改的代码非常之少,方便了以后的升级。

三、程序源/头文件及主要类的说明

程序包含六个文件。一个源文件:test.cpp ;五个头文件:GTNode.h 、GTree.h 、IOMan.h 、LList.h Link.h 。

GTNode.h 头文件的说明:

文件中有GTNode模板类的定义和说明,GTNode类是一般树的节点类,类中的私有变量包含一个待定义的数据变量,一个最左孩子指针,一个右兄弟指针,一个父指针。类中公有成员函数的作用主要是对四个私有成员进行返值和置值,此外还包括一个叶子节点的判断函数。

GTree.h 头文件的说明:

文件中有GTree 模板类的定义和说明,GTree 类是一般树类,以GTNode 类为基础进行操作。

一般树类的私有部分包括两个私有变量:树的根指针和整型的当前树的节点个数记录。另外还有三个私有辅助函数:析构辅助函数,打印辅助函数和查找辅助函数。这三个函数都是用递归的方式访问整棵树来完成打印,查找和树的析构。

一般树的公有部分重定义了构造和析构函数,定义了以私有的辅助查找函数为基础的对外的查找函数,定义了节点插入函数,节点删除函数和返回值节点个数记录的求树节点个数的函数。

List.h 头文件的说明:

文件中定义并说明了模板类List 类,这是程序中最简单的一个类,类中只有公有部分,包含一个待定义的数据变量,一个指向下一个节点的指针,和两个构造函数。

LList.h 头文件的说明:

文件中定义并说明了模板类LList 类,这是一个但链表类,这个类主要是我以数据结构教材中了LList 类为范本,进行一些细部的修改,并添加了一些成员函数后形成。

LList 类的私有部分包含了一个待定义的数据,头、尾和“栅栏”三个指,两个分别辅助构造与析构的函数。

LList 类的公有部分我根据需要添加了一个删除最后一个节点的函数,其它部分与教材中基本一致。

IOMan.h 头文件的说明:

IOMan.h 头文件是本程序中最大的一个头文件,其它四个头文件都是这个文件的支持。其中包含了两个类,一个结构:一个一般树节点类,一个IOMan类,一个个人记录文件模块化写入读出的结构。

这里重点介绍一下处理文件,树,输入输出的IOMan 类,这个类也是本程序的核心所在。

IOMan 类的私有部分包含一个树,一个链表和一个写入辅助函数。树是用来存放家谱中关系的结构;链表主要用来辅助输入,输出;写入辅助函数在链表的帮助下完成串型化地把树的结构写入外存保存树结构的文档中。

IOMan类的公有部分包含六个函数:构造函数,析构函数,家谱添加函数,删除函数,修改函数和查找函数。构造函数处理完成家族树的建树任务,析构函数同时完成家族树的写入外存保存,其它四个函数处理用户输入输出的同时也对外部文件进行更新。

test.cpp源文件的说明:

该文件中包含了main 函数。在main 函数中,如果没有记录文件,则完成记录文件的创建,否则,完成记录文件的打开。同时,main 函数还提供初始化的用户面板供用户进行操作。

四、主要函数的说明:

这次的大作业,我在程序中总共新写了(原创)五个类和二十多个较复杂的函数。其中的大部在源文件中都有较好的注释或用了比较常规的手法,在这里就不多加说明了,现在介绍的主要是比较特别的几个函数。

IOMan::IOMan ( ) 构造函数。这个构造函数的逻辑流程是:先打开线型化保存树形结构的文件,如果打开成功则继续后续操作,否则退出程序。在打开结构文件成功的情况下,模块化以树节点大小为单位逐个读入保存在结构文件中的内容,并用两个指针变量记录当前和上次读入的节点,如果当前读入节点在树中存在,则更新上次记录指针为当前记录指针值,如果读入节点不存在,则把当前读入的节点值作为上次记录节点的孩子插入结构树中,最后读完整个结构记录文件后,关闭该文件。

IOMan::~IOMan ( ) 析构函数。该函数主要完成树结构的写入保存工作。函数流程是:先打开保存树结构的文件,如打开失败则提示用户无法保存信息,否则调用辅助函数writeHelp ( ) 把树的结构写入结构保存文件。writeHelp ( ) 函数的写入规则是:遇到中间节点,往链表中添加该节点,先递归访问它的最左孩子,

相关文档
最新文档