C++实现一个家谱管理系统: (1)建立家族关系并能存储到文件中。 (2)实现家族成员的添加、删除功能。 (3)可以查询家族成员的父亲、祖先、 兄弟、儿子和后代信息。 (4)先序遍历输出家谱信息(树的遍历操作)、以树型结构输出家谱资料

时间: 2024-05-02 11:16:59 浏览: 11
好的,我可以为您提供一个家谱管理系统的C++实现,具体实现如下: ```c++ #include <iostream> #include <fstream> #include <sstream> #include <vector> using namespace std; // 定义家族成员结构体 struct Member { string name; // 成员姓名 int generation; // 辈分 vector<Member*> children; // 子女 Member* parent; // 父亲 Member(string n, int g) : name(n), generation(g), parent(nullptr) {} }; // 定义家族类 class FamilyTree { private: Member* root; // 家族树根节点 vector<Member*> members; // 家族成员列表 // 递归查找指定姓名的成员节点 Member* findMember(string name, Member* node) { if (node == nullptr) { // 节点为空,返回nullptr return nullptr; } if (node->name == name) { // 找到节点,返回节点指针 return node; } // 递归在子节点中查找 for (auto child : node->children) { Member* res = findMember(name, child); if (res != nullptr) { return res; } } // 未找到节点,返回nullptr return nullptr; } // 先序遍历家族树 void preOrderTraversal(Member* node, stringstream& ss) { if (node == nullptr) { return; } // 输出节点信息 ss << "- " << node->name << " (第" << node->generation << "代)" << endl; // 递归遍历子节点 for (auto child : node->children) { preOrderTraversal(child, ss); } } public: // 构造函数 FamilyTree() : root(nullptr) {} // 从文件读取家族树 void loadFromFile(string filename) { ifstream ifs(filename); if (!ifs) { cerr << "无法打开文件" << filename << endl; return; } string line; while (getline(ifs, line)) { // 解析每行数据 stringstream ss(line); string name, parentName; int generation; ss >> name >> generation >> parentName; // 如果是根节点,创建根节点 if (parentName == "-") { root = new Member(name, generation); members.push_back(root); } else { // 查找父节点 Member* parent = findMember(parentName, root); if (parent == nullptr) { cerr << "未找到父节点:" << parentName << endl; continue; } // 创建子节点并添加到父节点的子女列表中 Member* child = new Member(name, generation); members.push_back(child); child->parent = parent; parent->children.push_back(child); } } ifs.close(); } // 保存家族树到文件 void saveToFile(string filename) { ofstream ofs(filename); if (!ofs) { cerr << "无法打开文件" << filename << endl; return; } // 先序遍历家族树,输出到文件中 stringstream ss; preOrderTraversal(root, ss); ofs << ss.str(); ofs.close(); } // 添加家族成员 void addMember(string name, int generation, string parentName) { // 查找父节点 Member* parent = findMember(parentName, root); if (parent == nullptr) { cerr << "未找到父节点:" << parentName << endl; return; } // 创建子节点并添加到父节点的子女列表中 Member* child = new Member(name, generation); members.push_back(child); child->parent = parent; parent->children.push_back(child); } // 删除家族成员 void removeMember(string name) { // 查找节点 Member* node = findMember(name, root); if (node == nullptr) { cerr << "未找到成员:" << name << endl; return; } // 从父节点的子女列表中删除节点 auto& siblings = node->parent->children; siblings.erase(remove(siblings.begin(), siblings.end(), node), siblings.end()); // 删除节点及其子节点 for (auto child : node->children) { removeMember(child->name); } members.erase(remove(members.begin(), members.end(), node), members.end()); delete node; } // 查询家族成员的父亲 Member* getFather(string name) { Member* node = findMember(name, root); if (node != nullptr && node->parent != nullptr) { return node->parent; } return nullptr; } // 查询家族成员的祖先 vector<Member*> getAncestors(string name) { vector<Member*> res; Member* node = findMember(name, root); while (node != nullptr && node->parent != nullptr) { node = node->parent; res.push_back(node); } return res; } // 查询家族成员的兄弟 vector<Member*> getSiblings(string name) { vector<Member*> res; Member* node = findMember(name, root); if (node == nullptr || node->parent == nullptr) { return res; } for (auto child : node->parent->children) { if (child != node) { res.push_back(child); } } return res; } // 查询家族成员的儿子 vector<Member*> getChildren(string name) { Member* node = findMember(name, root); if (node != nullptr) { return node->children; } return vector<Member*>(); } // 查询家族成员的后代 vector<Member*> getDescendants(string name) { vector<Member*> res; Member* node = findMember(name, root); if (node != nullptr) { // 递归查找子孙节点 for (auto child : node->children) { res.push_back(child); auto descendants = getDescendants(child->name); res.insert(res.end(), descendants.begin(), descendants.end()); } } return res; } // 输出家族树 void printTree() { stringstream ss; preOrderTraversal(root, ss); cout << ss.str(); } }; int main() { FamilyTree ft; ft.loadFromFile("family.txt"); ft.printTree(); cout << "添加成员:张三 (第2代),父亲为王五" << endl; ft.addMember("张三", 2, "王五"); cout << "删除成员:李四" << endl; ft.removeMember("李四"); cout << "查询成员:王五 的父亲:" << (ft.getFather("王五") ? ft.getFather("王五")->name : "未知") << endl; auto ancestors = ft.getAncestors("王五"); cout << "查询成员:王五 的祖先:" << endl; for (auto ancestor : ancestors) { cout << "- " << ancestor->name << endl; } auto siblings = ft.getSiblings("王五"); cout << "查询成员:王五 的兄弟:" << endl; for (auto sibling : siblings) { cout << "- " << sibling->name << endl; } auto children = ft.getChildren("王五"); cout << "查询成员:王五 的儿子:" << endl; for (auto child : children) { cout << "- " << child->name << endl; } auto descendants = ft.getDescendants("王五"); cout << "查询成员:王五 的后代:" << endl; for (auto descendant : descendants) { cout << "- " << descendant->name << endl; } ft.saveToFile("family_new.txt"); return 0; } ``` 使用方法: 1. 将家族关系存储到文件 `family.txt` 中,每行数据表示一个成员,格式为 `姓名 辈分 父亲姓名`,根节点的父亲姓名用 `-` 表示。 2. 运行程序,程序读取 `family.txt` 文件中的数据,构建家族树。 3. 可以使用 `addMember()` 方法添加新成员,使用 `removeMember()` 方法删除成员。 4. 可以使用 `getFather()` 方法查询成员的父亲,使用 `getAncestors()` 方法查询成员的祖先,使用 `getSiblings()` 方法查询成员的兄弟,使用 `getChildren()` 方法查询成员的儿子,使用 `getDescendants()` 方法查询成员的后代。 5. 可以使用 `printTree()` 方法输出家族树,使用 `saveToFile()` 方法将家族树保存到文件中。

相关推荐

最新推荐

recommend-type

C++实现病人就医管理系统

主要为大家详细介绍了C++语言实现病人就医管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

C++读取WAV音频文件的头部数据的实现方法

主要介绍了C++读取WAV音频文件的头部数据的实现方法的相关资料,希望通过本文能帮助到大家,让大家实现这样的方法,需要的朋友可以参考下
recommend-type

C++实现数据文件存储与加载

主要为大家详细介绍了C++实现数据文件存储与加载,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

C++ 学生成绩管理系统设计报告书

内含4个类,各自具有其属性和行为。 基本实现了: (1)学生基本信息、考试科目及成绩的信息录入。 (2)已有学生信息的显示。 (3)学生基本信息的读取和保存输入数据等功能 (4)学生基本信息的查询与修改。可以对已有的...
recommend-type

基于C++实现读取指定路径文件

主要介绍了基于C++实现读取指定路径文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

可见光定位LED及其供电硬件具体型号,广角镜头和探测器,实验设计具体流程步骤,

1. 可见光定位LED型号:一般可使用5mm或3mm的普通白色LED,也可以选择专门用于定位的LED,例如OSRAM公司的SFH 4715AS或Vishay公司的VLMU3500-385-120。 2. 供电硬件型号:可以使用常见的直流电源供电,也可以选择专门的LED驱动器,例如Meanwell公司的ELG-75-C或ELG-150-C系列。 3. 广角镜头和探测器型号:一般可采用广角透镜和CMOS摄像头或光电二极管探测器,例如Omron公司的B5W-LA或Murata公司的IRS-B210ST01。 4. 实验设计流程步骤: 1)确定实验目的和研究对象,例如车辆或机器人的定位和导航。
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。