C语言写:采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲 输出形式要有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构: 学生自己根据系统功能要求自己设计,但是要求家谱系统的相关数据要存储在数据文件中。
时间: 2024-02-19 07:58:55 浏览: 19
这是一道比较复杂的问题,需要涉及到数据结构和文件操作等知识。下面是一个简单的参考实现,仅供参考。
首先,我们需要定义一个家庭成员的结构体,如下所示:
```c
typedef struct _FamilyMember{
char name[20];
char gender;
char spouse[20];
char id[20];
int age;
char birthdate[20];
struct _FamilyMember *parent; // 指向父节点
struct _FamilyMember *child; // 指向第一个子节点
struct _FamilyMember *sibling; // 指向下一个兄弟节点
} FamilyMember;
```
其中,parent 指向父节点,child 指向第一个子节点,sibling 指向下一个兄弟节点。
然后,我们可以定义一个家族的结构体,包含一个指向根节点的指针,以及一些其他的信息:
```c
typedef struct _FamilyTree{
FamilyMember *root; // 根节点
int size; // 家族成员数量
// 其他信息,比如文件名称等
} FamilyTree;
```
接着,我们可以设计一些基本操作,比如创建一个新的家庭成员节点:
```c
FamilyMember* createMember(char *name, char gender, char *spouse, char *id, int age, char *birthdate){
FamilyMember *member = (FamilyMember*)malloc(sizeof(FamilyMember));
strcpy(member->name, name);
member->gender = gender;
strcpy(member->spouse, spouse);
strcpy(member->id, id);
member->age = age;
strcpy(member->birthdate, birthdate);
member->parent = NULL;
member->child = NULL;
member->sibling = NULL;
return member;
}
```
然后,我们可以设计一个函数,用于向家谱树中添加一个新的成员节点:
```c
void addMember(FamilyTree *tree, FamilyMember *parent, FamilyMember *child){
if(parent == NULL){ // 如果父节点为空,说明该节点是根节点
tree->root = child;
}else{
child->parent = parent;
if(parent->child == NULL){ // 如果父节点没有子节点,那么该节点成为父节点的第一个子节点
parent->child = child;
}else{ // 否则,将该节点添加到父节点的子节点列表末尾
FamilyMember *p = parent->child;
while(p->sibling != NULL){
p = p->sibling;
}
p->sibling = child;
}
}
tree->size++;
}
```
接下来,我们可以设计一个函数,用于从文件中读取家族信息,并创建家谱树:
```c
void loadFamilyTreeFromFile(FamilyTree *tree, char *filename){
FILE *fp = fopen(filename, "r");
if(fp == NULL){
printf("Failed to open file %s\n", filename);
return;
}
// 从文件中读取家族信息,每行一个成员,格式为:姓名 性别 配偶 姓名身份证号 年龄 出生日期
char line[100];
while(fgets(line, 100, fp) != NULL){
char name[20], gender, spouse[20], id[20], birthdate[20];
int age;
sscanf(line, "%s %c %s %s %d %s", name, &gender, spouse, id, &age, birthdate);
FamilyMember *member = createMember(name, gender, spouse, id, age, birthdate);
addMember(tree, NULL, member); // 将该节点添加到家谱树中
}
fclose(fp);
}
```
然后,我们可以设计一个函数,用于将家族信息保存到文件中:
```c
void saveFamilyTreeToFile(FamilyTree *tree, char *filename){
FILE *fp = fopen(filename, "w");
if(fp == NULL){
printf("Failed to open file %s\n", filename);
return;
}
// 依次输出每个成员的信息到文件中
FamilyMember *p = tree->root;
while(p != NULL){
fprintf(fp, "%s %c %s %s %d %s\n", p->name, p->gender, p->spouse, p->id, p->age, p->birthdate);
p = p->sibling;
}
fclose(fp);
}
```
接下来,我们可以设计一个函数,用于输出家族信息:
```c
void printFamilyTree(FamilyTree *tree){
printf("Family members:\n");
// 从根节点开始递归遍历家谱树
printFamilyMember(tree->root, 0);
}
void printFamilyMember(FamilyMember *member, int level){
if(member == NULL){
return;
}
// 输出该成员的信息
for(int i=0; i<level; i++){
printf(" "); // 缩进
}
printf("%s (%c, %d)\n", member->name, member->gender, member->age);
// 递归输出该成员的子节点
printFamilyMember(member->child, level+1);
// 递归输出该成员的兄弟节点
printFamilyMember(member->sibling, level);
}
```
然后,我们可以设计一个函数,用于查找某个成员的所有儿子:
```c
void findChildren(FamilyTree *tree, char *name){
FamilyMember *member = findMember(tree->root, name);
if(member == NULL){
printf("Member %s not found!\n", name);
return;
}
printf("%s's children:\n", member->name);
// 输出该成员的所有子节点
FamilyMember *p = member->child;
while(p != NULL){
printf(" %s (%c, %d)\n", p->name, p->gender, p->age);
p = p->sibling;
}
}
FamilyMember* findMember(FamilyMember *member, char *name){
if(member == NULL){
return NULL;
}
if(strcmp(member->name, name) == 0){
return member;
}
// 递归查找该成员的子节点和兄弟节点
FamilyMember *p = findMember(member->child, name);
if(p == NULL){
p = findMember(member->sibling, name);
}
return p;
}
```
最后,我们可以设计一个简单的菜单系统,供用户选择需要的功能:
```c
int main(){
FamilyTree tree;
tree.root = NULL;
tree.size = 0;
loadFamilyTreeFromFile(&tree, "family.txt");
int choice = 0;
while(choice != 5){
printf("\n");
printf("1. Add a member\n");
printf("2. Print family tree\n");
printf("3. Find children\n");
printf("4. Save to file\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch(choice){
case 1:
// 从用户输入中创建一个新的成员节点,并将其添加到家谱树中
break;
case 2:
printFamilyTree(&tree);
break;
case 3:
// 从用户输入中查找某个成员的所有儿子,并输出到屏幕上
break;
case 4:
saveFamilyTreeToFile(&tree, "family.txt");
break;
case 5:
break;
default:
printf("Invalid choice!\n");
break;
}
}
return 0;
}
```
以上是一个简单的参考实现,仅供参考。实际应用中,需要根据具体需求进行修改和完善。