家族族谱管理系统(东软新手版)

【功能描述】
使用树形结构设计家族族谱数据管理系统。
【具体要求】
要求实现以下功能:
1. 使用树形结构设计家族族谱数据结构,定义节点(成员)的信息,
包括姓名、性别、出生日期、配偶、子女等。
2. 族谱构建:从用户输入的初始数据(如根节点信息)构建家族族谱
树,并允许逐步添加成员。
3. 添加成员:根据用户输入的信息添加新的家庭成员,并维护正确的
树结构。
4. 删除成员:根据用户输入的姓名删除指定成员,并确保树结构的完
整性。
5. 查找成员:根据用户输入的姓名查找并返回该成员的信息。
6. 遍历操作:实现家族族谱的前序遍历、中序遍历和后序遍历,并输
出遍历结果。
7. 用户界面:设计一个简单的命令行界面或图形界面,方便用户进行
各种操作,如添加、删除、查找成员,展示族谱等。
【可选部分】
1. 统计和分析:统计家族成员的数量、不同性别成员的数量、最长家
族树分支等。分析家族树的深度、平均每代成员数量等信息。
2. 关系查询:实现查询特定成员与其他成员的关系(如父子、祖孙、
兄弟姐妹等)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<windows.h>

// 家庭成员结构体
typedef struct family {
    char name[40];               // 姓名
    char gender[10];             // 性别
    char birthday[20];          // 出生日期
    char  spouse[40];       // 配偶
    struct family *children[5]; // 子女
    int childCount;              // 子女数量
    struct family *parent;       // 父母
} family;

family* root = NULL; // 根节点
int maleCount,femaleCount;// 家族中男,女成员数量 
char ch;

// 创建新成员
family* create(char* name, char* gender, char* birthday,char* spouse) {
    family* newfamily = (family*)malloc(sizeof(family)); // 分配内存
    strcpy(newfamily->name, name);                       // 设置姓名
    strcpy(newfamily->gender, gender);                   // 设置性别
    strcpy(newfamily->birthday, birthday);             // 设置出生日期
    strcpy(newfamily->spouse, spouse);                 //设置配偶 
    newfamily->childCount = 0;                           // 初始化子女数量为0
    newfamily->parent = NULL;                            // 初始化父母为空
    return newfamily;                                    // 返回新成员
}

// 添加子女
void addChild(family* parent, family* child) {
    if (parent->childCount < 5) {                           // 如果子女数量少于5
        parent->children[parent->childCount++] = child;      // 添加子女
        child->parent = parent;                              // 设置父母
    } else {
        printf("无法添加更多的子女。\n");                
    }
}


// 初始化家族树
void initialFamilyTree() {
    char name[40], gender[10], birthday[20],spouse[40];
    printf("请输入根成员的姓名 性别 出生日期 配偶: "); // 提示输入根成员姓名 性别 出生日期 配偶
    scanf("%s %s %s %s", name,gender,birthday, spouse ); 
    root = create(name, gender, birthday,spouse); // 创建根成员
}

  
// 查找成员  
family* findMember(family* root, char* name) {  
    if (root == NULL) { 
        return NULL;  
    }  
    if (strcmp(root->name, name) == 0) { // 如果找到成员  
        return root;  
    }  
    for (int i = 0; i < root->childCount; i++) { // 遍历子女  
        family* found = findMember(root->children[i], name); // 递归查找  
        if (found != NULL) { // 如果找到成员  
            return found;  
        } 
    }  
    return NULL; // 未找到成员  
}  
  
// 添加家庭成员  
void addFamily() {  
    if (root == NULL) { // 如果根节点为空  
        printf("家族树未初始化。\n"); // 提示家族树未初始化  
        return;  
    }  
    char parentName[40];  
    printf("请输入父母的姓名: "); // 提示输入父母姓名  
    scanf("%s", parentName); 
  
    family* parent = findMember(root, parentName); // 查找父母  
    if (parent == NULL) { // 如果未找到父母  
        printf("未找到父母。\n"); // 提示未找到父母  
        return;  
    }  
  
    char name[40], gender[10], birthday[20],spouse[40];  
    printf("请输入孩子的姓名 性别 出生日期 配偶: "); // 提示输入孩子姓名 性别 出生日期 配偶
    scanf("%s %s %s %s", name,gender,birthday, spouse ); 
    family* child = create(name, gender, birthday,spouse); // 创建孩子  
    addChild(parent, child); // 添加孩子到父母节点  
}  
  
