⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 home.h

📁 红楼梦贾氏家族人物谱  V1.0.rar
💻 H
📖 第 1 页 / 共 2 页
字号:
#include<iostream.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define namelength  6
#define length 7
#include <conio.h>
#include <process.h>

typedef struct homeperson{//个人结点
	char *name;//姓名
	char *bymd;//出生年月日
	char *dymd;//逝世年月日
	char marry;//婚否
	char living;//健在否
	char mother;//母亲,因为其父可能有一妻一妾,0表示文件中没有显示其母亲,1表示其母为其父之妻,2表示其母为其父之妾
	char distinction;//性别
	char generation;//第几代
	int ID;
	homeperson *child,*lover1,*lover2,*father,*lmates,*nmates;//链接,表示最大孩子,爱人,妾,父亲,最小兄姐,最大弟弟或妹妹
}*people;

typedef struct node{//队列结点
	homeperson *point;//存放人员指针
	node   *next;//指向队列在下一个结点
}linknode;

struct stack{//栈
	people *top;//栈顶
	people *bottom;//栈底
};

stack homeS;//全局变量
bool sinit( ){//初始化栈
	homeS.top=new people[50];//栈以数组形式存储
	if(!homeS.top)
		return false;
	homeS.bottom=homeS.top;
	return true;
}

bool homepop(homeperson *&p){//homepop
	if(homeS.top==homeS.bottom)
		return false;
	else
		p=*homeS.bottom;
	homeS.bottom--;
	return true;
}

bool homepush(homeperson *p){//homepush
	if((homeS.bottom-homeS.top)>=39)
		return false;
	else
		homeS.bottom++;
	*homeS.bottom=p;
	return true;
}

bool stackempty(  ){//判断栈是否为空
	if(homeS.top==homeS.bottom)
		return true;
	else
		return false;
}   

bool gettop(homeperson *&p){//取栈顶元素
	if(stackempty()){
		p=NULL;
		return false;
	}
	p=*homeS.bottom;
	return true;
}

bool destorys( ){//销毁栈
	delete []homeS.top;
	return true;
}

struct queue{//队列
	node *front;//头
	node *rear;//尾
};
queue homeQ;//全局变量

bool qinit( ){//队列初始化
	homeQ.front=new node;//为头分配一个指针
	if(!homeQ.front) return false;
	homeQ.front->next=NULL;//next置空
	homeQ.rear=homeQ.front;//头尾共处
	return true;
}

bool inqueue(homeperson *p){//进队
	node *q;
	q=new node;
	if(!q) 	return false;
	q->point=p;
	q->next=NULL;
	homeQ.rear->next=q;
	homeQ.rear=q;
	return true;
}

bool dequeue(homeperson *&p){//出队
	if(homeQ.front==homeQ.rear){
		p=NULL;
		return false;
	}
	node *r=homeQ.front->next;
	p=r->point;
	homeQ.front->next=r->next;
	if(homeQ.front->next==NULL)//特殊情况,栈已为空
		homeQ.rear=homeQ.front;
	delete r;
	return true;
}

bool qempty(){//判断队列是否为空
	if(homeQ.front==homeQ.rear)
		return true;
	else
		return false;
}

bool clears(  ){//清空栈
	homeS.bottom=homeS.top;
	return true;
}

bool clear(){//清空队列
	node *r,*q;
	if(homeQ.front==homeQ.rear)
		return true;
	else{
		r=homeQ.front->next;
		while(r){
			q=r;
			r=r->next;
			delete q;
		}
		homeQ.rear=homeQ.front;
	}
	return true;
}

bool qdestory(){//释放队列中所有结点
	node *r,*q;
	if(homeQ.front==homeQ.rear){
		delete homeQ.front;
	}
	else{
		r=homeQ.front;
		while(r!=NULL){
			q=r;
			r=r->next;
			delete q;
		}
	}
	return true;
}

class home{//家族类
private:
	int totalnumber;//总人数
	int generations;//总代数
	int womennumber;//女性人数
public:
	homeperson *ancestors;//祖
	home(){
		init( );
	}
	bool init( );//调用文件,在读取数据的同时,将树建好;
	bool insert(char name[],char mothername[],char sex,char bymd[]);
	bool insertmarry(char name[],char husbandname[],char bymd[]);
	void printheadline(){
		cout<<"姓名 第几代 父亲   母亲 出生     性别 最小兄姐 婚 偶   妾    长子 健在 死亡";
	}
	bool seek(homeperson *&q,char *name);   //按姓名查找人,并以q返回其指针
	bool gseek(char generation,people gs[],int &i);     //按代查找
	bool dseek(char distinction,people ds[],int &i);    //按性别查找
	bool lseek(char living,people ls[],int &i);     //按是否死亡查找
	bool modify(people p,int j,char info[]);     //修改某人资料
	int  treehigh(homeperson *q);    //计算出树高
	bool out(int &generation);   //为输入出总代数提供一个接口
	bool relation(people q,people p,CString &rela);       //找出两个人之间的关系
	bool initperson(homeperson *p);    //将一个人所包函的所有指针设置为空
	bool destoryperson(homeperson *&P);
	bool printperson(homeperson *r);   //在屏幕上打印一个人的信息
	bool printhome();              //在屏幕上打印整个家族
	bool makefile();               //将内存中的信息进行存盘
	bool writeperson(homeperson *p,FILE *fp);     //将一个人在内存中的信息输出到一个文件
	int  rank(homeperson *q);         //计算出此人的排行
	int  compare(homeperson *p,homeperson *q);    //比较两个人的大小


	friend bool inqueue(homeperson *p);
	friend bool homepush(homeperson *p);
	bool exist(){
		if(ancestors)
			return true;
		else 
			return false;
	}
	~home();//析构
};

bool home::seek(homeperson *&q,char *name){//按姓名查找人,并以q返回其指针
	homeperson *p;
	q=NULL;
	clear( );
    sinit( );
	qinit( );
	homepush(ancestors);
	while(!stackempty()){//以中序遍列执行;
		while(gettop(p)&&p) homepush(p->child);
		homepop(p);//将空出栈
		if(!stackempty()){
			homepop(p);
			if(strcmp(name,p->name)==0){
				q=p;
				clears( );//为下次执行seek,所以要进行清空处理
				return true;
			}
			if(p->lover1)//lover1,lover2为附带节点,不入栈,但需进行比较;
				if(strcmp(name,p->lover1->name)==0){
				q=p->lover1;
				clears( );//为下次执行seek,所以要进行清空处理
				return true;
				}
			if(p->lover2)
				if(strcmp(name,p->lover2->name)==0){
				q=p->lover2;
				clears( );//为下次执行seek,所以要进行清空处理
				return true;
				}
			homepush(p->nmates);//右孩子进栈
		}
	}
	return false;
}

bool home::init(){     //调用文件,在读取数据的同时,将树建好;
	FILE *fp;     //fp为家谱文件,fp1为记录文件名的文件
	char *home;
	char flag='y',ch,e=15;   //flag,use都是用以供用户选择
	char temp[20];
	char *name;
	int i=1;
	home=NULL;
	homeperson *q,*p;
	ancestors=NULL;
	totalnumber=home::womennumber=0; //初始化为0
	if((fp=fopen("home.txt","r+"))==NULL){ }  //打开记录文件名的文件	
	else
	{
		//文件存在则让用户选择用原文件,还是启用新的家谱文件
		//读取并输出文件名。
	}
	ch=fgetc(fp);
    while(ch!=EOF){//开始读取人员资料
		if(ch=='!'){
			//开始读一个人的资料
			q=new homeperson;
			home::initperson(q);
			home::totalnumber++;
			if(!q)
				return false;
			q->name=new char[length];
			//读姓名
			fread(q->name,namelength,1,fp);
			q->name[6]='\0';
//			cout<<q->name<<endl;
            //读代数
			q->generation=fgetc(fp);//读代数
			//以下为读父亲的姓名
			name=new char[length];
			fread(name,namelength,1,fp);
			if(name[0]=='0'){
				q->father=NULL;
			}
			else{
				name[6]='\0';
			    seek(p,name);
				if(!p->child){
					p->child=q;
				}
				q->father=p;
			}
			delete []name;
			//读出生年月日
			q->bymd=new char[9];
			fread(q->bymd,8,1,fp);
			q->bymd[8]='\0';
            //读性别
			q->distinction=fgetc(fp);
			if(q->distinction=='f')
				home::womennumber++;
			if(q->generation=='0'&& q->distinction=='m'){
				ancestors=q;
			}
			//读兄或姐
			name=new char[length];
			fread(name,namelength,1,fp);
			if(name[0]=='0'){
				delete []name;
			}
			else{
				name[6]='\0';
				seek(p,name);
				p->nmates=q;
				q->lmates=p;
			}
			q->mother=fgetc(fp);
			//读是否已婚
			q->marry=fgetc(fp);
			if(q->marry=='n'||q->distinction=='m'){//否,则无偶,或为女性时,不读
				fread(temp,6,1,fp);
			}				
			else{//是,则读偶
                name=new char[length];//读丈夫
			    fread(name,namelength,1,fp);
				if(name[0]=='0'){
					q->lover1=NULL;
				}
				else{
					name[6]='\0';
					seek(p,name);
					if(p->lover1)
						p->lover2=q;
					else
						p->lover1=q;
//					cout<<"夫"<<p->name;
					q->lover1=p;
				}
				q->lover2=NULL;
				delete []name;				
			}//else
			q->living=fgetc(fp);//读是否健在
///			cout<<"健"<<q->living<<" ";
			if(q->living=='y')
				q->dymd=NULL;
			else{//不在,读逝世日期
				q->dymd=new char[9];
				q->dymd[8]='\0';
				fread(q->dymd,8,1,fp);
			}//else
			generations=q->generation-48;
		}//if
		ch=fgetc(fp);
	}//while


//To Do
//	cout<<endl<<"数据调用完成,";
//	cout<<"本家族中共有"<<home::generations<<"代"<<home::totalnumber<<"人,其中女性"<<home::womennumber<<"人,下面进入功能区。"<<endl; ;
    fclose(fp);
	return true;
}

