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