// 删除家庭成员  
void deleteFamily() {  
    if (root == NULL) { // 如果根节点为空  
        printf("家族树未初始化。\n"); // 提示家族树未初始化  
        return;  
    }  
    char name[40];  
    printf("请输入要删除的成员姓名: "); // 提示输入要删除的成员姓名  
    scanf("%s", name);  
    if (strcmp(root->name, name) == 0) { // 如果要删除的是根节点  
        printf("无法删除根成员。\n"); // 提示无法删除根成员  
        return;  
    }  
    family* member = findMember(root, name); // 查找要删除的成员  
    if (member == NULL) { // 如果未找到成员  
        printf("未找到成员。\n"); // 提示未找到成员  
        return;  
    }  
    family* parent = member->parent; // 获取成员的父母  
    for (int i = 0; i < parent->childCount; i++) { // 遍历父母的子女  
        if (parent->children[i] == member) { // 找到要删除的成员  
            for (int j = i; j < parent->childCount - 1; j++) {  
                parent->children[j] = parent->children[j + 1]; // 移动子女位置  
            }  
            parent->childCount--; // 减少子女数量  
            free(member); // 释放成员内存  
            printf("成员删除成功。\n"); // 提示成员删除成功  
            return;  
        }  
    }  
}

  
// 查找家庭成员  
void findFamily() {  
    if (root == NULL) { 
        printf("家族树未初始化。\n"); 
        return;  
    }  
    char name[50];  
    printf("请输入要查找的成员姓名: "); 
    scanf("%s", name); 
    family* member = findMember(root, name); // 查找成员  
    if (member == NULL) { // 如果未找到成员  
        printf("未找到成员。\n"); // 提示未找到成员  
    } else {  
        printf("姓名: %s\n", member->name); // 输出成员姓名  
        printf("性别: %s\n", member->gender); // 输出成员性别  
        printf("出生日期: %s\n", member->birthday); // 输出成员出生日期  
        printf("配偶: %s\n", member->spouse); // 输出配偶姓名 
        if (member->childCount > 0) { // 如果有子女  
            printf("子女: ");  
            for (int i = 0; i < member->childCount; i++) {  
                printf("%s ", member->children[i]->name); // 输出子女姓名  
            }  
            printf("\n");  
        }  
    }  
}  
  
// 前序遍历  
void preOrderTraversal(family* root) {  
    if (root == NULL)  return;  
    printf("%s ", root->name); 
    for (int i = 0; i < root->childCount; i++)  
        preOrderTraversal(root->children[i]);    // 递归前序遍历子女  
}  
// 中序遍历  
void inOrderTraversal(family* root) {  
    if (root == NULL)  return;  
    if (root->childCount > 0)   
        inOrderTraversal(root->children[0]);     // 递归中序遍历第一个子女   
    printf("%s ", root->name);  
    for (int i = 1; i < root->childCount; i++) 
        inOrderTraversal(root->children[i]);     // 递归中序遍历其他子女  
} 
// 后序遍历  
void postOrderTraversal(family* root) {  
    if (root == NULL)   return;   
    for (int i = 0; i < root->childCount; i++)   
        postOrderTraversal(root->children[i]);   // 递归后序遍历子女   
    printf("%s ", root->name);  
}  
  
// 打印遍历结果  
void printTraversals() {  
    if (root == NULL) { 
        printf("家族树未初始化。\n"); 
        return;  
    }  
    printf("前序遍历: ");  
    preOrderTraversal(root); // 前序遍历  
    printf("\n");  
    printf("中序遍历: ");  
    inOrderTraversal(root); // 中序遍历  
    printf("\n");  
    printf("后序遍历: ");  
    postOrderTraversal(root); // 后序遍历  
    printf("\n");  
}

//家族成员的数量
int countFamilyMembers(struct family *root) {
    if (root == NULL) {
        return 0;
    }
    int count = 1; // 当前节点算一个成员
    for (int i = 0; i < root->childCount; i++) {
        count += countFamilyMembers(root->children[i]);     // 递归统计子节点的成员数量
    }
    return count;
}
// 家族中男,女成员数量 
void countGender(struct family *root) {
    if (root == NULL) {
        return;
    }
    if (strcmp(root->gender, "男") == 0) {
        maleCount++;
    } else if (strcmp(root->gender, "女") == 0) {
        femaleCount++;
    }
    for (int i = 0; i < root->childCount; i++) {
        countGender(root->children[i]);                   // 递归统计子节点的性别数量
    }
}
//家族树的深度
int calculateDepth(struct family *root) {
    if (root == NULL) {
        return 0;
    }
    int maxDepth = 0;
    for (int i = 0; i < root->childCount; i++) {
        int childDepth = calculateDepth(root->children[i]);
        if (childDepth > maxDepth) {
            maxDepth = childDepth;
        }
    }
    return 1 + maxDepth;
}

//关系查询 
int isParent(family* parent, family* child) {  
    if (parent == NULL || child == NULL) return 0;  
    for (int i = 0; i < parent->childCount; ++i) {  
        if (parent->children[i] == child) return 1;  
    }  
    return 0;  
}  
int isChild(family* parent, family* child) {  
    return isParent(child, parent); // 调用isParent,但方向相反  
}
int isGrandparent(family* gp, family* grandchild) {  
    if (gp == NULL || grandchild == NULL) return 0;  
    for (int i = 0; i < gp->childCount; ++i) {  
        family* child = gp->children[i];  
        for (int j = 0; j < child->childCount; ++j) {  
            if (child->children[j] == grandchild) return 1;  
        }  
    }  
    return 0;  
}  
int isGrandchild(family* gp, family* grandchild){
	return isGrandparent(grandchild, gp); // 调用isGrandparent,但方向相反
}

void print(){
    char name1[50],name2[50];  
    printf("请输入要查找的成员姓名: "); 
    scanf("%s %s", name1, name2); 
	family* alice = findMember(root, name1); 
    family* bob = findMember(root, name2);
    if(alice==NULL||bob==NULL) {
    	if(alice==NULL) printf("未找到成员: %s\n",name1);
    	if(bob==NULL) printf("未找到成员: %s\n",name2);
    	return ;
	} else {
		if (isParent(alice, bob)) {  
        if(strcmp(alice->gender, "男") == 0) printf("%s 是 %s 的 父亲\n",name1,name2); 
        else printf("%s 是 %s 的 母亲\n",name1,name2);
    } else if (isChild(alice, bob)) {  
        if(strcmp(alice->gender, "男") == 0) printf("%s 是 %s 的 儿子\n",name1,name2); 
        else printf("%s 是 %s 的 女儿\n",name1,name2);   
    } else if (isGrandparent(alice, bob)) {  
        if(strcmp(alice->gender, "男") == 0) printf("%s 是 %s 的 祖父\n",name1,name2); 
        else printf("%s 是 %s 的 祖母\n",name1,name2); 
    } else if(isGrandchild(alice, bob)){
    	if(strcmp(alice->gender, "男") == 0) printf("%s 是 %s 的 孙子\n",name1,name2); 
        else printf("%s 是 %s 的 孙女\n",name1,name2); 
	}else {  
        printf(" %s 和 %s 找不到直接关系\n", alice->name, bob->name);  
    }  
	} 
	
}

// 显示菜单  
void display() {  
    printf("家族树管理系统\n");  
    printf("1. 初始化家族树\n");  
    printf("2. 添加家庭成员\n");  
    printf("3. 删除家庭成员\n");  
    printf("4. 查找家庭成员\n");  
    printf("5. 打印遍历结果\n");  
    printf("6. 统计与分析\n"); 
    printf("7. 关系查询\n");
    printf("8. 退出\n");  
    printf("请输入你的选择: ");  
}  
  
