二叉树家谱图

题目要求

使用二叉树存储家谱,对家庭成员建立信息,并可以进行信息的查找,修改、删除等操作。基本功能如下:
1.建立家谱中每个成员的信息,包括姓名、性别、出生日期等。
2.家庭成员的添加,即添加某人的儿女,可通过控制台输入要添加的子女信息。
3.家庭成员的修改,可修改某一成员的姓名。
4.查询某一成员在家谱中的辈分(第几代)。

提示:
由于一个父节点可能有多个孩子 ,而二叉树最多只能表示两个孩子,因此可以使用左孩子右兄弟的表示方法,即一个节点有两个指针,左指针指向它的第一个孩子,右指针指向它的兄弟(即如下图1所示)。也可以用图2所示方法,父亲节点的左子节点表示妻子,右子节点表示其兄弟,妻子节点的右子节点表示儿子。
图1
图2

代码实现

#pragma once
#include<iostream>
#include<string>
using namespace std;
class Member
{
protected:
	string name;
	string gender;
	string birth;
	Member* root;
	Member* child;
	Member* sibling;

public:
	Member(string _name = "", string _gender = "Male", string _birth = "19800101",
		Member* _root = nullptr, Member* _child = nullptr, Member* _sibling = nullptr) :
		name(_name), gender(_gender), birth(_birth), root(_root), child(_child), sibling(_sibling)
	{}
	void addChild(string _name = "", string _gender = "Male", string _birth = "19800101");
	void addChild(Member* c);
	void addSibling(string _name = "", string _gender = "Male", string _birth = "19800101");
	void addSibling(Member* s);
	void modifyName(string _name);
	int getGeneration();
	string getName();
	string getGender();
	string getBirth();
	Member* getRoot();
	Member* getChild();
	Member* getSibling();
	void setName(string rename);
	void setGender(string regender);
	void setBirth(string rebirth);
	void show();
};


void Member::addChild(string _name, string _gender, string _birth)
{
	Member* newchild = new Member(_name, _gender, _birth);
	if (child == nullptr) {
		child = newchild;
		newchild->root = this;
	}
	else
	{
		Member* curchild = child;
		while (curchild != nullptr) {
			newchild->root = curchild;
			curchild = curchild->sibling;
		}
		curchild = newchild;
		newchild->root->sibling = newchild;
	}
}

void Member::addChild(Member* c)
{
	Member* newchild = c;
	if (child == nullptr) {
		child = newchild;
		newchild->root = this;
	}
	else
	{
		Member* curchild = child;
		while (curchild != nullptr) {
			newchild->root = curchild;
			curchild = curchild->sibling;
		}
		curchild = newchild;
		newchild->root->sibling = newchild;
	}
}

void Member::addSibling(string _name, string _gender, string _birth)
{
	Member* newsibling = new Member(_name, _gender, _birth);
	Member* cursibling = sibling;
	while (cursibling != nullptr) {
		newsibling->root = cursibling;
		cursibling = cursibling->sibling;
	}
	cursibling = newsibling;
}

void Member::addSibling(Member* s)
{
	Member* newsibling = s;
	Member* cursibling = sibling;
	while (cursibling != nullptr) {
		newsibling->root = cursibling;
		cursibling = cursibling->sibling;
	}
	cursibling = newsibling;
}

void Member::modifyName(string _name)
{
	name = _name;
}

int Member::getGeneration()
{
	int generation = 1;
	Member* cur = this;
	Member* last = root;
	while (last != nullptr)
	{
		if (last->child == cur)generation++;
		cur = last;
		last = last->root;
	}
	return generation;
}

string Member::getName()
{
	return name;
}

string Member::getGender()
{
	return gender;
}

string Member::getBirth()
{
	return birth;
}

Member* Member::getRoot()
{
	return root;
}

Member* Member::getChild() 
{
	return child;
}

Member* Member::getSibling()
{
	return sibling;
}

void Member::setName(string rename)
{
	name = rename;
}
void Member::setGender(string regender)
{
	gender = regender;
}
void Member::setBirth(string rebirth)
{
	birth = rebirth;
}

void Member::show()
{
	cout << "name:" << name << " gender:" << gender << " birth:" << birth;
	if(getRoot())
		cout<<" root:"<<getRoot()->getName()<< endl;
	else
		cout << " root: null" << endl;
}
#pragma once
#include"Member.h"
class FamilyTree
{
protected:
	Member* root;
public:
	FamilyTree() :root(nullptr) {}
	Member* getRoot();
	void setRoot(Member* node);
	void addMember(string parentName,Member* mperson);
	void deleteMember(string mname);
	void modifyMember(string mname);
	void checkMember(string mname);
	void traversal();
};

Member* findMember(Member* cur, string name);


Member* FamilyTree::getRoot()
{
	return root;
}

