C语言用树实现族谱怎么做呀?

问一下大神,小白不懂怎么用树来写族谱呀?
还要有创建、删除&添加家庭成员、检索属于第几代、改名的功能,感觉好难呀,根本不会,能不能求大神帮帮忙啊?
!!!图片说明

C语言使用树设计族谱

族谱规则

族谱只会跟踪记录男性以及男性的后代,对于女性我们只会记录她在何时出嫁,并不记录她的后代,或者说族谱中的人员向上追溯的时候默认追溯的是父亲一支的关系;

逻辑分析

族谱与数据结构中树的概念相结合,每一个节点就是族谱中的个人,于是我们就需要知道每个人最基本的特性,于是就可以抽象化变成树中的属性;

  • 父母 (parent) --人
  • 兄弟 (brother) --人
  • 伴侣 (soulmate) --人
  • 孩子 (children) --人
  • 姓名 (name) --字符串
  • 生辰八字 (birthday) --日期
  • 性别 (gender) --性别

    那么我们对应的树的结构就出来了

    // def Tree node 定义节点
    typedef struct _FamilyNode
    {
      struct _FamilyNode* parent;
      struct _FamilyNode* brother;
      struct _FamilyNode* soulmate;
      struct _FamilyNode* children;
      char name[30];
      char birthday[20];
      char gender[6];
    } FamilyNode;
    
    // def Family Tree 定义族谱
    typedef struct _FamilyTree
    {
      FamilyNode* root;
      int deep;
    } FamilyTree;
    

其他问题

  • 关于孩子的问题

    很多人的孩子不止一个,那么我们就会将二儿子/三儿子添加到对应的孩子的brother指针,并且将parent指针指向自己哥哥的父母;

  • 关于离婚的问题

    我们都是好孩子,不考虑离婚再婚.

  • 关于变性问题

    • ### 不考虑---不要问---问了就是不考虑
  • 简单示例

    这是小明家的族谱

    小明族谱.png

    小明->parent = NULL;
    小明->brother = NULL;
    小明->soulmate = NULL;
    小明->children = 武大郎;
    
    武大郎->parent = 小明;
    武大郎->brother = 武松;
    武大郎->soulmate = 潘金莲;
    武大郎->children = 小红;
    
    武松->parent = 小明;
    武松->brother = NULL;
    武松->soulmate = 玉兰;
    武松->children = 龙龙;
    
    ....
    
    

解决上述题目中的几个问题

  1. 找祖先
    你找第几代祖先~?
    再族谱里,你想找几代就找几代~ C //使用方式: findOrigin(tigerKiller,1); //往上找武松一代祖先 FamilyNode *findOrigin(FamilyNode *node, int generation) { if (node == NULL) return NULL; FamilyNode *ret = node; while (ret->parent != NULL && generation != 0) { ret = ret->parent; generation--; } return ret; }
  2. 找双亲
    C FamilyNode *findParent(FamilyNode *node) { if (node == NULL) return NULL; return node->parent; }
  3. 找兄弟 C void printBrother(FamilyNode *node) { if (node == NULL) return; FamilyNode *tmp = NULL; K_PRINT("%s的兄弟姐妹有:", node->man.name); if (node->parent != NULL) tmp = node->parent->children; else tmp = node->brother; while (tmp != NULL) { if (tmp != node) K_PRINT(" %s\n", tmp->man.name); tmp = tmp->brother; } }
  4. 找孩子 c // someone->children 后遍历 孩子的 brother 即可
  5. 找堂兄弟 c void printCousin(FamilyNode *node) { if (node == NULL || node->parent == NULL) return; FamilyNode *tmpuncle = NULL; FamilyNode *tmpbro = NULL; K_PRINT("%s的堂兄弟姐妹有:", node->man.name); if (node->parent->parent == NULL) tmpuncle = node->parent->brother; else tmpuncle = node->parent->parent->children; while (tmpuncle != NULL) { tmpbro = tmpuncle->children; while (tmpbro != NULL) { if (tmpbro != node) K_PRINT(" %s\n", tmpbro->man.name); tmpbro = tmpbro->brother; } tmpuncle = tmpuncle->brother; } }
  6. 找后代子孙

    void printFamily(FamilyNode *node)
    {
       if (node == NULL)
       {
           return;
       }
    
       for (int i = 0; i < node->deep; i++)
       {
           char *c = " ";
           if (i == node->deep - 2)
               c = "└";
           else if (i == node->deep - 1)
               c = "--";
           else
               c = "  ";
    
           K_PRINT("%s", c);
       }
       K_PRINT("%s:%s生,性别 %s", node->man.name,
               node->man.birthday, GENDER_TO_STR   (node->man.gender));
       if (node->soulmate != NULL)
       {
           K_PRINT(",伴侣: %s, 性别: %s",
                   node->soulmate->man.name,
                   GENDER_TO_STR(node->soulmate->man.gender)   );
       }
       K_PRINT("%s", "\n");
       printFamily(node->children);
       printFamily(node->brother);
    }
    
  7. 查询某人居于家族中的第几代

    someone->deep;
    

    github 地址点击这里