用C语言:采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲 输出形式要有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构: 学生自己根据系统功能要求自己设计,但是要求家谱系统的相关数据要存储在数据文件中。
时间: 2023-12-14 12:39:47 浏览: 78
为了实现这个家谱关系的系统,我们可以定义以下结构体来存储每个人的信息:
```c
struct Person {
char name[20]; // 姓名
char gender[5]; // 性别
char spouse[20]; // 配偶姓名
char id[20]; // 身份证号
int age; // 年龄
char birthdate[20]; // 出生日期
struct ChildNode *child; // 孩子链表
};
```
其中 `child` 是指向孩子链表的指针,我们再定义一个 `ChildNode` 结构体来表示孩子链表中的每个节点:
```c
struct ChildNode {
struct Person *person; // 子节点指向的人
struct ChildNode *next; // 下一个子节点
};
```
现在我们可以开始实现相关功能了。首先是输入家族信息,我们可以从文件中读取每个人的信息,然后根据他们之间的关系构建家谱树。可以定义一个 `load_data` 函数来读取文件并构建家谱树:
```c
void load_data(struct Person **root, const char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("Failed to open file %s\n", filename);
return;
}
// 读取每个人的信息
while (!feof(fp)) {
struct Person *person = malloc(sizeof(struct Person));
fscanf(fp, "%s %s %s %s %d %s", person->name, person->gender, person->spouse, person->id, &person->age, person->birthdate);
person->child = NULL;
// 构建家谱树
char father_name[20], mother_name[20];
fscanf(fp, "%s %s", father_name, mother_name);
if (strcmp(father_name, "-") == 0 && strcmp(mother_name, "-") == 0) {
// 没有父母,是根节点
*root = person;
} else {
// 找到父母节点,并将当前节点加入父母节点的孩子链表中
struct Person *father = find_person(*root, father_name);
struct Person *mother = find_person(*root, mother_name);
if (father != NULL) {
add_child(father, person);
}
if (mother != NULL) {
add_child(mother, person);
}
}
}
fclose(fp);
}
```
接下来是输出家族信息,我们可以定义一个 `print_tree` 函数来按照树的结构输出每个人的信息:
```c
void print_tree(struct Person *root, int level) {
if (root == NULL) {
return;
}
// 输出当前节点的信息
for (int i = 0; i < level; i++) {
printf(" ");
}
printf("%s (%s, %d)\n", root->name, root->gender, root->age);
// 输出孩子节点的信息
struct ChildNode *child = root->child;
while (child != NULL) {
print_tree(child->person, level + 1);
child = child->next;
}
}
```
然后是查找某人的所有儿子,我们可以定义一个 `find_sons` 函数来查找某个人的所有儿子并输出他们的信息:
```c
void find_sons(struct Person *root, const char *name) {
struct Person *person = find_person(root, name);
if (person != NULL) {
struct ChildNode *child = person->child;
while (child != NULL) {
if (strcmp(child->person->gender, "M") == 0) {
printf("%s\n", child->person->name);
}
child = child->next;
}
} else {
printf("Person %s not found\n", name);
}
}
```
最后是查找某人的双亲,我们可以定义一个 `find_parents` 函数来查找某个人的父母并输出他们的信息:
```c
void find_parents(struct Person *root, const char *name) {
struct Person *person = find_person(root, name);
if (person != NULL) {
struct ChildNode *child = person->child;
while (child != NULL) {
if (strcmp(child->person->gender, "M") == 0) {
printf("%s\n", child->person->name);
} else {
printf("%s\n", child->person->name);
}
child = child->next;
}
} else {
printf("Person %s not found\n", name);
}
}
```
最后,我们还需要实现几个辅助函数来操作家谱树:
```c
// 根据姓名查找某个人
struct Person *find_person(struct Person *root, const char *name) {
if (root == NULL) {
return NULL;
}
if (strcmp(root->name, name) == 0) {
return root;
} else {
struct ChildNode *child = root->child;
while (child != NULL) {
struct Person *person = find_person(child->person, name);
if (person != NULL) {
return person;
}
child = child->next;
}
return NULL;
}
}
// 将一个孩子节点加入父母节点的孩子链表中
void add_child(struct Person *parent, struct Person *child) {
struct ChildNode *node = malloc(sizeof(struct ChildNode));
node->person = child;
node->next = parent->child;
parent->child = node;
}
```
最后,我们可以定义一个 `main` 函数来实现菜单界面并调用上述函数:
```c
int main() {
struct Person *root = NULL;
load_data(&root, "family.dat");
int choice;
char name[20];
do {
printf("\n1. Print family tree\n");
printf("2. Find sons of a person\n");
printf("3. Find parents of a person\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("\nFamily tree:\n");
print_tree(root, 0);
break;
case 2:
printf("\nEnter name of the person: ");
scanf("%s", name);
printf("\nSons of %s:\n", name);
find_sons(root, name);
break;
case 3:
printf("\nEnter name of the person: ");
scanf("%s", name);
printf("\nParents of %s:\n", name);
find_parents(root, name);
break;
case 4:
printf("\nExiting program...\n");
break;
default:
printf("\nInvalid choice, please try again\n");
}
} while (choice != 4);
return 0;
}
```
这样,我们就完成了一个简单的家谱关系系统,可以根据需要对其进行扩展和优化。
阅读全文