📄 pedigree.cpp
字号:
#include<iostream> //输入输出流
#include<fstream> //文件输入/输出流
#include<string> //字符串处理
#include<stdlib.h> //定义杂项函数及内存分配函数
using namespace std; //全局命名空间
#ifndef BT_h //与#endif一起用,现在还不懂有什么用
#define BT_h //同上
class Family //定义字符串Family的类
{
public:
string father;
string wife;
string son;
};
template<typename T>//类模板
class Btnode //二叉数的结点类,教材p195有
{
public:
Btnode():l(NULL),r(NULL){} //默认构造函数
Btnode(T&item,Btnode<T>*ptr1=NULL,
Btnode<T>*ptr2=NULL):data(item),l(ptr1),r(ptr2){}
T data; //结点数据,作为公有成员
Btnode<T>*&L() //取左
{return l;}
Btnode<T>*&R() //取右
{return r;}
protected:
Btnode<T>*l,*r;
};
template<typename T>
void PO(Btnode<T>*t) //先序遍历
{
if(t)
{
cout<<t->data<<" "; //访问根结点
PO(t->L()); //遍历L
PO(t->R()); //遍历R
}
}
#endif
Btnode<string>*CreatBtnode(string &pre,Family fam[],int &n)/*从fam创建一棵二叉树*/
{
int i=0,j;
Btnode<string>*p1,*p2;
p1=new Btnode<string>;//建结点
p1->data=pre;
p1->L()=NULL;
p1->R()=NULL;
while
(i<n&&fam[i].father!=pre)
i++;
if(i<n)
{
p2=new Btnode<string>;
p2->L()=NULL;
p2->R()=NULL;
p2->data=fam[i].wife;
p1->L()=p2;
for(j=0;j<n;j++)
if(fam[j].father==pre)
{
p2->R()=CreatBtnode(fam[j].son,fam,n);
p2=p2->R();
}
}
return p1;
};
void DispTree1(Btnode<string>*b) //括号表示法,我记得书有,但忘记在那里
{
if (b!=NULL)
{
cout<<b->data<<" ";
if (b->L()!=NULL || b->R()!=NULL)
{
cout<<"("<<" ";
DispTree1(b->L());
if (b->R()!=NULL)
DispTree1(b->R());
cout<<")";
}
}
};
void DispTree2(Btnode<string>*T) // 凹入法显示二叉树,这个不懂抄人家的代码
{
Btnode<string>*stack[30],*p;
int level[30][2],top,n,i,width=4;
if(T!=NULL)
{
cout<<"\t\n凹入表示法:\n\t\t";
top=1;
stack[top]=T; // 根结点入栈
level[top][0]=width;
while(top>0)
{
p=stack[top]; // 退栈并显示结点的值
n=level[top][0];
for(i=1;i<=n;i++) // n为显示宽度,字符以右对齐显示
{
cout<<" ";
}
cout<<p->data;
for(i=n+1;i<50;i+=2)
{
cout<<"~";
}
cout<<"\n\t\t";
top--;
if(p->R()!=NULL)
{ // 右子树根结点入栈
top++;
stack[top]=p->R();
level[top][1]=2; // 左子树根结点入栈
}
if(p->L()!=NULL)
{
top++;
stack[top]=p->L();
level[top][0]=n+width; // 显示宽度增加width
level[top][1]=1;
}
}
}
cout<<"\n";
};
Btnode<string>*FindNode(Btnode<string>*bt,string xm) /*采用先序递归算法找xm的结点,从参考书中参考过来的*/
{
Btnode<string>*p=bt;
if(p==NULL)
{
return(NULL);
}
else
{
if(p->data==xm)
{
return(p);
}
else
{
bt=FindNode(p->L(),xm);
if(bt!=NULL)
{
return(bt);
}
else
{
return(FindNode(p->R(),xm));
}
}
}
};
void FindSon(Btnode<string>*bt)/*输出某人的所有儿子*/
{
string xm;
Btnode<string>*p;
cout<<"父亲的姓名: ";
cin>>xm;
cout<<"\n";
p=FindNode(bt,xm);
if(p==NULL)
cout<<"没有"<<xm<<"\n";
else
{
p=p->L();
if (p==NULL)
{
cout<<xm<<"没有妻子!\n";
}
else
{
p=p->R();
if(p==NULL)
{
cout<<xm<<"没有儿子!\n";
}
else
{
cout<<xm<<"的儿子: ";
while (p!=NULL)
{
cout<<p->data<<" ";
p=p->R();
}
cout<<"\n\n";
}
}
}
};
void FindAncestor(string xm,Family fam[],int &n)//找祖先
{
for(int i=0;i<n;i++)
{
if(fam[i].son==xm)
{
cout<<fam[i].father<<" ";
FindAncestor(fam[i].father,fam,n);
}
}
};
void Ancestor(Family fam[],int &n)/*输出某人的所有祖先*/
{
string xm;
int j=0;
cout<<"输入名字: ";
cin>>xm;
cout<<"\n";
for(int i=0;i<n;i++)
{
if(fam[i].son==xm)
{
cout<<xm<<"的祖先有: ";
FindAncestor(xm,fam,n);
cout<<"\n\n";
j=1;
}
}
if(j!=1)
{
cout<<"没有"<<xm<<"的祖先\n\n";
}
};
void SaveFile(Family fam[],int n) //储存函数,在C++教材那里改来的
{
ofstream outstuf;
outstuf.open("d:\\savenamefile.txt");
for(n=0;n<20;n++)
outstuf<<fam[n].father<<' '<<fam[n].wife<<' '<<fam[n].son<<'\n';
outstuf.close();
};
void ReadFile(Family fam[],int &n) //读数据函数,同上
{
n=0;
ifstream instuf("d:\\savenamefile.txt",ios::in);
while(instuf)
{
instuf>>fam[n].father>>fam[n].wife>>fam[n].son;
n++;
}
if(n!=0)
{
n=n-1;
}
instuf.close();
};
void InputFile(Family fam[],int &n) //输入数据
{
cout<<"请输入(父亲、母亲和儿子)姓名: "<<endl;
cin>>fam[n].father>>fam[n].wife>>fam[n].son;
n++;
};
void OutputFile(Family fam[],int &n) //输出数据
{
int i;
if(n<1)
{
cout<<"没有任何记录\n"<<endl;
return;
}
for(i=0;i<n;i++)
{
cout<<fam[i].father<<" "<<fam[i].wife<<" "<<fam[i].son<<"\n";
}
cout<<endl;
};
void DelAll(Family fam[],int &n) /*清除家谱文件全部记录*/
{
ifstream instuf("d:\\savenamefile",ios::trunc);
for(n=0;n<20;n++)
instuf>>fam[n].father>>fam[n].wife>>fam[n].son;
instuf.close();
n=0;
};
void main() //主函数main
{
int n;
Family fam[40];
ReadFile(fam,n);
cout<<" 欢迎使用家谱软件系统"<<endl;
char sel,sel1;
do //do while循环整个系统,使之可以循环运行
{
cout<<"(1.文件操作 2.家谱操作 0.退出系统 )请输入: ";
cin>>sel;
cout<<"\n";
switch(sel) //switch使可以条件选择选项
{
case '1':
{
do
{
cout<<"(1.记录输入 2.记录输出 3.清除全部记录 0.存盘,返回菜单) 请输入: ";
cin>>sel1;
cout<<"\n";
switch (sel1)
{
case '1':InputFile(fam,n);break;
case '2':OutputFile(fam,n);break;
case '3':DelAll(fam,n);break;
case '0':SaveFile(fam,n);break;
default:system("cls");cout<<"input error"<<endl;break;
}
}while(sel1!='0');
break;
case '2':
Btnode<string>*p;
p=CreatBtnode (fam[0].father,fam,n);
do
{
cout<<"( 1.括号表示法 2.凹入表示法 3.找某人的所有儿子 4.找某人所有祖先 0.返回菜单)请输入:";
cin>>sel1;
cout<<"\n";
switch(sel1) //switch使可以条件选择选项
{
case '1':cout<<"括号表示法:\n\t";DispTree1(p);cout<<endl<<endl;break;
case '2':DispTree2(p);break;
case '3':FindSon(p);break;
case '4':Ancestor(fam,n);break;
case '0':break;
default:system("cls");cout<<"input error"<<endl;break;
}
}while(sel1!='0');
break;
case '0':break;
default:system("cls");cout<<"input error"<<endl;break;
}
}
}while(sel!='0');
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -