C语言:采用树表示一个家谱关系,采用链表(孩子表示法)作为存储结构,实现家谱关系的相关运算。每个节点信息包含有:姓名、性别、配偶姓名、身份证号、年龄、出生日期等。 功能要求: 1)输入家族信息(要求自己设计文件存储格式,存放当前所有家族信息)2)输出家族信息(要求界面输出格式直观明了) 3)查找某人的所有儿子 4)查找某人的双亲 输出形式要有合理的提示,每个功能可以设立菜单,根据提示,可以完成相关的功能要求。 存储结构: 学生自己根据系统功能要求自己设计,但是要求家谱系统的相关数据要存储在数据文件中。
时间: 2023-12-10 17:41:30 浏览: 107
这是一个比较复杂的程序,需要涉及到树和链表两种数据结构的运用,以及文件读写等操作。下面给出一个简单的实现方案。
1. 定义家谱节点结构体:
```c
typedef struct node {
char name[20]; // 姓名
char gender[5]; // 性别
char spouse[20]; // 配偶姓名
char id[20]; // 身份证号
int age; // 年龄
char birth[20]; // 出生日期
struct node *child; // 第一个孩子
struct node *sibling; // 兄弟节点
} Node;
```
2. 定义家谱树结构体:
```c
typedef struct tree {
Node *root; // 树的根节点
} Tree;
```
3. 实现相关操作函数:
(1)插入节点函数
```c
void insertNode(Node *parent, Node *child) {
if (parent->child == NULL) { // 如果父节点没有孩子节点,则将孩子节点作为父节点的第一个孩子
parent->child = child;
} else { // 否则将孩子节点接到父节点孩子链表的最后一个节点之后
Node *p = parent->child;
while (p->sibling != NULL) {
p = p->sibling;
}
p->sibling = child;
}
}
```
(2)创建家谱树函数
```c
Tree *createTree() {
Tree *tree = (Tree*) malloc(sizeof(Tree));
tree->root = NULL;
return tree;
}
Node *createNode() {
Node *node = (Node*) malloc(sizeof(Node));
node->child = NULL;
node->sibling = NULL;
return node;
}
void addNode(Tree *tree, Node *node) {
if (tree->root == NULL) { // 如果树为空,则将该节点作为根节点
tree->root = node;
} else { // 否则将该节点插入到树中
insertNode(tree->root, node);
}
}
```
(3)读取文件函数
```c
void readData(Tree *tree, char *filename) {
FILE *fp = fopen(filename, "r");
if (fp == NULL) {
printf("文件打开失败!\n");
return;
}
while (!feof(fp)) {
Node *node = createNode();
fscanf(fp, "%s %s %s %s %d %s", node->name, node->gender, node->spouse, node->id,
&node->age, node->birth);
addNode(tree, node); // 将节点添加到树中
}
fclose(fp);
}
```
(4)写入文件函数
```c
void writeData(Tree *tree, char *filename) {
FILE *fp = fopen(filename, "w");
if (fp == NULL) {
printf("文件打开失败!\n");
return;
}
writeNode(fp, tree->root); // 从根节点开始递归写入文件
fclose(fp);
}
void writeNode(FILE *fp, Node *node) {
if (node == NULL) return;
fprintf(fp, "%s %s %s %s %d %s\n", node->name, node->gender, node->spouse, node->id,
node->age, node->birth);
writeNode(fp, node->child); // 递归写入孩子节点
writeNode(fp, node->sibling); // 递归写入兄弟节点
}
```
(5)查找某人所有儿子函数
```c
void findChildren(Node *parent) {
if (parent == NULL || parent->child == NULL) {
printf("%s 没有儿子!\n", parent->name);
return;
}
Node *p = parent->child;
printf("%s 的儿子有:\n", parent->name);
while (p != NULL) {
printf("%s\n", p->name);
p = p->sibling;
}
}
```
(6)查找某人的双亲函数
```c
void findParents(Tree *tree, Node *node) {
if (node == NULL || tree->root == node) { // 如果当前节点为空或者为根节点,则返回
printf("%s 没有双亲!\n", node->name);
return;
}
Node *p = tree->root;
while (p != NULL) {
Node *q = p->child;
while (q != NULL) {
if (q == node) { // 如果找到该节点,则输出其父节点的姓名
printf("%s 的双亲是:%s\n", node->name, p->name);
return;
}
q = q->sibling;
}
p = p->sibling;
}
}
```
4. 主函数实现
```c
int main() {
Tree *tree = createTree(); // 创建家谱树
readData(tree, "data.txt"); // 从文件中读取家谱数据
int choice;
while (1) {
printf("请选择操作:\n");
printf("1. 插入节点\n");
printf("2. 输出家族信息\n");
printf("3. 查找某人的所有儿子\n");
printf("4. 查找某人的双亲\n");
printf("0. 退出程序\n");
scanf("%d", &choice);
switch (choice) {
case 1: {
Node *node = createNode();
printf("请输入姓名:");
scanf("%s", node->name);
printf("请输入性别:");
scanf("%s", node->gender);
printf("请输入配偶姓名:");
scanf("%s", node->spouse);
printf("请输入身份证号:");
scanf("%s", node->id);
printf("请输入年龄:");
scanf("%d", &node->age);
printf("请输入出生日期:");
scanf("%s", node->birth);
addNode(tree, node); // 将节点添加到树中
printf("插入成功!\n");
break;
}
case 2: {
printf("家族信息如下:\n");
writeData(tree, "data.txt"); // 将家谱数据写入文件并输出
break;
}
case 3: {
char name[20];
printf("请输入要查找的人的姓名:");
scanf("%s", name);
Node *p = tree->root;
while (p != NULL) {
if (strcmp(p->name, name) == 0) { // 如果找到该节点,则调用查找儿子函数
findChildren(p);
break;
}
p = p->sibling;
}
if (p == NULL) {
printf("未找到该人!\n");
}
break;
}
case 4: {
char name[20];
printf("请输入要查找的人的姓名:");
scanf("%s", name);
Node *p = tree->root;
while (p != NULL) {
if (strcmp(p->name, name) == 0) { // 如果找到该节点,则调用查找双亲函数
findParents(tree, p);
break;
}
p = p->sibling;
}
if (p == NULL) {
printf("未找到该人!\n");
}
break;
}
case 0: {
printf("程序已退出!\n");
return 0;
}
default: {
printf("输入错误,请重新输入!\n");
break;
}
}
}
}
```
注意,上述代码只是一个简单的实现方案,还有很多细节需要考虑,比如输入的数据可能会超出数组范围,文件打开可能会失败等等。在实际开发中需要更加严谨和完善。
阅读全文