1条回答 默认 最新
- Kim_小星兴 2020-01-02 14:19关注
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指针指向自己哥哥的父母;关于离婚的问题
我们都是好孩子,不考虑离婚再婚.-
关于变性问题
- ### 不考虑---不要问---问了就是不考虑
- ### 不考虑---不要问---问了就是不考虑
-
简单示例
这是小明家的族谱小明->parent = NULL; 小明->brother = NULL; 小明->soulmate = NULL; 小明->children = 武大郎; 武大郎->parent = 小明; 武大郎->brother = 武松; 武大郎->soulmate = 潘金莲; 武大郎->children = 小红; 武松->parent = 小明; 武松->brother = NULL; 武松->soulmate = 玉兰; 武松->children = 龙龙; ....
解决上述题目中的几个问题
-
找祖先
你找第几代祖先~?
再族谱里,你想找几代就找几代~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; }
-
找双亲
C FamilyNode *findParent(FamilyNode *node) { if (node == NULL) return NULL; return node->parent; }
-
找兄弟
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; } }
-
找孩子
c // someone->children 后遍历 孩子的 brother 即可
-
找堂兄弟
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; } }
-
找后代子孙
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); }
-
查询某人居于家族中的第几代
someone->deep;
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 3无用 2