ImageVerifierCode 换一换
格式:DOCX , 页数:28 ,大小:96.15KB ,
资源ID:8643173      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8643173.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(数据结构课程设计家族关系查询系统.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

数据结构课程设计家族关系查询系统.docx

1、数据结构课程设计家族关系查询系统1 课程设计介绍 1.1课程设计项目简介 家谱是一种以表谱形式,记载一个以血缘关系为主体的家族世系繁衍和重要人物事迹的特殊图书载体。家谱是中国特有的文化遗产,是中华民族的三大文献之一,属珍贵的人文资料,对于历史学,民俗学,人口学,社会学和经济学的深入研究,均有不可替代的重要功能。本项目对家谱管理进行简单的模拟,以实现查看祖先和子孙个人信息 、插入家族成员等功能。 1.2课设题目分析本程序的实质是完成对家谱成员信息的建立、查找、插入等功能。可以首先定义家族成员的数据结构,然后将每个功能写成一个函数来完成对数据的操作,最后完成主函数以验证各个函数功能并得出运行结果。

2、本程序包含以下几个模块(1)建立家族关系树。此模块将构建一个家族关系,对数据初始化,构造关系树并录入数据一遍后续程序使用。(2)添加新成员。此模块将添加一个新成员,实现对家族关系的修改。(3)家族关系的查询。此模块将实现对家族不同关系的查询(4)主程序模块。此模块实现整个程序的进入和进出,以及各种初始化处理。(5)1.3课程题目原理与数据结构 因为家族的成员之间存在一个对多个的层次结构关系,所以不能用线性表来表示和实现。家谱从形状上看像一颗倒长的树,所以用树结构来表示比较合适。树形结构是一类非常重要的非线性数据结构,直观看来树是以分支关系定义的层次结构。 因此本课程设计可以采用的数据结构有树状

3、结构和队列。树状结构采用三叉链表来实现,队列采用链式队列实现。1.4功能分析说明图 2 分析与实现 2.1 基本数据结构和栈队的操作2.1.1 结点基本数据结构和链队的定义/*家族关系树实现*/#include #include #include#include#include#include#include#include#define TRUE 1#define FALSE 0#define OK 1#define ERROR -1#define INFEASIBLE -1typedef char DataType;#define MAXNUM 20typedef struct TriTN

4、ode/* 树的三叉链表存储结构*/ DataType dataMAXNUM; struct TriTNode *parent;/* 双亲*/ struct TriTNode *lchild;/* 左孩子*/ struct TriTNode *rchild;/* 右孩子*/TriTree;typedef struct Node/* 队列的结点结构*/ TriTree *info; struct Node *next;Node;typedef struct/* 链接队列类型定义*/ struct Node *front; /* 头指针*/ struct Node *rear; /* 尾指针*/L

5、inkQueue;DataType fnameMAXNUM,family50MAXNUM;/* 全局变量*/2.1.2 链队的基本操作LinkQueue *LQueueCreateEmpty( )/* 建立一个空队列*/ LinkQueue *plqu=(LinkQueue *)malloc(sizeof(LinkQueue); if (plqu!=NULL) plqu-front=plqu-rear=NULL; else printf(内存不足!n); return NULL; return plqu;int LQueueIsEmpty(LinkQueue *plqu)/* 判断链接表示队列

6、是否为空队列*/ return(plqu-front=NULL);void LQueueEnQueue(LinkQueue *plqu,TriTree *x)/* 进队列*/ Node *p=(Node *)malloc(sizeof(Node); if(p=NULL) printf(内存分配失败!n); else p-info=x; p-next=NULL; if(plqu-front=NULL)/* 原来为空队*/ plqu-front=p; else plqu-rear-next=p; plqu-rear=p; int LQueueDeQueue(LinkQueue *plqu,TriT

7、ree *x)/* 出队列*/ Node *p; if(plqu-front=NULL) printf(队列空!n); return ERROR; else p=plqu-front; x=p-info; plqu-front=plqu-front-next; free(p); return OK; TriTree *LQueueGetFront(LinkQueue *plqu)/* 在非空队列中求队头元素*/ return(plqu-front-info);2.2建立家族关系2.2.1 建立家族关系并存入文件 基本思想:首先输入家族关系的名称,以此名称为文件名,建立文本文件接下来按层次输入结

8、点信息,输入一个在文件中写入一行同时将输入的信息保存 到二位字符数组family中。字符数组family是全局变量,存储临时信息 . 注意,输入时每个结点信息占一行,一个结点有多个兄弟,以“”作为兄弟结束标志,结点若无孩子,直接以“”代替。依次输入各节点信息,以“#” 作为结束标志。最后使用函数CreateTriTree建立家族关系树. TriTree *Create(DataType familynameMAXNUM)/* 建立家族关系并存入文件*/ int i=0; /* i控制family数组下标*/ DataType ch,strMAXNUM; /* ch存储输入的y或n,str存储输

9、入的字符串*/ TriTree *t; FILE *fp; strcpy(fname,familyname); /* 以家族名为文本文件名存储*/ strcat(fname,.txt); fp=fopen(fname,r); /* 以读取方式打开文件*/ if(fp) /* 文件已存在*/ fclose(fp); printf(%s 的家族关系已存在!重新建立请按“Y”,直接打开请按“N”n,familyname); ch=getchar(); getchar(); /* 接收回车*/ if(ch=N|ch=n) t=Open(familyname);/* 直接打开*/ return t; i

10、f(!fp|ch=Y|ch=y) /* 重新建立,执行以下操作*/ fp=fopen(fname,w); /* 以写入方式打开文件,不存在则新建*/ printf(请按层次输入结点,每个结点信息占一行n); printf(兄弟输入结束以“”为标志,结束标志为“#”n. ); gets(str); fputs(str,fp); fputc(n,fp); strcpy(familyi,str); /* 将成员信息存储到字符数组中*/ i+; /* family数组下标后移*/ while(str0!=#) printf(. ); /* 以点提示符提示继续输入*/ gets(str); fputs(

11、str,fp); /* 写到文件中,每个信息占一行*/ fputc(n,fp); strcpy(familyi,str);/* 将成员信息存储到字符数组中*/ i+; /* family数组下标后移*/ fclose(fp); /* 关闭文件*/ t=TriTreeCreate(); /* 根据family数组信息创建三叉树*/ printf(家族关系已成功建立!n); return t; /* 返回树*/ 2.2.2建立家族关系树基本思想:采用指针数组作为指针,保存输入的结点地址。队列的尾指针指向当前结点。头指针指向当前结点的双亲结点。输入的结点信息已存储在字符数组family中。将信息复制

12、到字符串数组“ch”中 ,如果ch不是“”,则建立一个新结点。若新结点是第一个结点,则它是根结点,将其入队,指针tree指向这个根节点;如果不是根结点,则将当前结点链接到双亲结点上,即当前结点的双亲指针就是队头元素,然后将当前结点入队列。接着判断flag的值,如果flag=0,表示当前结点没有左孩子,那么当前结点就是双亲的左孩子。否则,当前结点就是双亲的右孩子。用指针root指向刚刚入队的结点。继续复制数组family的下个元素。如果“ch” 是。则flag=0(因为“”后面的第一个孩子为左孩子),同时判断“”是否是第一次出现,如果是第一次,则令标志star=1;如果不是第一次出现。则出队列,

13、root指向队头元素(实际上root总是指向双亲结点)。继续复制family的下一个元素。知道遇到“#”结束。函数返回指针tree。 /* 建立家族关系树*/TriTree *TriTreeCreate() TriTree *t,*x=NULL,*tree,*root=NULL; LinkQueue *q=LQueueCreateEmpty();/* 建立一个空的队列,存储指向树的指针*/ int i=0,flag=0,start=0; DataType strMAXNUM; /* 存放family数组中信息*/ strcpy(str,familyi); /* 复制*/ i+; /* fami

14、ly数组下标后移*/ while(str0!=#) /* 没遇到结束标志继续循环*/ while(str0!=) /* 没遇到兄弟输入结束标志继续*/ if(root=NULL) /* 空树*/ root=(TriTree *)malloc(sizeof(TriTree);/* 申请空间*/ strcpy(root-data,str); root-parent=NULL; root-lchild=NULL; root-rchild=NULL; LQueueEnQueue(q,root); /* 将root存入队列*/ tree=root; else /* 不为空树*/ t=(TriTree *

15、)malloc(sizeof(TriTree); /* 申请空间*/ strcpy(t-data,str); t-lchild=NULL; t-rchild=NULL; t-parent=LQueueGetFront(q); /* 当前结点的双亲为队头元素*/ LQueueEnQueue(q,t); /* 入队*/ if(!flag) /* flag为,当前结点没有左孩子*/ root-lchild=t; else /* flag为,当前结点已有左孩子*/ root-rchild=t; root=t; /* root指向新的结点t */ flag=1; /* 标记当前结点已有左孩子*/ str

16、cpy(str,familyi); i+; if(start!=0) /* 标记不是第一次出现“”*/ LQueueDeQueue(q,x); /* 出队*/ if(q-front!=NULL) root=LQueueGetFront(q);/* root为队头元素*/ start=1; /* 标记已出现过“”*/ flag=0; /* “”后面的结点一定为左孩子*/ strcpy(str,familyi); i+; return tree; /* 返回树*/2.3打开一个家族关系 首先输入家族关系名,以家族名为文件名打开文件,如果家族关系不存在,返回空;如果存在,文件打开,读取文件。将文件的

17、每行信息依次存储在数组family【】中。/* 打开一个家族关系*/TriTree *Open(DataType familynameMAXNUM) int i=0,j=0; DataType ch; FILE *fp; TriTree *t; strcpy(fname,familyname); /* 以家族名为文本文件名存储*/ strcat(fname,.txt); fp=fopen(fname,r); /* 以读取方式打开文件*/ if(fp=NULL) /* 文件不存在*/ printf(%s 的家族关系不存在!n,familyname); return NULL; else ch=f

18、getc(fp); /* 按字符读取文件*/ while(ch!=EOF) /* 读到文件尾结束*/ if(ch!=n) /* ch不为一个结点信息的结尾*/ familyij=ch; /* 将文件信息存储到family数组中*/ j+; else familyij=0; /* 字符串结束标志*/ i+; /* family数组行下标后移*/ j=0; /* family数组列下标归零*/ ch=fgetc(fp); /* 继续读取文件信息*/ fclose(fp); /* 关闭文件*/ t=TriTreeCreate(family); /* 调用函数建立三叉链表*/ printf(家族关系已

19、成功打开!n); return t; 2.4在家族关系中查找一个成员是否存在用递归算法实现。如果树空,返回NULL。如果根节点就是要查找的成员,返回根节点;否则,递归查找它的左右子树。/* 查找一个成员是否存在*/TriTree *Search(TriTree *t,DataType str) TriTree *temp; if(t=NULL) /* 如果树空则返回NULL */ return NULL; else if(strcmp(t-data,str)=0) /* 如果找到返回该成员指针*/ return t; else /* 如果没找到遍历左右子树进行查找*/ temp=Search(

20、t-lchild,str); /* 递归查找*/ if(temp) /* 结点不空则查找*/ return(Search(t-lchild,str); else return(Search(t-rchild,str); 2.5 向家族中添加一个新成员基本思想:添加的新成员要根据其双亲确定其在家族中的位置。首先判断该双亲是否在此家族关系中,若存在则查找其双亲,将新结点插入其双亲的最后一个孩子之后;若没有孩子,则直接作为左孩子插入。以写入的方式打开文件,如果成功打开,则更新family数组中的信息,并查找新成员的双亲所在位置和其对应的“”个数,如果“”个数小于双亲位置,则添加“”实质相等,新成员不

21、插入到最后“”之前。最后将family数组中信息写入文件保存,关闭文件。/* 添加一个新成员*/void Append(TriTree *t) int i=0,j,parpos=1,curpos,num,end=0,count=-1; DataType chiMAXNUM,parMAXNUM;/* 存储输入的孩子和其双亲结点*/ TriTree *tpar,*temp; FILE *fp; printf(请输入要添加的成员和其父亲,以回车分隔!n. ); gets(chi); printf(. ); /* 以点提示符提示继续输入*/ gets(par); tpar=Search(t,par);

22、 /* 查找双亲结点是否存在*/ if(!tpar) printf(%s 该成员不存在!n); else /* 存在则添加其孩子*/ temp=(TriTree *)malloc(sizeof(TriTree);/* 申请空间*/ temp-parent=tpar; strcpy(temp-data,chi); temp-lchild=NULL; /* 新结点左右孩子置空*/ temp-rchild=NULL; if(tpar-lchild) /* 成员存在左孩子*/ tpar=tpar-lchild; /* 遍历当前成员左孩子的右子树*/ while(tpar-rchild) /* 当前结点

23、右孩子存在*/ tpar=tpar-rchild; /* 继续遍历右孩子*/ tpar-rchild=temp; /* 将新结点添加到所有孩子之后*/ else /* 没有孩子则直接添加*/ tpar-lchild=temp; fp=fopen(fname,w); /* 以写入方式打开文件*/ if(fp) while(strcmp(par,familyi)!=0&familyi0!=#) if(familyi0!=) /* 查找双亲在数组中位置*/ parpos+; /* parpos计数*/ i+; /* family数组行下标后移*/ i=0; /* family数组行下标归*/ whi

24、le(familyi0!=#) if(familyi0=) /* 查找“”的个数,第一个不计*/ count+; /* count累加个数*/ if(count=parpos) /* 说明此“”与其前一个“”之前为par的孩子*/ curpos=i; /* curpos计当前位置*/ i+; /* family数组行下标后移*/ if(countparpos) /* “”数小于parpos数*/ num=parpos-count; /* 添加“”个数为num */ for(j=i;j=curpos;j-) /* 当前位置到数组最后的全部信息后移一行*/ strcpy(familyj+1,fam

25、ilyj); strcpy(familycurpos,chi); /* 将新结点存储到“”的前一行*/ if(end=1) /* 若end为,则数组末尾下标后移num位*/ i=i+num; for(j=0;jdata);2.6.2 查找一个成员的所有祖先路径查找一个成员的所有祖先路径,需要从它的双亲一直向上查找到根结点。基本思想:对与结点t,先判断它是否是根结点(根节点的双亲是NULL),如果是根结点,直接输出它本身;如果不是,查找它的双亲指针指向的结点,将双亲信息输出。继续查找,直到找到根结点。/* 查找一个成员的所有祖先*/void AncesstorPath(TriTree *t) i

26、f(t-parent=NULL) /* 若该成员为祖先,则直接输出*/ printf(%s 无祖先!n,t-data); else /* 否则继续查找祖先*/ printf(%s 所有祖先路径:%s,t-data,t-data); while(t-parent!=NULL)/* 若当前成员的双亲不是祖先,则继续查找*/ printf( - %s,t-parent-data); /* 访问当前成员的双亲*/ t=t-parent; /* 继续循环查找*/ printf(n); 2.6.3 查找一个成员的双亲基本思想:先判断结点t是否是根结点,过不是根结点,直接输出该结点双亲指针的结点信息;若是根结点,输出提示信息,结点无双亲。/* 查找一个成员的双亲*/void Parent(TriTree *t)

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

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