Member* findMember(Member* cur,string name)
{
	if (cur->getName() == name) return cur;

	if (cur->getChild()) {
		Member* m = findMember(cur->getChild(), name);
		if (m)return m;
	}
	if (cur->getSibling())  {
		Member* m = findMember(cur->getSibling(), name);
		if (m)return m;
	}

	return nullptr;
}

void FamilyTree::setRoot(Member* node)
{
	root = node;
}
void FamilyTree::addMember(string parentName, Member* mperson)
{
	if (root == nullptr) 
	{
		root = mperson;
		cout << "添加成员" << mperson->getName() << endl;
	}
	else {
		Member* parent = findMember(root, parentName);
		if (parent)
		{
			parent->addChild(mperson);
			cout << "添加成员" << mperson->getName() << endl;
		}
		else
		{
			cout << "父母不存在" << endl;
		}
	}
	
}
void FamilyTree::deleteMember(string mname)
{
	Member* m = findMember(root, mname);
	if (m)
	{
		cout << "删除成员" << m->getName() << endl;
		delete m;
	}
	else
		cout <<mname<< "不存在" << endl;
}
void FamilyTree::modifyMember(string mname)
{
	Member* m = findMember(root, mname);
	if (m)
	{
		string rename, regender, rebirth;
		cout << "请输入修改后的成员姓名:" << endl;
		cin >> rename;
		m->setName(rename);
		cout << "请输入修改后的成员性别:" << endl;
		cin >> regender;
		m->setGender(regender);
		cout << "请输入修改后的成员生日:" << endl;
		cin >> rebirth;
		m->setBirth(rebirth);
		cout << "修改成功!" << endl;
	}
	else
		cout << mname << "不存在" << endl;
}
void FamilyTree::checkMember(string mname)
{
	Member* m = findMember(root, mname);
	if (m)
	{
		cout << m->getName()<<"的性别是:" << m->getGender() << ",生日是:" << m->getBirth() << endl;
		cout << ((m->getGender()=="Male")?"他":"她")<<"在家族中的辈分是:" << m->getGeneration() << endl;
	}
	else
	{
		cout << mname << "不存在" << endl;
	}
}

void traval(Member* m) 
{
	if (m == nullptr)return;
	m->show();
	traval(m->getChild());
	traval(m->getSibling());
}

void FamilyTree::traversal()
{
	traval(root);
}
#include "Member.h"
#include "FamilyTree.h"

using namespace std;

bool checkBirth(const string birth)
{
	if (birth.length() > 8) return false;
	for (char c : birth) {
		if (c < '0' || c>'9')return false;
	}
	int month = (birth[4] - '0') * 10 + birth[5] - '0';
	if (month > 12 || month < 1) return false;
	int day = (birth[6] - '0') * 10 + birth[7] - '0';
	if (day > 31 || day < 1) return false;
	return true;
}

int main()
{
	char choose=0;
	FamilyTree family;
	string rootname, name, gender, birth;
	checkBirth("19600101");
	while (1)
	{
		cout << "请选择操作:" << endl;
		cout << "a:增加成员   b:删除成员   c:修改成员信息   d:查找成员  e:查看家谱  f:退出" << endl;
		cin >> choose;
		switch (choose)
		{
		case 'a':
			{
				cout << "请输入要添加的成员的父母的姓名:" << endl;
				cin >> rootname;
				if (family.getRoot()&&findMember(family.getRoot(), rootname) == nullptr) {
					cout << "父母不存在,请重新输入:" << endl;
					cin >> rootname;
				}
				cout << "请输入要添加的成员的姓名:" << endl;
				cin >> name;
				cout << "请输入要添加的成员的性别(Male/Female):" << endl;
				cin >> gender;
				if (gender != "Male" && gender != "Female") {
					cout << "输入错误,请重新输入(Male/Female):" << endl;
					cin >> gender;
				}
				cout << "请输入要添加的成员的生日(如19980102):" << endl;
				cin >> birth;//检查输入格式、日期正确性
				if (checkBirth(birth) == false) {
					cout << "输入错误,请重新输入(如19980102):" << endl;
					cin >> birth;
				}
				Member* newmember = new Member(name, gender, birth);
				family.addMember(rootname, newmember);
				break;
			}
		case 'b':
			cout << "请输入要删除的成员的姓名:" << endl;
			cin >> name;
			family.deleteMember(name);
			break;
		case 'c':
			cout << "请输入要修改的成员的姓名:" << endl;
			cin >> name;
			family.modifyMember(name);
			break;
		case 'd':
			cout << "请输入要查找的成员的姓名:" << endl;
			cin >> name;
			family.checkMember(name);
			break;
		case 'e':
			family.traversal();
			break;
		case 'f':
			exit(0);
			break;
		default:
			cout << "输入错误,请重新输入!" << endl;
			break;
		}
	}
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值