C语言:采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲 输出形式要有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构: 学生自己根据系统功能要求自己设计,但是要求家谱系统的相关数据要存储在数据文件中。
时间: 2024-01-22 22:20:03 浏览: 78
以下是基于孩子表示法的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" 文件中。
阅读全文