前几天遇见一个大一的(实际上我也不敢相信一个大一的老师就敢给他们出这么二逼的题),他给我出了个老师给的问题,就是下边这个:
实际上看见这个题的时候我心里边第一想到的就是链表,然后上下的继承关系啥的就直接存储在数据去里边整个结构体就完事儿了,但是后来想了想还得有个遍历过程,不然上下边的话光图简单也达不到上来就能很准确的输出继承关系输出的效果。这个时候的话就想到了二叉树。但是二叉树的话一对儿夫妻很可能不想生孩子,也很可能养十几个的将来卖着玩儿玩儿。
嗯这样的话实际上家族关系在基本的夫妻关系上就要考虑到孩子之间是怎么完成亲属关系的对吧,毕竟数据区域就是有这一个节点对象的几个属性,除了配偶你能够通过遍历树外加比对对象属性直接找到这个对象然后进行设定(这儿之所以没把配偶也设计成像孩子那样儿的数组是考虑到下边很可能就直接展现“一妻多夫”政策跟“一夫多妻”思想之间相互报复的局面,孩子将来也被骂成杂种,挺不好的,不过下边的话我也给实现了),这就直接的借鉴了CSDN伯克利编一个大佬的结构根思路(之所以说是借鉴也并不是虚伪,骨架跟思想的话是模仿了,但肉上的确是真真实实自己打出来的)然后就开始添加属性跟方法,方法的话你只要跟着修改了一个属性,这个属性就会根据他的设定初衷直接颠覆整个方法的定义,甚至要增加减少n个方法(私有的跟公有的都算上)。
这就是在设计完第一版之后为啥直接的又整出来了二版三版,实际上就是耗子舔猫逼没事儿寻刺激,既然这么好玩儿为啥不瞎改着玩儿玩儿呢是不是?????
下边上三版代码跟三版的运行效果。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int MATEFLAG=0;//配偶
typedef struct TreeNode
{
int Num; //记录这个人拥有几个儿女
char Name[20]; //记录这个人的姓名
char Kind; //标示节点的种类有女G男B
char work[20]; //记录这个人的姓名
char zaishishijian[20]; //记录这个人的姓名
char shifouhaihuozhe[20]; //记录这个人的姓名
struct TreeNode * NextNode[20]; //记录这个人的儿女
struct TreeNode * Parent; //记录这个节点的父节点
}TreeNode;
void MainMenue(TreeNode *Tree);
void CreatTree(TreeNode *Tree);
TreeNode * SearchTree(TreeNode *Tree,char name[] );
void OutPutMessage(TreeNode * Tree,char name[] );
void AddNew(TreeNode * Tree);
void AddNewMenue(TreeNode * Tree);
void OutPutAll(TreeNode *Tree);
void Change(TreeNode * Tree);
void ChangeMenue(TreeNode *Tree);
//主函数
int main()
{
TreeNode *Tree;
Tree=(TreeNode *)malloc(sizeof(TreeNode));
Tree->Parent =NULL;
strcpy(Tree->Name,"0");
MainMenue(Tree);
}
//添加新的成员
void AddNew(TreeNode * Tree)
{
AddNewMenue(Tree);
}
//添加个人信息菜单
void AddNewMenue(TreeNode *Tree)
{
char c;
int num;
char name[20];
char work[20];
char zaishishijian[20];
char shifouhaihuozhe[20];
getchar();
while(1)
{
system("cls");
printf("\t");
printf("\n\n\t ---*****---请选择你的操作---****---");
printf("\n\t---*---*---*---A:添加某个人的子女的信息---*---*---*---*----");
printf("\n\t---*---*---*---B:添加某个人配偶的信息-*---*---*---*---*----");
printf("\n\t---*---*---*---C:退出-*---*---*---*---*---*---*---*---*----\n\t");
c=getchar();
switch(c)
{
case 'A':
case 'a':
TreeNode * NewNode;
TreeNode * CurrNode;
CurrNode=(TreeNode *)malloc(sizeof(TreeNode));
CurrNode = NULL ;
printf("\n\n\t请输入那个人的名字:\n\t");
scanf("%s",name);
CurrNode=SearchTree(Tree,name );
if(CurrNode==NULL)
{
printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n",name);
break;
}
if( CurrNode->Parent==NULL&&CurrNode->NextNode[0]==NULL ||\
CurrNode->Parent!=NULL&&CurrNode->NextNode[0]==NULL&&CurrNode->Name!=CurrNode->Parent->NextNode[0]->Name )
{
printf("\n\n\t%s至今还没有配偶请先添加配偶",CurrNode->Name);
break;//退出
}
if(CurrNode->Parent==NULL&&(CurrNode->Num>20||CurrNode->Num<0))
CurrNode->Num=0;
if(MATEFLAG==1)
CurrNode=CurrNode->Parent;
NewNode=(TreeNode *)malloc(sizeof(TreeNode));
printf("\n\n\t请输入添加人员姓名:\n\t");
scanf("%s",name);//NewNode->Name
strcpy( NewNode->Name , name ) ;
printf("\n\n\t请输入添加人员工作:\n\t");
scanf("%s",work);//NewNode->Name
strcpy( NewNode->work , work ) ;
printf("\n\n\t请输入添加人员在世时间:\n\t");
scanf("%s",zaishishijian);//NewNode->Name
strcpy( NewNode->zaishishijian , zaishishijian ) ;
printf("\n\n\t请输入添加人员生死状态:\n\t");
scanf("%s",shifouhaihuozhe);//NewNode->Name
strcpy( NewNode->shifouhaihuozhe , shifouhaihuozhe ) ;
printf("\n\n\t请输入添加人员性别女G男B:\n\t");
scanf("%1s",&NewNode->Kind);
num=CurrNode->Num;
NewNode->NextNode[0]=(TreeNode *)malloc(sizeof(TreeNode));
NewNode->NextNode[0]=NULL;
NewNode->Num=0;
NewNode->Parent=CurrNode;
CurrNode->NextNode[num+1]=NewNode;
CurrNode->Num=num+1;
//free( CurrNode ) ;
// free( NewNode ) ;
printf("\n\n\t-------------子女的信息添加成功----------------");
break;
case 'B':
case 'b':
TreeNode * NewNode1;
TreeNode * CurrNode1;
CurrNode1=(TreeNode *)malloc(sizeof(TreeNode));
CurrNode1 = NULL ;
printf("\n\n\t请输入那个人的名字:\n\t");
scanf("%s",name);
CurrNode1 = SearchTree(Tree,name );
if(CurrNode1->Parent!=NULL&&strcmp(CurrNode1->Name,CurrNode1->Parent->NextNode[0]->Name)==0||CurrNode1->NextNode[0]!=NULL)
{
printf("\n\n\t已经有了配偶");
break;
}
if(CurrNode1==NULL)
{
printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n",name);
break;
}
NewNode1=(TreeNode *)malloc(sizeof(TreeNode));
printf("\n\n\t请输入添加人员姓名:\n\t");
scanf("%s",NewNode1->Name);
printf("\n\n\t请输入添加人员工作:\n\t");
scanf("%s",NewNode1->work);
printf("\n\n\t请输入添加人员在世时间:\n\t");
scanf("%s",NewNode1->zaishishijian);
printf("\n\n\t请输入添加人员生死状态:\n\t");
scanf("%s",NewNode1->shifouhaihuozhe);
if(CurrNode1->Kind == 'B' || CurrNode1->Kind == 'b' )
NewNode1->Kind='G' ;
else
NewNode1->Kind='B' ;
//上面的代码换下面2行的代码就不行,why?
/* printf("\n\n\t请输入添加人员性别女G男B:\n\t");
scanf("%1s",&NewNode1->Kind);
*/
NewNode1->Parent=CurrNode1;
CurrNode1->NextNode[0]=NewNode1;
//free( CurrNode1 ) ;
//free( NewNode1 ) ;
printf("\n\t-------------配偶信息添加成功----------------");
break;
case 'C':
case 'c':
printf("\n\n\t----------------本项服务到此结束-----------------");
break;
case '\n':
break;
default:
printf("\n\n\t--------对不起!你的选择不在服务范围之内!---------");
printf("\n\t-----------请您再次选择所需的服务项!-------------");
printf("\n\t------------------谢谢合作!----------------------\n\t");
break;
}//end switch
if (c=='C'||c=='c')
break;
printf("\n\n\t--------------请按Enter键继续操作--------------");
getchar();
getchar();
}//end while
return ;
}
//修改某个人的信息
void Change(TreeNode * Tree)
{
char name[20];
TreeNode * NewNode;
printf("\n\t请输入你要修改的人的名字:\n\t");
scanf("%s",name);
NewNode=SearchTree(Tree,name );//?
if(NewNode==NULL)
{
printf("\n\n\t****该家谱图中没有%s这个人的信息请确认是否输入错误*****\n",name);
return;
}
else
{
ChangeMenue(NewNode);
}
}
//修改个人信息菜单
void ChangeMenue(TreeNode * Tree)
{
char c;
int flag,i;
char name[20];
char work[20];
char zaishishijian[20];
char shifouhaihuozhe[20];
char Parent[2][20];
TreeNode * NewNode;
getchar();
while(1)
{
system("cls");
printf("\t");
printf("\n\n\t ---*****---请选择你的操作---****---");
printf("\n\t---*---*---*---A:修改个人的信息---*---*---*---*---*---*----");
printf("\n\t---*---*---*---B:修改父母的信息---*---*---*---*---*---*----");
printf("\n\t---*---*---*---C:修改兄弟姐妹的信息---*---*---*---*---*----");
printf("\n\t---*---*---*---D:修改子女的信息---*---*---*---*---*---*----");
printf("\n\t---*---*---*---E:修改配偶的信息---*---*---*---*---*---*----");
printf("\n\t---*---*---*---F:退出-*---*---*---*---*---*---*---*---*----\n\t");
c=getchar();
switch(c)
{
case 'A':
case 'a':
printf("\n\t请输入修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t");
scanf("%s",name);
if(strcmp(name,"0")!=0)
strcpy(Tree->Name,name);
printf("\n\t是否要修改性别:如果不需要修改就输入'0'然后按Enter键继续\n\t");
scanf("%d",&flag);
if (flag==1)
{
if(Tree->Kind=='G'||Tree->Kind=='g')
Tree->Kind='B';
else Tree->Kind='G';
}
printf("\n\t请输入修改的工作:如果不需要修改就输入‘0’然后按Enter键继续\n\t");
scanf("%s",work);
if(strcmp(work,"0")!=0)
strcpy(Tree->work,work);
printf("\n\t请输入修改的在世时间:如果不需要修改就输入‘0’然后按Enter键继续\n\t");
scanf("%s",zaishishijian);
if(strcmp(zaishishijian,"0")!=0)
strcpy(Tree->zaishishijian,zaishishijian);
printf("\n\t请输入修改的生死状态:如果不需要修改就输入‘0’然后按Enter键继续\n\t");
scanf("%s",shifouhaihuozhe);
if(strcmp(shifouhaihuozhe,"0")!=0)
strcpy(Tree->shifouhaihuozhe,shifouhaihuozhe);
printf("\n\t个人信息修改成功");
break;
case 'B':
case 'b':
if(Tree->Parent==NULL) //判断是不是头节点
{
printf("\n\t是这个家谱图里最顶端的人没有父母信息!",name);
break;
}
if (MATEFLAG==1) //判断是不是入赘或加入此间的
{
if(Tree->Kind=='G'||Tree->Kind=='g')
{
printf("\n\n\t她是嫁入此间的所以父母信息不在家谱内包括");
}
else
{
printf("\n\n\t他是入赘此间的所以父母信息不在家谱内包括");
}
break;
}
if(Tree->Parent->Kind=='G'||Tree->Parent->Kind=='g')
{
strcpy(Parent[0],"母亲");
strcpy(Parent[1],"父亲");
}
else
{
strcpy(Parent[0],"父亲");
strcpy(Parent[1],"母亲");
}
printf("\n\n\t请输入%s要修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[0]);
scanf("%s",name);
if(strcmp(name,"0")!=0)
strcpy(Tree->Parent->Name,name);
printf("\n\n\t请输入%s要修改的工作:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[0]);
scanf("%s",work);
if(strcmp(work,"0")!=0)
strcpy(Tree->Parent->work,work);
printf("\n\n\t请输入%s要修改的在世时间:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[0]);
scanf("%s",zaishishijian);
if(strcmp(zaishishijian,"0")!=0)
strcpy(Tree->Parent->zaishishijian,zaishishijian);
printf("\n\n\t请输入%s要修改的生死状态:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[0]);
scanf("%s",shifouhaihuozhe);
if(strcmp(shifouhaihuozhe,"0")!=0)
strcpy(Tree->Parent->shifouhaihuozhe,shifouhaihuozhe);
printf("\n\n\t请输入%s要修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[1]);
scanf("%s",name);
if(strcmp(name,"0")!=0)
strcpy(Tree->Parent->NextNode[0]->Name,name);
printf("\n\n\t请输入%s要修改的工作:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[1]);
scanf("%s",work);
if(strcmp(work,"0")!=0)
strcpy(Tree->Parent->NextNode[0]->work,work);
printf("\n\n\t请输入%s要修改的在世时间:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[1]);
scanf("%s",zaishishijian);
if(strcmp(zaishishijian,"0")!=0)
strcpy(Tree->Parent->NextNode[0]->zaishishijian,zaishishijian);
printf("\n\n\t请输入%s要修改的生存状态:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Parent[1]);
scanf("%s",shifouhaihuozhe);
if(strcmp(shifouhaihuozhe,"0")!=0)
strcpy(Tree->Parent->NextNode[0]->shifouhaihuozhe,shifouhaihuozhe);
printf("\n\n\t-------------父母的信息修改成功----------------");
break;
case 'C':
case 'c':
NewNode=Tree->Parent;
if(NewNode==NULL) //判断是不是头节点
{
printf("\n\t是这个家谱图里最顶端的人没有兄弟姐妹信息!",name);
break;
}
if (MATEFLAG==1) //判断是不是入赘或加入此间的
{
if(Tree->Kind=='G'||Tree->Kind=='g')
{
printf("\n\n\t她是嫁入此间的所以兄弟姐妹信息不在家谱内包括");
}
else
{
printf("\n\n\t他是入赘此间的所以兄弟姐妹信息不在家谱内包括");
}
break;
}
if(NewNode->Num==1)
{
printf("\n\n\t没有兄弟姐妹");
break;
}
else
{
for(i=1;i<=NewNode->Num;i++)
{
if(NewNode->NextNode[i]->Name!=Tree->Name )
{
printf("\n\t请输入%s修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",NewNode->NextNode[i]->Name);
scanf("%s",name);
if(strcmp(name,"0")!=0)
strcpy(NewNode->NextNode[i]->Name,name);
printf("\n\t请输入%s修改的工作:如果不需要修改就输入‘0’然后按Enter键继续\n\t",NewNode->NextNode[i]->Name);
scanf("%s",work);
if(strcmp(work,"0")!=0)
strcpy(NewNode->NextNode[i]->work,work);
printf("\n\t请输入%s修改的在世时间:如果不需要修改就输入‘0’然后按Enter键继续\n\t",NewNode->NextNode[i]->Name);
scanf("%s",zaishishijian);
if(strcmp(zaishishijian,"0")!=0)
strcpy(NewNode->NextNode[i]->zaishishijian,zaishishijian);
printf("\n\t请输入%s修改的生死状态:如果不需要修改就输入‘0’然后按Enter键继续\n\t",NewNode->NextNode[i]->Name);
scanf("%s",shifouhaihuozhe);
if(strcmp(shifouhaihuozhe,"0")!=0)
strcpy(NewNode->NextNode[i]->shifouhaihuozhe,shifouhaihuozhe);
printf("\n\n\t是否要修改性别:如果需要就输入'1'不需要修改就输入'0'然后按Enter键继续\n\t");
scanf("%d",&flag);
if (flag==1)
{
if(NewNode->NextNode[i]->Kind=='G'||NewNode->NextNode[i]->Kind=='g')
NewNode->NextNode[i]->Kind='B';
else NewNode->NextNode[i]->Kind='G';
}
}
}
}
printf("\n\n\t------------兄弟姐妹的信息修改成功-------------");
break;
case 'D':
case 'd':
if(Tree->Num==0)
{
printf("\n\n\t至今还没有子女");
break;
}
if (Tree->Parent !=NULL)
if (strcmp(Tree->Name,Tree->Parent->NextNode[0]->Name)==0) //如果他是入赘或者是嫁入的就需用配偶节点完成修改
{
Tree=Tree->Parent;
}
for(i=1;i<=Tree->Num;i++)
{
printf("\n\n\t请输入%s修改的姓名:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Tree->NextNode[i]->Name);
scanf("%s",name);
if(strcmp(name,"0")!=0)
strcpy(Tree->NextNode[i]->Name,name);
printf("\n\n\t请输入%s修改的工作:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Tree->NextNode[i]->Name);
scanf("%s",work);
if(strcmp(work,"0")!=0)
strcpy(Tree->NextNode[i]->work,work);
printf("\n\n\t请输入%s修改的在世时间:如果不需要修改就输入‘0’然后按Enter键继续\n\t",Tree->NextNode[i]->Name);
scanf("%s",zaishishijian);
if(strcmp(zaishishijian,"0")!=0)
strcpy(Tree->NextNode[i]->zaishishijian,zaishishijian);
printf("\n\n\t请输入%s修改的生死状态:如果不需要修改就输入‘0’然后按Ente