bool home::insert(char name[],char mothername[],char sex,char bymd[])
{//增加新人
	char flag='y';
	homeperson *q,*p,*r;
	q=new homeperson;
	home::initperson(q);
	q->name=name;
	q->bymd=bymd;
	//ToDo
	if(q){//出生
		q->distinction=sex;
		if(q->distinction=='f')
			home::womennumber++;
		while(flag=='y'){	
			if(seek(r,mothername)&&r->distinction=='f'){
				p=r->lover1;
				if(p->lover1==r)
					q->mother='1';
				else
					q->mother='2';
				q->father=p;
				q->generation=p->generation+1;
				if(home::generations=p->generation-48)
					home::generations++;
				if(p->child){
					p=p->child;
					while(p->nmates)
						p=p->nmates;
					p->nmates=q;
					q->lmates=p;
				}
				else{
					p->child=q;
					q->lmates=NULL;
				}
				 flag='n';
				 q->marry='n';
				 q->living='y';
				 q->lover1=q->lover2=q->nmates=NULL;
				 q->dymd=NULL;
				 home::totalnumber++;
			}//if
			else
			{
				return false;				
			}//else
		}//while
	}//if
	return true;
}

bool home::insertmarry(char name[],char husbandname[],char bymd[]){//增加新人
	homeperson *q,*p; 
	q=new homeperson;
	home::initperson(q);
	q->name=name; 
    q->bymd=bymd;
	if(q)
	{//迎娶
	 //迎娶在以往家族中皆为女性外嫁
			if(seek(p,husbandname)){//建立关系
				if(p->lover1)
					p->lover2=q;
				else
					p->lover1=q;
				 q->lover1=p;
				 p->marry='y';
				 q->lover2=q->father=q->nmates=q->lmates=q->child=NULL;
				 q->marry='y';
				 q->living='y';
				 q->distinction='f';//自动给出性别
				 home::totalnumber++;
				 home::womennumber++;
				 q->generation=p->generation;
			}//if
			else
			{				
				return false;				
			}//else
	}
	return true;
}

bool home::destoryperson(homeperson *&p){//销毁人员,用于析构。
	delete []p->name;
	delete []p->bymd;
    if(p->living=='y')
		delete p->dymd;
	delete p;
	return true;
}


home::~home(){//析构
	homeperson *p;
	homepush(ancestors);
	while(!stackempty()){
		while(gettop(p)&&p) homepush(p->child);
		homepop(p);
		if(!stackempty()){
			homepop(p);
			if(p->lover1){
				destoryperson(p->lover1);				
			}
			if(p->lover2)
				destoryperson(p->lover2);    
			homepush(p->nmates);
			destoryperson(p);
		}
	}

}

bool home::initperson(homeperson *q){//将一个人所包函的所有指针设置为空,及部分信息初始化
	if(!q)
		return false;
	else{
		q->name=q->bymd=q->dymd=NULL;
		q->child=q->father=q->nmates=q->lmates=q->lover1=q->lover2=NULL;
		q->living='y';
		q->marry='n';
		q->mother='0';
		return true;
	}
}

