《2020年整理数据结构课程设计(家族关系查询系统).doc》由会员分享,可在线阅读,更多相关《2020年整理数据结构课程设计(家族关系查询系统).doc(28页珍藏版)》请在金锄头文库上搜索。
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 FALS
4、E 0#define OK 1#define ERROR -1#define INFEASIBLE -1typedef char DataType;#define MAXNUM 20typedef struct TriTNode/* 树的三叉链表存储结构*/ DataType dataMAXNUM;struct TriTNode *parent;/* 双亲*/struct TriTNode *lchild;/* 左孩子*/struct TriTNode *rchild;/* 右孩子*/TriTree;typedef struct Node/* 队列的结点结构*/ TriTree *info;
5、struct Node *next;Node;typedef struct/* 链接队列类型定义*/ struct Node *front; /* 头指针*/ struct Node *rear; /* 尾指针*/LinkQueue;DataType fnameMAXNUM,family50MAXNUM;/* 全局变量*/2.1.2 链队的基本操作LinkQueue *LQueueCreateEmpty( )/* 建立一个空队列*/ LinkQueue *plqu=(LinkQueue *)malloc(sizeof(LinkQueue); if (plqu!=NULL) plqu-front
6、=plqu-rear=NULL; elseprintf(内存不足!n);return NULL; return plqu;int LQueueIsEmpty(LinkQueue *plqu)/* 判断链接表示队列是否为空队列*/ 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-fron
7、t=NULL)/* 原来为空队*/ plqu-front=p; else plqu-rear-next=p; plqu-rear=p; int LQueueDeQueue(LinkQueue *plqu,TriTree *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)/* 在非空队
8、列中求队头元素*/ return(plqu-front-info);2.2建立家族关系2.2.1 建立家族关系并存入文件 基本思想:首先输入家族关系的名称,以此名称为文件名,建立文本文件接下来按层次输入结点信息,输入一个在文件中写入一行同时将输入的信息保存 到二位字符数组family中。字符数组family是全局变量,存储临时信息 . 注意,输入时每个结点信息占一行,一个结点有多个兄弟,以“”作为兄弟结束标志,结点若无孩子,直接以“”代替。依次输入各节点信息,以“#” 作为结束标志。最后使用函数CreateTriTree建立家族关系树.lixianliguoyu liguojun liguoq
9、iangliyongzhi liyongrui liyongmingliwende liwenjia TriTree *Create(DataType familynameMAXNUM)/* 建立家族关系并存入文件*/int i=0; /* i控制family数组下标*/DataType ch,strMAXNUM; /* ch存储输入的y或n,str存储输入的字符串*/TriTree *t;FILE *fp;strcpy(fname,familyname); /* 以家族名为文本文件名存储*/strcat(fname,.txt);fp=fopen(fname,r); /* 以读取方式打开文件*
10、/ if(fp) /* 文件已存在*/fclose(fp);printf(%s 的家族关系已存在!重新建立请按“Y”,直接打开请按“N”n,familyname);ch=getchar();getchar(); /* 接收回车*/if(ch=N|ch=n)t=Open(familyname);/* 直接打开*/return t;if(!fp|ch=Y|ch=y) /* 重新建立,执行以下操作*/fp=fopen(fname,w); /* 以写入方式打开文件,不存在则新建*/printf(请按层次输入结点,每个结点信息占一行n);printf(兄弟输入结束以“”为标志,结束标志为“#”n. );
11、gets(str);fputs(str,fp);fputc(n,fp);strcpy(familyi,str); /* 将成员信息存储到字符数组中*/i+; /* family数组下标后移*/while(str0!=#) printf(. ); /* 以点提示符提示继续输入*/gets(str);fputs(str,fp); /* 写到文件中,每个信息占一行*/fputc(n,fp);strcpy(familyi,str);/* 将成员信息存储到字符数组中*/i+; /* family数组下标后移*/fclose(fp); /* 关闭文件*/t=TriTreeCreate(); /* 根据fa
12、mily数组信息创建三叉树*/printf(家族关系已成功建立!n);return t; /* 返回树*/2.2.2建立家族关系树基本思想:采用指针数组作为指针,保存输入的结点地址。队列的尾指针指向当前结点。头指针指向当前结点的双亲结点。输入的结点信息已存储在字符数组family中。将信息复制到字符串数组“ch”中 ,如果ch不是“”,则建立一个新结点。若新结点是第一个结点,则它是根结点,将其入队,指针tree指向这个根节点;如果不是根结点,则将当前结点链接到双亲结点上,即当前结点的双亲指针就是队头元素,然后将当前结点入队列。接着判断flag的值,如果flag=0,表示当前结点没有左孩子,那么当前结点就是双亲的左孩子。否则,当前结点就是双亲的右孩子。用指针root指向刚刚入队的结点。继续复制数组family的下个元素。如果“ch” 是。则flag=0(因为