用二叉树链式存储结构来采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲选做功能: 1)查找某人的所有祖先 2)查找某人的所有兄弟界面
时间: 2023-11-22 17:54:06 浏览: 154
很好,这是一道很有挑战性的数据结构题目。下面是我的解答:
1. 文件存储格式设计
我们可以将每个节点的信息存储为一个结构体,然后用链式存储结构来表示整个家谱树。在文件中,我们可以将每个节点的信息依次存储下来,每行表示一个节点,不同字段之间用空格隔开,每个节点的子节点也按照同样的格式存储在文件中。如下所示:
```
张三 男 张媛 110101198001011234 40 1980-01-01
李四 女 李华 120101198101012345 10 2010-01-01
王五 男 王小丽 130101198201012345 8 2012-01-01
```
这个文件表示了一个家谱树,张三节点有两个子节点,分别是李四和王五,他们的信息也按照同样的格式存储在文件中。
2. 链表(孩子表示法)存储结构
我们可以定义一个节点结构体,包含所有的节点信息和一个指向子节点的指针,如下所示:
```
struct Node {
string name; // 姓名
string gender; // 性别
string spouse; // 配偶姓名
string id; // 身份证号
int age; // 年龄
string birth; // 出生日期
Node *child; // 指向子节点的指针
};
```
然后,我们可以定义一个家谱树类,其中包含一个指向根节点的指针和一些基本操作:
```
class FamilyTree {
public:
FamilyTree(); // 构造函数
~FamilyTree(); // 析构函数
void loadFromFile(string filename); // 从文件中加载家族信息
void saveToFile(string filename); // 将家族信息保存到文件中
void print(); // 输出家族信息
vector<Node*> findSons(string name); // 查找某人的所有儿子
vector<Node*> findParents(string name); // 查找某人的双亲
private:
Node *root; // 指向根节点的指针
void clear(Node *node); // 递归删除节点
};
```
3. 相关操作的实现
loadFromFile() 函数的实现如下:
```
void FamilyTree::loadFromFile(string filename) {
ifstream fin(filename);
string line;
stack<Node*> s; // 用栈来保存父节点
while (getline(fin, line)) {
int depth = 0; // 记录当前节点的深度
while (line[depth] == ' ') depth++; // 计算空格数
Node *node = new Node;
stringstream ss(line.substr(depth));
ss >> node->name >> node->gender >> node->spouse >> node->id >> node->age >> node->birth;
node->child = NULL;
if (depth == 0) { // 根节点
root = node;
s.push(node);
} else {
while (depth <= s.size()) s.pop(); // 弹出栈顶元素直到找到父节点
Node *parent = s.top();
if (parent->child == NULL) { // 第一个子节点
parent->child = node;
} else { // 后续子节点
Node *p = parent->child;
while (p->child != NULL) p = p->child;
p->child = node;
}
s.push(node);
}
}
fin.close();
}
```
saveToFile() 函数的实现如下:
```
void FamilyTree::saveToFile(string filename) {
ofstream fout(filename);
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node *node = q.front();
q.pop();
for (int i = 0; i < q.size(); i++) fout << " ";
fout << node->name << " " << node->gender << " " << node->spouse << " " << node->id << " " << node->age << " " << node->birth << endl;
Node *p = node->child;
while (p != NULL) {
q.push(p);
p = p->child;
}
}
fout.close();
}
```
print() 函数的实现如下:
```
void FamilyTree::print() {
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node *node = q.front();
q.pop();
cout << node->name << " " << node->gender << " " << node->spouse << " " << node->id << " " << node->age << " " << node->birth << endl;
Node *p = node->child;
while (p != NULL) {
q.push(p);
p = p->child;
}
}
}
```
findSons() 函数的实现如下:
```
vector<Node*> FamilyTree::findSons(string name) {
vector<Node*> sons;
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node *node = q.front();
q.pop();
Node *p = node->child;
while (p != NULL) {
if (p->gender == "男" && p->spouse == "" && node->name == name) {
sons.push_back(p);
}
q.push(p);
p = p->child;
}
}
return sons;
}
```
findParents() 函数的实现如下:
```
vector<Node*> FamilyTree::findParents(string name) {
vector<Node*> parents;
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node *node = q.front();
q.pop();
Node *p = node->child;
while (p != NULL) {
if (p->name == name) {
parents.push_back(node);
}
q.push(p);
p = p->child;
}
}
return parents;
}
```
4. 界面
界面可以用命令行实现,例如:
```
Welcome to family tree system!
1. Load family information from file
2. Save family information to file
3. Print family information
4. Find all sons of a person
5. Find all parents of a person
0. Quit
Please enter your choice: 1
Please enter the filename: family.txt
Load family information successfully!
Please enter your choice: 3
张三 男 张媛 110101198001011234 40 1980-01-01
李四 女 李华 120101198101012345 10 2010-01-01
王五 男 王小丽 130101198201012345 8 2012-01-01
Please enter your choice: 4
Please enter the person's name: 张三
李四 女 李华 120101198101012345 10 2010-01-01
王五 男 王小丽 130101198201012345 8 2012-01-01
Please enter your choice: 5
Please enter the person's name: 李四
张三 男 张媛 110101198001011234 40 1980-01-01
Please enter your choice: 0
Goodbye!
```
这样,我们就完成了这道数据结构题目的解答。
阅读全文