bool home::printperson(homeperson *r){//在屏幕上打印一个人的信息
	if(r==NULL){
		return false;
	}
	else{
		cout<<endl<<r->name<<"   "<<r->generation<<" ";
		if(r->father)
			cout<<"  "<<r->father->name;
		else
			cout<<"        ";
		if(r->mother=='0')
			cout<<"        ";
		else{
			if(r->mother=='1')
				cout<<"  "<<r->father->lover1->name;
			else
				cout<<"  "<<r->father->lover2->name;
		}
		cout<<"  "<<r->bymd;
		cout<<"   "<<r->distinction;
		if(r->lmates)
			cout<<"    "<<r->lmates->name;
		else
		    cout<<"          ";		
		cout<<"    "<<r->marry<<" ";
		if(r->lover1){//cout<<"lover1";
			cout<<r->lover1->name<<" ";
		}
		else{
			cout<<"       ";
		}
		if(r->lover2){//cout<<"lover2";
			cout<<r->lover2->name;
		}
		else{
			cout<<"      ";
		}
		if(r->child){
			cout<<"  "<<r->child->name;
		}
		else{
			cout<<"        ";
		}
		cout<<r->living;
		if(r->living=='n')
			cout<<"  "<<r->dymd<<"  ";
	}
	return true;
}

bool home::gseek(char generation,people gs[],int &i){//按代查找
	i=0;
	if(generation>57||generation<48)//本程序中暂时不支持超进9代的家族,不过作者认为要支持也很简单,不过程序编完大面积地改有点吃力,所有没有作修改
		return false;
	homeperson *r;
	clear();
	if(!ancestors)
		return false;		
	inqueue(ancestors);
	while(!qempty()){//以队列形式查找
		dequeue(r);
		if(r->generation==generation){
			gs[i]=r;
			i++;
			if(r->lover1)
			{
				gs[i]=r->lover1;
			    i++;
			}
			if(r->lover2)
			{
				gs[i]=r->lover2;
			    i++;
			}
		}
		if(r->child){
			inqueue(r->child);
			r=r->child;
		    while(r->nmates){
			inqueue(r->nmates);
			r=r->nmates;		
			}
		}		
	}
	clear( );
	return true;
}

bool home::dseek(char distinction,people ds[],int &i){//按性别查找
	homeperson *r;
	clear();
	i=0;//记录人数
	if(!ancestors)
		return false;		
	inqueue(ancestors);
	while(!qempty()){//查找方法与代相同
		dequeue(r);
		if(r->distinction!=distinction){			
			if(r->lover1)
			{				
				ds[i]=r->lover1;
				i++;
			}
			
			if(r->lover2)
			{
				ds[i]=r->lover2;
				i++;
			}
		}
		else
		{
			if(r!=ancestors)
			{
				ds[i]=r;
				i++;
			}
		}
		if(r->child){
			inqueue(r->child);
			r=r->child;
		    while(r->nmates){
			inqueue(r->nmates);
			r=r->nmates;		
			}
		}		
	}
	clear( );
	return true;
}
void getmini(people p,CString str)
{
	CString str2;
	str2.Format("姓名  %s    ",p->name);
	str+=str2;
	if(p->distinction=='f')
		str+="女";
	else
		str+="男";
	str+="\r\n";
}

bool home::lseek(char living,people ls[],int &i){//按是否死亡查找
	homeperson *r;
	clear();
	i=0;//记录人数
	if(!ancestors)
		return false;		
	inqueue(ancestors);
	while(!qempty()){//查找方法也与代的查找方法相同
		dequeue(r);
		if(r!=ancestors&&r->living==living)
		{
			ls[i]=r;
			i++;
		}
		if(r->lover1&&r->lover1->living==living)
		{
			
			ls[i]=r->lover1;
			i++;
		}
		if(r->lover2&&r->lover2->living==living)
		{
			
			ls[i]=r->lover2;
			i++;
		}
		if(r->child){
			inqueue(r->child);
			r=r->child;
		    while(r->nmates){
			inqueue(r->nmates);
			r=r->nmates;		
			}
		}		
	}
	clear( );
	return true;
}

bool home::modify(people p,int j,char info[]){//修改某人资料
	homeperson *r;
	char c;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -