DAurora
EDen%
采纳率100%
2019-12-30 14:57

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

已采纳

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

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • qq_39575645 Kim_小星兴 1年前

    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 地址点击这里

    点赞 1 评论 复制链接分享