// 主函数  
int main() {  
    int n; 
	int k,t; 
    do { 
        display(); // 显示菜单  
        scanf("%d", &n); 
        switch (n) {  
            case 1:  
                initialFamilyTree(); // 初始化家族树  
                printf("初始化成功,三秒后返回...");
                Sleep(3000);
                system("cls");
                break;  
            case 2:  
                addFamily(); // 添加家庭成员  
                printf("添加成功,三秒后返回...");
                Sleep(3000);
                system("cls");
                break;  
            case 3:  
                deleteFamily(); // 删除家庭成员 
                printf("删除成功,三秒后返回...");
                Sleep(3000);
				system("cls"); 
                break;  
            case 4:  
                 findFamily(); // 查找家庭成员  
                 printf("按任意键返回:");
                getchar();
				scanf("%c",&ch); 
				system("cls");
                break;  
            case 5:  
                printTraversals(); // 打印遍历结果 
                printf("按任意键返回:");
                getchar();
				scanf("%c",&ch); 
				system("cls");
                break;    
            case 6:
            	 k=countFamilyMembers(root);//家族成员的数量
            	 t=calculateDepth(root);//家族树的深度
            	 countGender(root);//家族中男,女成员数量 
            	printf("家族成员的数量: %d\n",k);
            	printf("男成员的数量: %d\n 女成员的数量: %d\n",maleCount,femaleCount);
            	printf("家族树的深度: %d\n",t);
            	printf("平均每代成员数量: %lf\n",(double)k/(double)t);
            	maleCount=0,femaleCount=0;
            	printf("按任意键返回:");
                getchar();
				scanf("%c",&ch); 
				system("cls");
            	break;
            case 7:
				print(); //关系查询 
				printf("按任意键返回:");
                getchar();
				scanf("%c",&ch); 
				system("cls");
				break;
            case 8:  
                exit(0);  
            default:  
                printf("无效的选择。请重试。\n"); // 提示无效选择  
        }  
    } while (n != 8); // 如果选择不是7,继续循环  
  
    return 0;  
}
		   

小结

这个代码我用的是多叉树,也可以用儿子-兄弟法来写。整体来说,这个代码还有许多可以改进的地方。毕竟我在测试的时候就觉得很别扭,当然因为本人比较懒,所以在满足课程要求的情况下没改。希望东软的学弟学妹可以看到这代码。

好的,以下是一个简单的家族族谱管理系统的实现,供您参考: ```c++ #include <iostream> #include <vector> #include <string> using namespace std; struct Member { string name; // 成员姓名 vector<Member> children; // 孩子列表 }; Member root; // 家族族谱根节点 // 添加成员 void add_member(Member& parent) { string name; cout << "请输入要添加的成员姓名:\n"; cin >> name; Member new_member = {name}; parent.children.push_back(new_member); cout << "添加成功!\n"; } // 删除成员 void delete_member(Member& parent) { string name; cout << "请输入要删除的成员姓名:\n"; cin >> name; for (auto it = parent.children.begin(); it != parent.children.end(); it++) { if (it->name == name) { parent.children.erase(it); cout << "删除成功!\n"; return; } } cout << "没有找到该成员!\n"; } // 显示成员列表 void show_member_list(Member& parent, int level) { for (auto it = parent.children.begin(); it != parent.children.end(); it++) { for (int i = 0; i < level; i++) { cout << " "; // 根据层级缩进 } cout << "└─" << it->name << endl; show_member_list(*it, level + 1); // 递归显示子孙列表 } } // 查询成员 void search_member(Member& parent) { string name; cout << "请输入要查询的成员姓名:\n"; cin >> name; for (auto it = parent.children.begin(); it != parent.children.end(); it++) { if (it->name == name) { cout << "找到了该成员!\n"; return; } search_member(*it); // 递归查询子孙列表 } } int main() { root.name = "家族族谱"; // 根节点 while (true) { // 家族族谱管理程序循环 cout << "请选择操作:\n"; cout << "a. 添加成员\n"; cout << "b. 删除成员\n"; cout << "c. 显示成员列表\n"; cout << "d. 查询成员\n"; cout << "e. 退出程序\n"; char choice; cin >> choice; switch (choice) { case 'a': add_member(root); break; case 'b': delete_member(root); break; case 'c': show_member_list(root, 0); break; case 'd': search_member(root); break; case 'e': cout << "程序已退出!\n"; return 0; default: cout << "输入无效,请重新输入!\n"; break; } } } ``` 该程序通过使用递归结构来实现家族族谱的管理。程序中每个成员都有一个 `vector` 类型的孩子列表,可以通过添加和删除孩子来修改家族族谱。同时,程序支持显示成员列表和查询成员等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值