家族关系查询系统(2021-9-22更新)
最多的问题:1.如何运行?2.功能都什么?3.生成的文件都保存到哪里了?4.输入输出的格式是什么样的?
1.打开编译器,复制粘贴运行,我用的是codeblocks,vs也是可以的,如不行,先看报错,尝试百度解决,如不行,下面评论我会回复。
2.功能就是运行起来以后的展示出来的那么多,后面不会再增加新功能。
3.cpp文件的相同目录下。
4.
文件名是家族名,格式输入如截图所示,如果不知道文件建在哪里,就使用第一个功能,让程序自动生成一个,你再进行修改。
--------------------------------------------------------------------------------------------------------------------------------
家族关系查询系统
1.问题描述
建立家族关系数据库,实现对家族成员关系的相关查询。
2.基本要求
(1)建立家族关系并能存储到文件中;
(2)实现家族成员的添加。
(3)可以查询家族成员的双亲、祖先、兄弟、孩子和后代等信息。
3.扩展功能
在家族关系查询中包含了许多查询功能,可通过输入不同的命令和参数有选择的实现各种查询。在编写程序时,可以加入修改成员信息的功能并能及时更新保存。
数据结构的课程设计,用的三叉树,STL中的queue,使用文件形式输入。
#include <string.h>
#include<iostream>
#include <malloc.h>
#include<queue>
#include<limits.h>
#include<stdio.h>
#include<stdlib.h>
#include<io.h>
#include<math.h>
#include<ctype.h>
#include<process.h>
using namespace std;
#define MAX 20
typedef struct TriTNode
{char data[MAX];struct TriTNode *parent;//双亲struct TriTNode *lchild;struct TriTNode *rchild;
} Tree,*TreePt;char fname[MAX],family[50][MAX];// 全局变量Tree *Open(char familyname[MAX]);
Tree *TreeCreate();
Tree *Search(Tree *t,char str[]);
void Append(Tree *t);
void Ancestor(Tree *t);
void AncestorPath(Tree *t);
void Parent(Tree *t);
void Generation(Tree *t);
void Brothers(Tree *t,char str[]);
void Consin(Tree *t);
void Children(Tree *t);
void InOrder(Tree *t);
void allChildren(Tree *t);
Tree *Create(char familyname[MAX]);int main()
{char str[MAX];int flag,start =0;;Tree *temp,*tree=NULL;while(1){printf("\t欢迎使用家族关系查询系统!\n");printf("\t 1.新建一个家庭关系:\n");printf("\t 2.打开一个家庭关系: \n");printf("\t 3.添加新成员的信息: \n");printf("\t 4.查找家族的祖先:\n");printf("\t 5.查找一个成员的祖先路径:\n");printf("\t 6.确定一个成员是第几代:\n");printf("\t 7.查找一个成员的双亲:\n");printf("\t 8.查找一个成员的兄弟:\n");printf("\t 9.查找一个成员的堂兄弟:\n");printf("\t10.查找一个成员的孩子:\n");printf("\t11.查找一个成员的子孙后代:\n");printf("\t12.退出系统: \n ");cin>>flag;if(!(flag==1||flag==2||flag==12)&&start==0){printf("请先建立或打开一个家族关系!\n");continue;}start=1;switch(flag) //根据flag标记调用函数{case 1:cout<<"请输入家族名氏"<<endl;getchar();gets(str);tree=Create(str);break;case 2:cout<<"请输入家族名氏"<<endl;getchar();gets(str);tree=Open(str);break;case 3:Append(tree);break;case 4:Ancestor(tree);break;case 5:cout<<"请输入成员名氏"<<endl;cin>>str;temp=Search(tree,str);if(!temp) // 若不存在则返回{printf("该成员不存在!\n");continue;}AncestorPath(temp);break;case 6:cout<<"请输入成员名氏"<<endl;cin>>str;temp=Search(tree,str);if(!temp) // 若不存在则返回{printf("该成员不存在!\n");continue;}Generation(temp);break;case 7:cout<<"请输入成员名氏"<<endl;cin>>str;temp=Search(tree,str);if(!temp) // 若不存在则返回{printf("该成员不存在!\n");continue;}Parent(temp);break;case 8:cout<<"请输入成员名氏"<<endl;cin>>str;temp=Search(tree,str);if(!temp) // 若不存在则返回{printf("该成员不存在!\n");continue;}Brothers(temp,str);break;case 9:cout<<"请输入成员名氏"<<endl;cin>>str;temp=Search(tree,str);if(!temp) // 若不存在则返回{printf("该成员不存在!\n");continue;}Consin(temp);break;case 10:cout<<"请输入成员名氏"<<endl;cin>>str;temp=Search(tree,str);if(!temp) // 若不存在则返回{printf("该成员不存在!\n");continue;}Children(temp);break;case 11:cout<<"请输入成员名氏"<<endl;cin>>str;temp=Search(tree,str);if(!temp) // 若不存在则返回{printf("该成员不存在!\n");continue;}allChildren(temp);break;case 12:exit(1);}}return 0;
}Tree *Create(char familyname[MAX])//建立家族关系并存入文件
{int i=0;char ch,str[MAX]; //Tree *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;}}if(!fp||ch=='Y'||ch=='y') //重新建立,执行以下操作{fp=fopen(fname,"w"); //以写入方式打开文件,不存在则新建printf("请按层次输入结点,每个结点信息占一行\n");printf("兄弟输入结束以“@”为标志,结束标志为“#”\n★");gets(str);fputs(str,fp);fputc('\n',fp);strcpy(family[i],str); //将成员信息存储到字符数组中*/i++;while(str[0]!='#'){printf("★"); //提示符提示继续输入gets(str);fputs(str,fp); //写到文件中,每个信息占一行fputc('\n',fp);strcpy(family[i],str); //将成员信息存储到字符数组中i++;}fclose(fp);t=TreeCreate(); // 根据family数组信息创建三叉树*/printf("家族关系已成功建立!\n");return t;}return 0;
}Tree *TreeCreate()
{Tree *t,*tree,*root=NULL;queue<TreePt>q;int i=0,flag=0,start=0;char str[MAX]; // 存放family数组中信息strcpy(str,family[i]);i++;while(str[0]!='#') //没遇到结束标志继续循环*/{while(str[0]!='@') //没遇到兄弟输入结束标志继续{if(root==NULL) // 空树{root=(Tree *)malloc(sizeof(Tree));strcpy(root->data,str);root->parent=NULL;root->lchild=NULL;root->rchild=NULL;q.push(root);tree=root;}else //不为空树{t=(Tree *)malloc(sizeof(Tree));strcpy(t->data,str);t->lchild=NULL;t->rchild=NULL;t->parent = q.front();// 当前结点的双亲为队头元素q.push(t);if(flag == 0) //flag为0,当前结点没有左孩子root->lchild=t;elseroot->rchild=t; //flag为1,当前结点已有左孩子root=t; //root指向新的结点t}flag=1; //标记当前结点已有左孩子strcpy(str,family[i]);i++;}if(start!=0) //标记不是第一次出现“@”{q.pop();if(q.front())root = q.front();}start=1; // 标记已出现过“@”flag=0; //“@”后面的结点一定为左孩子strcpy(str,family[i]);i++;}return tree;
}Tree *Open(char familyname[MAX])
{int i=0,j=0;char ch;FILE *fp;Tree *t;strcpy(fname,familyname); //以家族名为文本文件名存储strcat(fname,".txt");fp=fopen(fname,"r"); //以读取方式打开文件if(fp==NULL) //文件不存在{printf("%s 的家族关系不存在!\n",familyname);return NULL;}else{ch=fgetc(fp); //按字符读取文件while(ch!=EOF) //读到文件尾结束{if(ch!='\n'){family[i][j]=ch;j++;}else{family[i][j]='\0'; //字符串结束标志i++; //family数组行下标后移j=0; //family数组列下标归零}ch=fgetc(fp); //继续读取文件信息}fclose(fp);t=TreeCreate(); //调用函数建立三叉链表printf("家族关系已成功打开!\n");return t;}
}
Tree *Search(Tree *t,char str[])
{Tree *temp;if(t==NULL) //如果树空则返回NULLreturn NULL;else if(strcmp(t->data,str)==0) //如果找到返回该成员指针return t;else //如果没找到遍历左右子树进行查找{temp=Search(t->lchild,str);if(temp) //结点不空则查找return(Search(t->lchild,str));elsereturn(Search(t->rchild,str));}
}
void Append(Tree *t) //添加成员
{int i=0,j,parpos=1,curpos,num,end=0,count=-1;char chi[MAX],par[MAX]; //存储输入的孩子和其双亲结点Tree *tpar,*temp;FILE *fp;printf("请输入要添加的成员和其父亲,以回车分隔!\n. ");getchar();gets(chi);printf(". "); //以点提示符提示继续输入gets(par);tpar=Search(t,par); //查找双亲结点是否存在if(!tpar)printf("%s 该成员不存在!\n",par);else //存在则添加其孩子{temp=(Tree *)malloc(sizeof(Tree));temp->parent=tpar;strcpy(temp->data,chi);temp->lchild=NULL;temp->rchild=NULL;if(tpar->lchild) //成员存在左孩子{tpar=tpar->lchild; //遍历当前成员左孩子的右子树while(tpar->rchild) //当前结点右孩子存在tpar=tpar->rchild; //继续遍历右孩子tpar->rchild=temp; //将新结点添加到所有孩子之后*/}else //没有孩子则直接添加tpar->lchild=temp;fp=fopen(fname,"w"); // 以写入方式打开文件if(fp){while(strcmp(par,family[i])!=0&&family[i][0]!='#'){if(family[i][0]!='@')parpos++;i++;}i=0;while(family[i][0]!='#'){if(family[i][0]=='@')count++;if(count==parpos)curpos=i;i++;}if(count<parpos){num=parpos-count;for(j=i; j<=i+num; j++)strcpy(family[j],"@\0");strcpy(family[i+num+1],"#\0");strcpy(family[i+num-1],chi);end=1;}else{for(j=i; j>=curpos; j--)strcpy(family[j+1],family[j]);strcpy(family[curpos],chi);}if(end==1)i=i+num;for(j=0; j<=i+1; j++){fputs(family[j],fp);fputc('\n',fp);}fclose(fp);cout<<"添加新成员成功!"<<endl;}elsecout<<"添加新成员失败!"<<endl;}
}
void Ancestor(Tree *t) //祖先
{printf("该家族的祖先为%s\n",t->data);
}
void AncestorPath(Tree *t) //祖先路径
{if(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");}
}
void Parent(Tree *t) //双亲
{if(t->parent!=NULL) //若该成员为祖先,则无双亲printf("%s 的双亲为%s\n",t->data,t->parent->data);elseprintf("%s 无双亲!\n",t->data);
}void Generation(Tree *t) //确定一个成员是第几代
{int count=1;char str[MAX];strcpy(str,t->data);while(t->parent!=NULL){count++;t=t->parent;}printf("%s 是第%d 代!\n",str,count);
}
void Brothers(Tree *t,char str[]) //查找兄弟
{if(t->parent!=NULL) //若该结点是祖先,则无兄弟{t=t->parent; //该结点的兄弟即为其双亲除该成员以外的所有孩子if(t->lchild&&t->lchild->rchild) //当前结点的左孩子及其右孩子都存在{printf("%s 的所有兄弟有:",str);t=t->lchild;while(t) //遍历当前成员左孩子的右子树{if(strcmp(t->data,str)!=0) //遍历右子树,选择输出printf("%s ",t->data); //访问当前结点t=t->rchild;}printf("\n");}elseprintf("%s 无兄弟!\n",str);}elseprintf("%s 无兄弟!\n",str);
}
void Consin(Tree *t)
{int flag=0;Tree *ch=t;Tree *temp;if(t->parent&&t->parent->parent)//当前结点的双亲及其双亲都存在{t=t->parent->parent->lchild;//当前结点等于其祖先的第一个孩子while(t) //存在则继续查找{if(strcmp(t->data,ch->parent->data)!=0){if(t->lchild) //当前结点存在左孩子*/{temp=t->lchild;while(temp) //遍历当前结点左孩子的右子树*/{if(strcmp(temp->data,ch->data)!=0){if(!flag)printf("%s 的所有堂兄弟有:",ch->data);printf("%s ",temp->data);flag=1;}temp=temp->rchild; //继续遍历右孩子}}}t=t->rchild; //继续遍历右孩子}printf("\n");}if(!flag)printf("%s 无堂兄弟!\n",ch->data);
}
void Children(Tree *t) //遍历左孩子
{if(t->lchild) // 当前结点存在左孩子{printf("%s 的所有孩子有:",t->data);t=t->lchild; //遍历当前成员左孩子的右子树*/while(t){printf("%s ",t->data);t=t->rchild;}printf("\n");}elseprintf("%s 无孩子!\n",t->data);
}/* 中序遍历一棵树*/
void InOrder(Tree *t)
{if(t){InOrder(t->lchild);printf("%s ",t->data);InOrder(t->rchild);}
}
void allChildren(Tree *t) //所有后代
{if(t->lchild) //当前结点存在左孩子{printf("%s 的所有子孙后代有:",t->data);InOrder(t->lchild); //中序遍历当前结点的左右子树printf("\n");}elseprintf("%s 无后代!\n",t->data);
}
家族关系查询系统(2021-9-22更新)相关推荐
- 家族关系查询系统程序设计算法思路_数据结构课程设计--
数据结构课程设计-- 家族关系查询系统 课 程 设 计 任 务 书 题目题目 家族关系查询系统家族关系查询系统 主要内容.基本要求.主要参考资料等主要内容.基本要求.主要参考资料等 主要内容主要内容 ...
- 家族关系查询系统程序设计算法思路_家族关系查询系统
家族关系查询系统 1.问题描述 建立家族关系数据库,实现对家族成员关系的相关查询. 2.基本要求 (1)建立家族关系并能存储到文件中: (2)实现家族成员的添加. (3)可以查询家族成员的双亲.祖先. ...
- 家族关系查询系统程序设计算法思路_数据结构课程设计(家族关系查询系统)
1 课程设计介绍 1 . 1 课程设计项目简介 家谱就是一种以表谱形式 , 记载一个以血缘关系为主体得 家族世系繁衍与重要人物事迹得特殊图书载体.家谱就是中国特 有得文化遗产,就是中华民族得三大文献之 ...
- 家族关系查询系统程序设计算法思路_数据结构课程设计(家族关系查询系统)..doc...
数据结构课程设计(家族关系查询系统). 1 课程设计介绍 1.1课程设计项目简介 家谱是一种以表谱形式,记载一个以血缘关系为主体的家族世系繁衍和重要人物事迹的特殊图书载体.家谱是中国特有的文化遗产,是 ...
- 家族关系查询系统程序设计算法思路_数据结构课程设计方案(家族关系查询系统)...
家族关系查询系统 1 1 课程设计介绍 1.1 课程设计项目简介 家谱是一种以表谱形式, 记载一个以血缘关系为主体的家族世 系繁衍和重要人物事迹的特殊图书载体.家谱是中国特有的文化 遗产,是中华民族的 ...
- 家族关系查询系统程序设计算法思路_数据结构课程设计(家族关系查询系统).....
家族关系查询系统 1 1 课程设计介绍 1.1 课程设计项目简介 家谱是一种以表谱形式, 记载一个以血缘关系为主体的家族世 系繁衍和重要人物事迹的特殊图书载体.家谱是中国特有的文化 遗产,是中华民族的 ...
- 家族关系查询系统程序设计算法思路_数据结构课程设计家族关系查询系统要点...
家族关系查询系统 1 课程设计介绍 1.1 课程设计项目简介 家谱是一种以表谱形式,记载一个以血缘关系为主体的家族世系繁衍和重要 人物事迹的特殊图书载体. 家谱是中国特有的文化遗产, 是中华民族的三大 ...
- 家族关系查询系统程序设计算法思路_大数据结构课程设计(家族关系查询系统)要点...
实用标准文案 精彩文档 1 课程设计介绍 1.1 课程设计项目简介 家谱是一种以表谱形式, 记载一个以血缘关系为主体的家族世 系繁衍和重要人物事迹的特殊图书载体.家谱是中国特有的文化 遗产,是中华民族 ...
- 家族关系查询系统程序设计算法思路_数据结构设计(家族关系查询系统)汇编.doc...
1 课程设计介绍 1.1课程设计项目简介 家谱是一种以表谱形式,记载一个以血缘关系为主体的家族世系繁衍和重要人物事迹的特殊图书载体.家谱是中国特有的文化遗产,是中华民族的三大文献之一,属珍贵的人文资料 ...
最新文章
- RateLimiter 源码分析(Guava 和 Sentinel 实现)
- [js]设计模式小结对原型的修改
- 生产者与消费者案例-虚假唤醒
- EDM数据库营销是什么?-EDM数据库营销的概念
- Java 并发(JUC 包-03)
- spring boot注解_Spring-boot(二)注解
- win7查看隐藏文件_Win8系统查看隐藏文件的操作方法是什么?
- C++_类和对象_C++继承_继承中子类的同名成员处理_同名变量_同名函数---C++语言工作笔记065
- php修改mysql排序_php – 自定义MySQL排序
- 大数据开发笔记(六):Flume基础学习
- bzoj 3123 [Sdoi2013]森林
- 十大热门编程语言的介绍
- 抖音html动态时钟,三分钟教会!火爆抖音的“动态时钟屏保”,个性十足!
- 登录samba后提示“你可能没有权限访问网络资源”的解决方法
- golang 生成二维码名片 海报
- 微信小程序的选择收货地址、新增地址、地址管理等模块的总结(1)
- YbtOJ 洛谷UVA10559 方块消除
- 鸿蒙系统桌面搭配,华为平板 MatePad Pro 来了!首搭鸿蒙系统,与电脑“花样”协同…...
- seata xid是什么_微服务分布式事务解决方案-springboot整合分布式seata1.3.0
- 圣斗士星矢重生服务器维护,11月26日全服停机维护公告