持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情
一、题目
描述
某一姓氏族谱系统
某一姓氏为了更好的理清各代人的关系传承,想请你为他们做一套族谱关系系统。系统要求:
1,每一个人信息包含姓名,性别,出生年月
2,可先序遍历整个族谱井列出所有的人
3,可添加某一个人进族谱
4,可删除某一个人
5. 给出某一个人,可列出其孩子和双亲
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
int generateId(){
static int id = 0;
++id;
return id;
}
struct Human{
Human* dad = nullptr;
Human* mom = nullptr;
vector<Human*> children;
Human(string name, string sex, string born): id(generateId()), name(name), sex(sex), born(born) {}
int id;
string name;
string sex;
string born;
};
void printAll(int ancestorDad){
}
void add(Human* child, int dad, int mom){
}
void remove(int id){
}
void printOne(int id){
}
int main(int, char*[])
{
Human ancestorDad("朱元璋", "男", "1328.10");
Human ancestorMom("孝慈高皇后", "女", "1332.08");
Human* child1 = new Human("朱标", "男", "1355.10");
Human* child2 = new Human("吕氏", "女", "1355.11");
Human* child3 = new Human("朱允炆", "男", "1377.12");
Human* child4 = new Human("朱棣", "男", "1360.05");
Human* child5 = new Human("明成祖仁孝皇后", "女", "1362.03");
Human* child6 = new Human("朱高炽", "男", "1378.08");
Human* child7 = new Human("诚孝张皇后", "女", "1380.03");
Human* child8 = new Human("朱瞻基", "男", "1399.03");
add(&ancestorDad, 0, 0);
add(&ancestorMom, 0, 0);
add(child1, ancestorDad.id, ancestorMom.id);
add(child2, 0, 0);
add(child3, child1->id, child2->id);
add(child4, ancestorDad.id, ancestorMom.id);
add(child5, 0, 0);
add(child6, child4->id, child5->id);
add(child7, 0, 0);
add(child8, child6->id, child7->id);
printAll(ancestorDad.id);
remove(child6->id);
printAll(ancestorDad.id);
printOne(child4->id);
return 0;
}
二、分析
由题意可知,姓氏族谱系统和二叉树结构非常像,每个该姓氏节点,除祖父节点外,必定有父母双亲两个节点指向他,不同的是,母亲节点是没有父母双亲节点的,而且父母双亲节点也可能指向多个子女节点,也就是说需要兼容一母多子,一夫多妻的情况。
题中规定要完成添加,删除,打印单个,打印所有四个功能。
添加功能比较简单,按部就班对节点属性进行赋值即可。
删除功能就比较复杂,删除一个节点,要考虑其是父亲节点还是母亲节点,删除父亲节点,就要删除他的所有妻子节点和所有孩子节点,而父亲节点并不直接指向母亲节点。删除母亲节点,要考虑其所有孩子节点。删除孩子节点,要考虑他的母亲节点是否还有孩子,因为没有孩子的母亲节点是不能单独存在于族谱上的。
打印单个功能比较简单,按部就班打印结构属性即可。
打印全部功能比较复杂,要考虑到一夫多妻,一母多子,妻子节点不能二次打印,所以在打印过程中需要加状态。
三、模拟
- 朱元璋
- 朱标的母节点-孝慈高皇后
- 朱标
- 朱允炆的母节点-吕氏
- 朱允炆
- 朱棣
- 朱高炽的母节点-明成祖仁孝皇后
- 朱高炽
- 朱瞻基的母节点-诚孝张皇后
- 朱瞻基
四、实现
struct Human{
Human* dad = nullptr;
Human* mom = nullptr;
vector<Human*> children;
Human(string name, string sex, string born): id(generateId()), name(name), sex(sex), born(born) {}
int id;
string name;
string sex;
string born;
bool printed = false;
};
static unordered_map<int, Human*> hashHuman;
void printAllDfs(Human* child){
if(!child->mom->printed){
child->mom->printed = true;
cout << "\n姓名:" << child->mom->name << ",性别:" << child->mom->sex << ",出生年月:" << child->mom->born << endl;
}
cout << "\n姓名:" << child->name << ",性别:" << child->sex << ",出生年月:" << child->born << endl;
for(Human* sun : child->children){
printAllDfs(sun);
}
for(Human* sun : child->children){
if(sun->mom->printed){
sun->mom->printed = false;
}
}
}
void printAll(int ancestorDad){
auto iter = hashHuman.find(ancestorDad);
Human* human = iter->second;
cout << "\n姓名:" << human->name << ",性别:" << human->sex << ",出生年月:" << human->born << endl;
for(Human* child : human->children){
printAllDfs(child);
}
for(Human* child : human->children){
if(child->mom->printed){
child->mom->printed = false;
}
}
}
void add(Human* child, int dad, int mom){
if(dad != 0){
auto iter = hashHuman.find(dad);
Human* dad = iter->second;
iter = hashHuman.find(mom);
Human* mom = iter->second;
child->dad = dad;
child->mom = mom;
dad->children.push_back(child);
mom->children.push_back(child);
}
hashHuman.insert(std::pair<int, Human*>(child->id, child));
}
void remove(int id){
auto iter = hashHuman.find(id);
Human* human = iter->second;
if(!human->children.empty()){
if(human->sex == "女"){
remove(human->children.at(0)->dad->id);
return;
}
for(Human* child : human->children){
remove(child->id);
}
}
if(human->dad){
for(int i = human->dad->children.size() - 1; i >= 0; --i){
if(human->dad->children.at(i)->id == human->id){
human->dad->children.erase(std::begin(human->dad->children) + i);
break;
}
}
for(int i = human->mom->children.size() - 1; i >= 0; --i){
if(human->mom->children.at(i)->id == human->id){
human->mom->children.erase(std::begin(human->mom->children) + i);
break;
}
}
if(human->mom->children.empty()){
delete human->mom;
}
}
delete human;
}
void printOne(int id){
auto iter = hashHuman.find(id);
Human* human = iter->second;
cout << "\n姓名:" << human->name << ",性别:" << human->sex << ",出生年月:" << human->born << endl;
}
五、结言
族谱系统与常见树结构不同,特定问题,特殊解决。
创作不易,留个赞再走吧!如果对文章内容有任何指正,欢迎评论!