C语言:采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲 输出形式要有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构: 学生自己根据系统功能要求自己设计,但是要求家谱系统的相关数据要存储在数据文件中。
时间: 2024-01-24 16:20:14 浏览: 68
实现思路:
1. 定义节点结构体,包含姓名、性别、配偶姓名、身份证号、年龄、出生日期等信息,以及指向孩子节点的指针和指向兄弟节点的指针。
2. 定义家谱树结构体,包含根节点指针和当前节点指针。
3. 实现创建节点、添加孩子节点、添加兄弟节点等基本操作。
4. 实现从文件读取家族信息、保存家族信息到文件、输出家族信息等操作。
5. 实现查找某人的所有儿子、查找某人的双亲等功能。
代码如下:
相关问题
c语言:采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲 输出形式要有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构: 学生自己根据系统功能要求自己设计,但是要求家谱系统的相关数据要存储在数据文件中。
以下是一个简单的家谱关系管理程序,包含了输入家族信息、输出家族信息、查找某人的所有儿子和查找某人的双亲等功能。程序采用链式存储结构(孩子表示法)来表示家谱关系,以文本文件形式存储家族信息。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LEN 20
#define MAX_ID_LEN 20
#define MAX_LINE_LEN 100
typedef struct Node {
char name[MAX_NAME_LEN];
char gender;
char spouse[MAX_NAME_LEN];
char id[MAX_ID_LEN];
int age;
char birthdate[MAX_LINE_LEN];
struct Node *first_child;
struct Node *next_sibling;
} Node;
Node *root = NULL;
void load_data() {
FILE *fp = fopen("family.txt", "r");
if (fp == NULL) {
printf("Error: cannot open file 'family.txt'\n");
return;
}
char line[MAX_LINE_LEN];
Node *parent = NULL;
while (fgets(line, MAX_LINE_LEN, fp)) {
Node *node = (Node *) malloc(sizeof(Node));
sscanf(line, "%s %c %s %s %d %s", node->name, &node->gender, node->spouse, node->id, &node->age, node->birthdate);
node->first_child = NULL;
node->next_sibling = NULL;
if (parent == NULL) {
root = node;
} else if (parent->first_child == NULL) {
parent->first_child = node;
} else {
Node *sibling = parent->first_child;
while (sibling->next_sibling != NULL) {
sibling = sibling->next_sibling;
}
sibling->next_sibling = node;
}
if (node->gender == 'M') {
parent = node;
}
}
fclose(fp);
}
void save_data() {
FILE *fp = fopen("family.txt", "w");
if (fp == NULL) {
printf("Error: cannot open file 'family.txt'\n");
return;
}
Node *parent = root;
while (parent != NULL) {
Node *node = parent->first_child;
while (node != NULL) {
fprintf(fp, "%s %c %s %s %d %s\n", node->name, node->gender, node->spouse, node->id, node->age, node->birthdate);
node = node->next_sibling;
}
parent = parent->next_sibling;
}
fclose(fp);
}
void add_person() {
Node *node = (Node *) malloc(sizeof(Node));
printf("Enter name: ");
scanf("%s", node->name);
printf("Enter gender (M/F): ");
scanf(" %c", &node->gender);
printf("Enter spouse name (N/A): ");
scanf("%s", node->spouse);
printf("Enter ID number: ");
scanf("%s", node->id);
printf("Enter age: ");
scanf("%d", &node->age);
printf("Enter birthdate (YYYY-MM-DD): ");
scanf("%s", node->birthdate);
node->first_child = NULL;
node->next_sibling = NULL;
if (root == NULL) {
root = node;
} else {
Node *parent = root;
while (1) {
printf("Enter parent name (N/A for root): ");
char parent_name[MAX_NAME_LEN];
scanf("%s", parent_name);
if (strcmp(parent_name, "N/A") == 0) {
break;
}
int found = 0;
Node *child = parent->first_child;
while (child != NULL) {
if (strcmp(child->name, parent_name) == 0) {
found = 1;
break;
}
child = child->next_sibling;
}
if (found) {
parent = child;
} else {
printf("Error: parent not found\n");
}
}
if (parent->gender == 'F') {
printf("Error: mother cannot have children\n");
return;
}
if (parent->first_child == NULL) {
parent->first_child = node;
} else {
Node *sibling = parent->first_child;
while (sibling->next_sibling != NULL) {
sibling = sibling->next_sibling;
}
sibling->next_sibling = node;
}
}
save_data();
printf("Person added successfully\n");
}
void print_person(Node *node) {
printf("%s (%c, %d)\n", node->name, node->gender, node->age);
}
void print_family(Node *node, int level) {
for (int i = 0; i < level; i++) {
printf(" ");
}
print_person(node);
Node *child = node->first_child;
while (child != NULL) {
print_family(child, level + 1);
child = child->next_sibling;
}
}
Node *find_person(char *name) {
Node *parent = root;
while (parent != NULL) {
Node *node = parent->first_child;
while (node != NULL) {
if (strcmp(node->name, name) == 0) {
return node;
}
node = node->next_sibling;
}
parent = parent->next_sibling;
}
return NULL;
}
void find_sons() {
char name[MAX_NAME_LEN];
printf("Enter name: ");
scanf("%s", name);
Node *node = find_person(name);
if (node == NULL) {
printf("Error: person not found\n");
return;
}
if (node->gender == 'F') {
printf("Error: mother cannot have children\n");
return;
}
if (node->first_child == NULL) {
printf("%s has no children\n", node->name);
return;
}
printf("%s's children:\n", node->name);
Node *child = node->first_child;
while (child != NULL) {
print_person(child);
child = child->next_sibling;
}
}
void find_parents() {
char name[MAX_NAME_LEN];
printf("Enter name: ");
scanf("%s", name);
Node *node = find_person(name);
if (node == NULL) {
printf("Error: person not found\n");
return;
}
if (node == root) {
printf("%s is the root\n", node->name);
return;
}
printf("%s's parents:\n", node->name);
Node *parent = root;
while (parent != NULL) {
Node *child = parent->first_child;
while (child != NULL) {
if (child == node) {
print_person(parent);
return;
}
child = child->next_sibling;
}
parent = parent->next_sibling;
}
}
int main() {
load_data();
while (1) {
printf("\n1. Add person\n");
printf("2. Print family tree\n");
printf("3. Find sons\n");
printf("4. Find parents\n");
printf("5. Exit\n");
printf("Enter your choice: ");
int choice;
scanf("%d", &choice);
switch (choice) {
case 1:
add_person();
break;
case 2:
if (root == NULL) {
printf("Error: no family data\n");
} else {
print_family(root, 0);
}
break;
case 3:
find_sons();
break;
case 4:
find_parents();
break;
case 5:
return 0;
default:
printf("Error: invalid choice\n");
}
}
}
```
家族信息以文本文件 `family.txt` 的形式存储,每行表示一个人的信息,包括姓名、性别、配偶姓名、身份证号、年龄和出生日期,以空格分隔。如果一个人没有配偶,则配偶姓名为 N/A。如果一个人是根节点,则其父亲姓名为 N/A。
程序启动时会自动加载 `family.txt` 中的家族信息。程序提供了菜单界面,用户可以选择添加人物、输出家族信息、查找某人的所有儿子或查找某人的双亲。
如果用户选择添加人物,程序会提示用户输入该人物的各项信息,包括姓名、性别、配偶姓名、身份证号、年龄和出生日期。程序会要求用户指定该人物的父亲,如果该人物是根节点,则无需指定父亲。程序会将新人物插入到家谱树中。
如果用户选择输出家族信息,程序会遍历家谱树,并以缩进方式输出每个人物的信息,从而形成家谱树的结构。
如果用户选择查找某人的所有儿子,程序会提示用户输入该人物的姓名,并遍历该人物的所有孩子,输出他们的姓名、性别、年龄等信息。
如果用户选择查找某人的双亲,程序会提示用户输入该人物的姓名,并遍历家谱树,查找该人物的父亲和母亲,并输出他们的姓名、性别、年龄等信息。
程序结束时会自动保存家族信息到 `family.txt` 中。
C语言:采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲 输出形式要有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构: 学生自己根据系统功能要求自己设计,但是要求家谱系统的相关数据要存储在数据文件中。
以下是基于孩子表示法的C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LEN 20
#define MAX_ID_LEN 18
// 节点信息结构体
typedef struct NodeInfo {
char name[MAX_NAME_LEN]; // 姓名
char gender; // 性别
char spouse_name[MAX_NAME_LEN]; // 配偶姓名
char id[MAX_ID_LEN]; // 身份证号
int age; // 年龄
char birthdate[MAX_NAME_LEN]; // 出生日期
} NodeInfo;
// 家谱树节点结构体
typedef struct TreeNode {
NodeInfo info; // 节点信息
struct TreeNode *first_child; // 第一个孩子指针
struct TreeNode *next_sibling; // 右兄弟指针
} TreeNode;
// 创建新节点
TreeNode *create_node(NodeInfo info) {
TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode));
node->info = info;
node->first_child = NULL;
node->next_sibling = NULL;
return node;
}
// 读取节点信息
NodeInfo read_node_info() {
NodeInfo info;
printf("请输入姓名:");
scanf("%s", info.name);
printf("请输入性别(M/F):");
scanf(" %c", &info.gender);
printf("请输入配偶姓名(如果没有请输N):");
scanf("%s", info.spouse_name);
printf("请输入身份证号:");
scanf("%s", info.id);
printf("请输入年龄:");
scanf("%d", &info.age);
printf("请输入出生日期:");
scanf("%s", info.birthdate);
return info;
}
// 查找节点
TreeNode *find_node(TreeNode *root, char *name) {
if (root == NULL) {
return NULL;
}
if (strcmp(root->info.name, name) == 0) {
return root;
}
TreeNode *node = root->first_child;
while (node != NULL) {
TreeNode *result = find_node(node, name);
if (result != NULL) {
return result;
}
node = node->next_sibling;
}
return NULL;
}
// 添加子女
void add_child(TreeNode *parent) {
NodeInfo info = read_node_info();
TreeNode *child = create_node(info);
if (parent->first_child == NULL) {
parent->first_child = child;
} else {
TreeNode *node = parent->first_child;
while (node->next_sibling != NULL) {
node = node->next_sibling;
}
node->next_sibling = child;
}
}
// 读取家谱信息
TreeNode *read_family_tree() {
TreeNode *root = NULL;
FILE *fp = fopen("family_tree.txt", "r");
if (fp != NULL) {
char line[100];
while (fgets(line, sizeof(line), fp) != NULL) {
if (line[strlen(line)-1] == '\n') {
line[strlen(line)-1] = '\0';
}
char *name = strtok(line, ",");
char *gender_str = strtok(NULL, ",");
char *spouse_name = strtok(NULL, ",");
char *id = strtok(NULL, ",");
char *age_str = strtok(NULL, ",");
char *birthdate = strtok(NULL, ",");
NodeInfo info = {0};
strcpy(info.name, name);
info.gender = gender_str[0];
strcpy(info.spouse_name, spouse_name);
strcpy(info.id, id);
info.age = atoi(age_str);
strcpy(info.birthdate, birthdate);
TreeNode *node = create_node(info);
if (root == NULL) {
root = node;
} else {
char *parent_name = strtok(NULL, ",");
TreeNode *parent = find_node(root, parent_name);
if (parent != NULL) {
if (parent->first_child == NULL) {
parent->first_child = node;
} else {
TreeNode *sibling = parent->first_child;
while (sibling->next_sibling != NULL) {
sibling = sibling->next_sibling;
}
sibling->next_sibling = node;
}
}
}
}
fclose(fp);
}
return root;
}
// 保存家谱信息
void save_family_tree(TreeNode *root) {
FILE *fp = fopen("family_tree.txt", "w");
if (fp != NULL) {
fprintf(fp, "%s,%c,%s,%s,%d,%s\n", root->info.name, root->info.gender,
root->info.spouse_name, root->info.id, root->info.age, root->info.birthdate);
TreeNode *node = root->first_child;
while (node != NULL) {
save_family_tree_helper(node, root->info.name, fp);
node = node->next_sibling;
}
fclose(fp);
}
}
// 保存家谱信息辅助函数
void save_family_tree_helper(TreeNode *node, char *parent_name, FILE *fp) {
fprintf(fp, "%s,%c,%s,%s,%d,%s,%s\n", node->info.name, node->info.gender,
node->info.spouse_name, node->info.id, node->info.age, node->info.birthdate, parent_name);
TreeNode *child = node->first_child;
while (child != NULL) {
save_family_tree_helper(child, node->info.name, fp);
child = child->next_sibling;
}
}
// 输出家谱信息
void print_family_tree(TreeNode *node, int level) {
for (int i = 0; i < level; i++) {
printf(" ");
}
printf("%s (%c)\n", node->info.name, node->info.gender);
TreeNode *child = node->first_child;
while (child != NULL) {
print_family_tree(child, level+1);
child = child->next_sibling;
}
}
// 查找某人的所有儿子
void search_sons(TreeNode *node) {
int count = 0;
TreeNode *child = node->first_child;
while (child != NULL) {
if (child->info.gender == 'M') {
printf("%s\n", child->info.name);
count++;
}
child = child->next_sibling;
}
if (count == 0) {
printf("该人没有儿子!\n");
}
}
// 查找某人的双亲
void search_parents(TreeNode *root, TreeNode *node) {
if (root == NULL || node == root) {
return;
}
TreeNode *child = root->first_child;
while (child != NULL) {
if (child == node) {
printf("父亲:%s\n", root->info.gender == 'M' ? root->info.name : root->info.spouse_name);
TreeNode *sibling = root->first_child;
while (sibling != NULL) {
if (sibling != node && sibling->info.gender == 'F') {
printf("母亲:%s\n", sibling->info.name);
break;
}
sibling = sibling->next_sibling;
}
return;
}
search_parents(child, node);
child = child->next_sibling;
}
}
int main() {
TreeNode *root = read_family_tree();
int choice = 0;
while (choice != 5) {
printf("1. 输入家族信息\n");
printf("2. 输出家族信息\n");
printf("3. 查找某人的所有儿子\n");
printf("4. 查找某人的双亲\n");
printf("5. 退出\n");
printf("请选择功能:");
scanf("%d", &choice);
switch (choice) {
case 1: {
printf("请输入父亲姓名:");
char father_name[MAX_NAME_LEN];
scanf("%s", father_name);
TreeNode *father = find_node(root, father_name);
if (father == NULL) {
printf("未找到该人,请重新输入!\n");
} else {
printf("请输入子女信息(输入0结束):\n");
while (1) {
NodeInfo info = read_node_info();
if (strcmp(info.name, "0") == 0) {
break;
}
TreeNode *child = create_node(info);
if (info.gender == 'M') {
printf("请注意,您输入的是一个男性,请重新输入!\n");
continue;
}
if (father->first_child == NULL) {
father->first_child = child;
} else {
TreeNode *node = father->first_child;
while (node->next_sibling != NULL) {
node = node->next_sibling;
}
node->next_sibling = child;
}
}
save_family_tree(root);
printf("添加成功!\n");
}
break;
}
case 2: {
printf("家族信息如下:\n");
print_family_tree(root, 0);
break;
}
case 3: {
printf("请输入要查找的人的姓名:");
char name[MAX_NAME_LEN];
scanf("%s", name);
TreeNode *node = find_node(root, name);
if (node == NULL) {
printf("未找到该人,请重新输入!\n");
} else {
printf("%s的所有儿子如下:\n", name);
search_sons(node);
}
break;
}
case 4: {
printf("请输入要查找的人的姓名:");
char name[MAX_NAME_LEN];
scanf("%s", name);
TreeNode *node = find_node(root, name);
if (node == NULL) {
printf("未找到该人,请重新输入!\n");
} else {
printf("%s的双亲如下:\n", name);
search_parents(root, node);
}
break;
}
case 5: {
printf("谢谢使用!\n");
break;
}
default: {
printf("请输入正确的选项!\n");
break;
}
}
}
return 0;
}
```
家谱信息存储在文件 "family_tree.txt" 中,每行存储一个节点的信息,格式为:
```
姓名,性别,配偶姓名,身份证号,年龄,出生日期,父亲姓名
```
其中父亲姓名只在非根节点出现,根节点的父亲姓名为空。在程序启动时,会读取 "family_tree.txt" 文件中的信息,构建家谱树;在程序结束时,会将修改后的家谱信息保存回 "family_tree.txt" 文件中。
阅读全文
相关推荐
![-](https://img-home.csdnimg.cn/images/20241231044937.png)
![-](https://img-home.csdnimg.cn/images/20241231044937.png)
![-](https://img-home.csdnimg.cn/images/20241231044937.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![-](https://img-home.csdnimg.cn/images/20241226111658.png)
![-](https://img-home.csdnimg.cn/images/20241231044937.png)
![-](https://img-home.csdnimg.cn/images/20241231045021.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)