*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:test.cpp * 作者:常轩 * 微信公众号:Worldhello * 完成日期:2016年12月27日 * 版本号:V1.0 * 程序输入:无 * 程序输出:见运行结果 */ /* 使用孩子兄弟结构进行存储 */ #include<iostream> #include<stdio.h> #include<String> #define MaxSize 1000 using namespace std; char zuxian[100],chengyuan[100],fubei[100]; int zuigaomax=1; int time=0; typedef struct { char data[MaxSize]; //存放字符串 int length; //存放串长 }SqString; struct Tree { char name[100]; char sex[100]; char fed[100];//配偶 char thing[1000];//个人简介 char borth[100];//生日 int level;//辈分 struct Tree *child; //孩子指针 struct Tree *brother; //兄弟指针 struct Tree *parent; //父亲指针 }; Tree *Create(Tree *t,char s[]) { //创建族谱 Tree *p; p=new Tree; strcpy(p->name,s); //祖先名字 p->brother=NULL; //规定祖先只有一个人,即指向兄弟的指针为空,指向父亲节点的指针为空 p->child=NULL; //暂且将孩子指针赋值为空 p->parent=NULL; p->level=1; //记录辈分,为第一代 cout<<"请输入性别:"<<endl; cin>>p->sex; cout<<"请输入配偶名称:"<<endl; cin>>p->fed; cout<<"请输入生日:"<<endl; cin>>p->borth; cout<<"请输入个人简介:"<<endl; cin>>p->thing; t=p; return t; //创建祖先成功,返回 } Tree *Find(Tree *b,char cname[]) //查询位置 { Tree *p; if(b==NULL) //如果树为空,则返回NULL return NULL; else if(strcmp(b->name,cname)==0) //判断查询的是否为祖先节点 { return b; } else //如果不符合上面的两种情况,则使用递归进行下一轮查询 { p=Find(b->child,cname); if(p!=NULL) { return p; } else { return Find(b->brother,cname); } } } void coutxinxi(Tree *b,char cname[]) //输出个人信息 { Tree *p; p=Find(b,cname); //使用查询位置函数,对所要查询的成员信息进行定位,然后再返回赋值给p cout<<"名字: "<<p->name; cout<<"第"<<p->level<<"代"; cout<<"父辈: "<<p->parent->name; cout<<"性别: "<<p->sex; cout<<"配偶: "<<p->fed; cout<<"生日: "<<p->borth; cout<<"个人简介: "<<p->thing; } int chaxunbeifen(Tree *b,char chaxunmingzi[]) //查询名称的辈分 { Tree *p; p=Find(b,chaxunmingzi); //首先找到这个人,因为节点信息里包括了成员的辈分信息,所以如果此节点不为空就直接返回p->level if(p==NULL) return 0; else return p->level; } void add(Tree *b,char parent[],char erzi[]) //增加 { Tree *p,*q; p=Find(b,parent); //根据输入的父亲节点的名字,进行查找父亲节点 if(p==NULL) //为空,不存在 { cout<<"双亲不存在"<<endl; return ; } q=new Tree; //存在,对子节点进行赋值 strcpy(q->name,erzi); q->level=p->level+1; //辈分在父亲结点的基础上进行+1 cout<<"请输入性别:"<<endl; cin>>chengyuan; strcpy(q->sex,chengyuan); cout<<"请输入配偶名称:"<<endl; cin>>chengyuan; strcpy(q->fed,chengyuan); cout<<"请输入生日:"<<endl; cin>>chengyuan; strcpy(q->borth,chengyuan); cout<<"请输入个人简介:"<<endl; cin>>chengyuan; strcpy(q->thing,chengyuan); if(p->level+1>zuigaomax) //判断一下,新增的这个节点的辈分是否超过了整个族谱的高度,如果超过则纪录最高长度的变量zuigaomax=此时的辈分+1 { zuigaomax=p->level+1; } q->child=NULL; //接着对其孩子指针赋值为空 q->brother=NULL; //兄弟指针赋值为空 q->parent=p; //父亲结点就是此函数刚开始时的查找到的,然后进行赋值 if(p->child==NULL) //现在开始查找一下新增节点的父节点原来有没有孩子,如果没有,就直接将父节点的孩子指针直接指向次新增节点 { p->child=q; } else //如果有孩子,则开始循环,知道查到父节点的最后一个新增的孩子节点 { p=p->child; while(p->brother!=NULL) { p=p->brother; } p->brother=q; //将新增的节点与查找到的最后一个孩子节点连接起来 } } void xiugai(Tree *b,char chaxunmingzi[]) //修改函数 { Tree *p; p=Find(b,chaxunmingzi); //查找要修改的节点 if(p==NULL) //没查到,返回NULL { cout<<"查无此人"; return ; } cout<<"请输入修改信息"<<endl; //查到之后进行逐项修改 cout<<"新姓名:"; cin>>chengyuan; strcpy(p->name,chengyuan); cout<<"请输入性别:"<<endl; cin>>chengyuan; strcpy(p->sex,chengyuan); cout<<"请输入配偶名称:"<<endl; cin>>chengyuan; strcpy(p->fed,chengyuan); cout<<"请输入生日----(格式:****--**--**)"<<endl; cin>>chengyuan; strcpy(p->borth,chengyuan); cout<<"请输入个人简介:"<<endl; cin>>chengyuan; strcpy(p->thing,chengyuan); } void deletechengyan(Tree * &b,char chaxunmingzi[]) //删除函数 { Tree *p,*shanchus; p=Find(b,chaxunmingzi); if(p==NULL) { cout<<"此人不存在"<<endl; return ; } shanchus=p; Tree *q; q=p->parent; if(q==NULL) //如果被删除节点是第一个,则释放 { delete shanchus; } else if(q->child==p) //判断被删除节点是否是父节点直接指向的节点 { if(p->brother!=NULL) { q->child=p->brother; } delete shanchus; } else { Tree *r=q->child,*m; m=r; while(r!=NULL) { if(r==shanchus) { m->brother=r->brother; delete shanchus; break; } m=r; r=r->brother; } } } void bianli(Tree *b) //遍历 查看族谱 { if (b!=NULL) { for(int i=0;i<b->level;i++) cout<<" "; cout <<"第"<<b->level<<"代"; cout <<b->name<<"---"; cout<<"配偶:"<<b->fed<<"---"; cout<<"出生日期:"<<b->borth<<endl; if (b->child!=NULL || b->brother!=NULL) { bianli(b->child); bianli(b->brother); } } } void creatZupu(Tree * &u) //创建族谱 { cout<<"开始创建族谱!作为祖先很光荣啊!"<<endl; cout<<"请输入祖先姓名:"<<endl; cin>>zuxian; u=Create(u,zuxian); cout<<"好了,恭喜啦!第一个祖先已经入住族谱了,后辈们要加油哟!"<<endl; } SqString changeSign(char sign[]) //将字符串转换成串存储结构 { int i; SqString str; for(i=0;sign[i]!=' ';i++) { str.data[i]=sign[i]; } str.length=i; return str; } bool piPei(SqString s,SqString t) //BF算法 串的模式皮匹配 { int i=0,j=0; while(i<s.length&&j<t.length) { if(s.data[i]==t.data[j]) //继续匹配下一个字符 { i++; //主串和字串依次匹配下一个节点 j++; } else { i=i-j+1; j=0; } } if(j>=t.length) return true;// (i-t.length);下标 else return false; } void bianli1(Tree *b, char aboutInformation[]) //遍历搜索 { if(b!=NULL) { if(piPei(changeSign(b->thing),changeSign(aboutInformation))==true) //调用pipei()函数对于每一个节点的简历和关键字进行匹配,如果简历中包含关键字则输出成员姓名和成员的相关简历 { cout<<"名字: "<<b->name<<endl<<endl; cout<<" ——相关介绍:"<<endl<<" "<<b->thing<<endl; } if (b->child!=NULL || b->brother!=NULL) //进行递归调用,遍历每一个节点的个人简历 { bianli1(b->child,aboutInformation); bianli1(b->brother,aboutInformation); } } // else // cout<<"尚未创建族谱!"<<endl; } void seven(Tree * u) //根据关键字查询 { cout<<"请输入有关信息:"<<endl; char aboutInformation[80]; cin>>aboutInformation; bianli1(u,aboutInformation); //将关键字传入进行遍历搜索 } int menu_select(); int main() { Tree *u; u=NULL; // SqString *s,*t; int n;. while(1) { n=menu_select(); if(n==1) { if(u==NULL) { cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl; continue; } cout<<"请输入添加成员名称:"<<endl; cin>>chengyuan; cout<<"请输入添加成员的长辈名称:"<<endl; cin>>fubei; add(u,fubei,chengyuan); } else if(n==2) { if(u==NULL) { cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl; continue; } cout<<"请输入删除成员的名称:"<<endl; char chengyuan[10]; cin>>chengyuan; deletechengyan(u,chengyuan); } else if(n==3) { if(u==NULL) { cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl; continue; } cout<<"请输入查询名称:"; cin>>chengyuan; Tree *o=Find(u,chengyuan); if(o) { cout<<"名字: "<<o->name<<endl; cout<<"辈分: "<<o->level<<endl; cout<<"性别: "<<o->sex<<endl; cout<<"配偶: "<<o->fed<<endl; cout<<"生日: "<<o->borth<<endl; cout<<"个人简介: "<<o->thing<<endl; if(o->parent==NULL) { } else cout<<"爸爸为"<<o->parent->name<<endl; } else { cout<<"查无此人"<<endl; } } else if(n==4) { if(u==NULL) { cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl; continue; } bianli(u); } else if(n==5) { if(u==NULL) { cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl; continue; } cout<<"请输入查询名称:"; cin>>chengyuan; int y=chaxunbeifen(u,chengyuan); if(y) { cout<<"辈分为:第"<<y<<"代"<<endl; } else { cout<<"查无此人"<<endl; } } else if(n==6) { if(u==NULL) { cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl; continue; } cout<<"请输入要修改的成员名称"<<endl; cin>>chengyuan; xiugai(u,chengyuan); } else if(n==7) { if(u==NULL) { cout<<"暂未创建族谱,请输入功能键8创建族谱!"<<endl; continue; } seven(u); } else if(n==8) { creatZupu(u); } else { break; } } return 0; } int menu_select() //菜单函数定义 { char c; printf("=============================================================== "); printf("|--------------------家族成员信息管理系统 v1.0----------------| "); printf("| | "); printf("| 1.添加成员 | "); printf("| 2.删除成员 | "); printf("| 3.查询个人信息 | "); printf("| 4.查看族谱 | "); printf("| 5.查询辈分 | "); printf("| 6.修改信息 | "); printf("| 7.根据关键字查询 | "); printf("| 8.创建族谱 | "); printf("| 9.退出系统 | "); printf("*************************************************************** "); printf(" 请输入(1-7)进行操作: "); do{ scanf("%c",&c); }while(c<'1'||c>'9'); return c-48; }