1:废话不多说先看成果。
QQ录屏20230418163603
QQ录屏20230418163732
2:解析:
1:不知道会有多少个孩子,所以我们用二叉树的孩子兄弟结构
typedef struct treeNode {
char name[100];//名字
int generation;//辈分
char gender;//性别
char birth[11];//生日
char death[11];//死亡
struct treeNode* firstChild;//第一个孩子
struct treeNode* nextSibling;//兄弟
} TreeNode, * Tree;
2:创立新节点
Tree createNode(char* name, int generation, char gender, char* birth, char* death) {// 创建一个新节点
Tree node = (Tree)malloc(sizeof(TreeNode));
strcpy(node->name, name);
node->generation = generation;
node->gender = gender;
strcpy(node->birth, birth);
strcpy(node->death, death);
node->firstChild = NULL;
node->nextSibling = NULL;
return node;
}
3:因为我没加父亲指针,所以这里又加了一个确立父子关系的函数
void insertChild(Tree parent, Tree child) {//确定父子关系
if (parent == NULL || child == NULL) {
return;
}
if (parent->firstChild == NULL) { // 如果该节点没有子节点,则直接将新节点作为子节点
parent->firstChild = child;
}
else { // 否则在子节点链表尾部添加新节点
Tree sibling = parent->firstChild;
while (sibling->nextSibling != NULL) {
sibling = sibling->nextSibling;
}
sibling->nextSibling = child;
}
}
4:先序遍历显示整个家谱
void traverseTree(Tree root) {//全部输出
char a[100];
if (root == NULL) {
return;
}
if (root->generation == 1)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(130, i, a); i += 100;
}
else if (root->generation == 2)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(260, j, a); j += 100;
}
else if (root->generation == 3)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(390, o, a); o += 100;
}
else if (root->generation == 4)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(510, u, a); u += 100;
}
else if (root->generation == 5)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(640, y, a); y += 100;
}
else if (root->generation == 6)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(770, t, a); t += 100;
}
else if (root->generation == 7)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(900, r, a); r += 100;
}
traverseTree(root->firstChild);
traverseTree(root->nextSibling);
}
5:因为没加父亲指针,又要想想怎么找父亲的节点
Tree findParent(Tree root, Tree p) {//找父亲节点
if (root == NULL || p == NULL) {
return NULL;
}
if (root == p) { // 如果要查找的是根节点,则其没有父亲节点
return NULL;
}
Tree q = root->firstChild;
while (q != NULL) {
Tree parent = findParent(q, p); // 递归查找节点p的父亲节点
if (parent != NULL) {
return parent;
}
q = q->nextSibling; // 遍历root的下一个兄弟节点
}
// 如果root的孩子节点中没有包含节点p,则判断root是否为p的父亲节点
if (root->firstChild == p) {
return root;
}
else {
Tree sibling = root->firstChild;
while (sibling != NULL && sibling != p) {
sibling = sibling->nextSibling;
}
if (sibling != NULL) {
return root;
}
}
return NULL; // 没有找到节点p,返回NULL
}
6:有了父亲节点就可以进行删除了
void deleteMember(Tree root) {//删除成员
char name[100];
InputBox(name, 100, "请输入要删除的成员姓名:");
Tree node = searchNode(root, name);
if (node == NULL) {
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(690, 200, "没找到");
return;
}
// 删除该节点及其所有子节点
if (node == root) { // 如果要删除的是根节点,则直接释放整个家谱
free(root);
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(690, 200, "家谱已经清空");
return;
}
Tree parent = findParent(root, node);
Tree child = parent->firstChild;
while (child != NULL) { // 在父节点的子节点链表中删除该节点
if (child == node) { // 找到要删除的节点
if (child == parent->firstChild) { // 如果要删除的节点是第一个子节点,则直接将其后面的节点作为父节点的第一个子节点
parent->firstChild = child->nextSibling;
}
else { // 否则在子节点链表中删除该节点
Tree sibling = parent->firstChild;
while (sibling->nextSibling != child) {
sibling = sibling->nextSibling;
}
sibling->nextSibling = child->nextSibling;
}
free(node); // 释放要删除的节点
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(690, 200, "删除成功");
return;
}
child = child->nextSibling;
}
}
7:修改和添加的话,就先找到它的节点,加和改。我们直接看完整代码。这里我图形化用的有点乱,抱歉。
3:完整代码
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include<fstream>
#include<easyx.h>
#include<conio.h>
#include<graphics.h>
using namespace std;
const int i1 = 50;
int i = i1, j = i1, o = i1, u = i1, y = i1, t = i1, r = i1, k = i1;
typedef struct treeNode {
char name[100];//名字
int generation;//辈分
char gender;//性别
char birth[11];//生日
char death[11];//死亡
struct treeNode* firstChild;//第一个孩子
struct treeNode* nextSibling;//兄弟
} TreeNode, * Tree;
void huanyuan()//图形化输出家谱的时候用还原y的坐标
{
i = i1; j = i1; o = i1; u = i1; y = i1; t = i1; r = i1; k = i1;
}
Tree createNode(char* name, int generation, char gender, char* birth, char* death) {// 创建一个新节点
Tree node = (Tree)malloc(sizeof(TreeNode));
strcpy(node->name, name);
node->generation = generation;
node->gender = gender;
strcpy(node->birth, birth);
strcpy(node->death, death);
node->firstChild = NULL;
node->nextSibling = NULL;
return node;
}
void insertChild(Tree parent, Tree child) {//确定父子关系
if (parent == NULL || child == NULL) {
return;
}
if (parent->firstChild == NULL) { // 如果该节点没有子节点,则直接将新节点作为子节点
parent->firstChild = child;
}
else { // 否则在子节点链表尾部添加新节点
Tree sibling = parent->firstChild;
while (sibling->nextSibling != NULL) {
sibling = sibling->nextSibling;
}
sibling->nextSibling = child;
}
}
void beifen(Tree root, int a)//辈分输出
{
char nm[100];
if (root == NULL)
{
return;
}
if (root->generation == a)
{
strcpy(nm,root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(500, k, nm); k += 50;
}
beifen(root->firstChild, a);
beifen(root->nextSibling, a);
}
void traverseTree(Tree root) {//全部输出
char a[100];
if (root == NULL) {
return;
}
if (root->generation == 1)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(130, i, a); i += 100;
}
else if (root->generation == 2)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(260, j, a); j += 100;
}
else if (root->generation == 3)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(390, o, a); o += 100;
}
else if (root->generation == 4)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(510, u, a); u += 100;
}
else if (root->generation == 5)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(640, y, a); y += 100;
}
else if (root->generation == 6)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(770, t, a); t += 100;
}
else if (root->generation == 7)
{
strcpy(a, root->name);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(900, r, a); r += 100;
}
traverseTree(root->firstChild);
traverseTree(root->nextSibling);
}
Tree searchNode(Tree root, char* name) {//查找姓名的节点
if (root == NULL) {
return NULL;
}
if (strcmp(root->name, name) == 0) {
return root; // 如果找到了,则返回该节点
}
// 否则递归查找该节点的子节点
Tree child = root->firstChild;
while (child != NULL) {
Tree node = searchNode(child, name);
if (node != NULL) {
return node;
}
child = child->nextSibling;
}
return NULL;
}
void chazhao(Tree root, char* name)//查姓名
{
int a;
Tree node=searchNode(root, name);
if (node == NULL)
{
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(690, 200, "没查到");
return;
}
a = node->generation;
char str[10];
sprintf(str, "%d", a);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(690, 200, node->name);
outtextxy(690, 250, str);
outtextxy(690, 400, node->gender);
outtextxy(690, 300, node->birth);
outtextxy(690, 350, node->death);
}
Tree findParent(Tree root, Tree p) {//找父亲节点
if (root == NULL || p == NULL) {
return NULL;
}
if (root == p) { // 如果要查找的是根节点,则其没有父亲节点
return NULL;
}
Tree q = root->firstChild;
while (q != NULL) {
Tree parent = findParent(q, p); // 递归查找节点p的父亲节点
if (parent != NULL) {
return parent;
}
q = q->nextSibling; // 遍历root的下一个兄弟节点
}
// 如果root的孩子节点中没有包含节点p,则判断root是否为p的父亲节点
if (root->firstChild == p) {
return root;
}
else {
Tree sibling = root->firstChild;
while (sibling != NULL && sibling != p) {
sibling = sibling->nextSibling;
}
if (sibling != NULL) {
return root;
}
}
return NULL; // 没有找到节点p,返回NULL
}
void addMember(Tree root) {//添加成员
char name[100], generation,b[10], gender, birth[11], death[11];
InputBox(name, 100, "请输入成员姓名:");
InputBox(b, 100, "请输入性别(M/F):");
gender = b[0];
InputBox(birth, 100, "请输入出生日期(格式:yyyy-mm-dd):");
InputBox(death, 100, "请输入死亡日期(格式:yyyy-mm-dd,如在世请输入“-”):");
Tree node = createNode(name, 1, gender, birth, death);
InputBox(name, 100, "请选择该成员的父亲或母亲姓名:");
Tree parent = searchNode(root, name);
if (parent == NULL) {
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(690, 200, "未找到他的父母,请确认后重试");
return;
}
insertChild(parent, node);
node->generation = parent->generation + 1;
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(690, 200, "添加成功");
}
void modifyMember(Tree root) {// 修改成员信息
char name[100], birth[100], death[100];
InputBox(name, 100, "请输入要修改信息的成员姓名:");
Tree node = searchNode(root, name);
if (node == NULL) {
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(690, 200, "没查到");
return;
}
InputBox(birth, 100, "请输入新的出生日期(格式:2002-12-28):");
strcpy(node->birth, birth);
InputBox(name, 100, "请输入新的死亡日期(格式:2002-12-28,如在世请输入“-”):");
strcpy(node->death, death);
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(690, 200, "修改成功");
}
void deleteMember(Tree root) {//删除成员
char name[100];
InputBox(name, 100, "请输入要删除的成员姓名:");
Tree node = searchNode(root, name);
if (node == NULL) {
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(690, 200, "没找到");
return;
}
// 删除该节点及其所有子节点
if (node == root) { // 如果要删除的是根节点,则直接释放整个家谱
free(root);
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(690, 200, "家谱已经清空");
return;
}
Tree parent = findParent(root, node);
Tree child = parent->firstChild;
while (child != NULL) { // 在父节点的子节点链表中删除该节点
if (child == node) { // 找到要删除的节点
if (child == parent->firstChild) { // 如果要删除的节点是第一个子节点,则直接将其后面的节点作为父节点的第一个子节点
parent->firstChild = child->nextSibling;
}
else { // 否则在子节点链表中删除该节点
Tree sibling = parent->firstChild;
while (sibling->nextSibling != child) {
sibling = sibling->nextSibling;
}
sibling->nextSibling = child->nextSibling;
}
free(node); // 释放要删除的节点
settextcolor(YELLOW);
settextstyle(25, 0, _T("楷体"));
outtextxy(690, 200, "删除成功");
return;
}
child = child->nextSibling;
}
}
void anjian()
{
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(20, 50, _T("显示家谱"));
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(20, 150, _T("查找成员"));
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(20, 250, _T("添加成员"));
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(20, 350, _T("修改成员"));
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(20, 450, _T("删除成员"));
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(20, 550, _T("退出"));
}
void fanhui()
{
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(900, 600, _T("返回"));
}
void tuichu()
{
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(380, 1, _T("真的要退出吗?"));
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(170, 100, _T("嗯,下次再见"));
settextcolor(YELLOW);
settextstyle(50, 0, _T("楷体"));
outtextxy(610, 100, _T("算了,再待一会"));
}
void chazhaoanjian()
{
settextcolor(RED);
settextstyle(25, 0, _T("楷体"));
outtextxy(130, 1, _T("按姓名查"));
outtextxy(430, 1, _T("按辈分查"));
outtextxy(726, 1, _T("查父母"));
outtextxy(128, 352, _T("查子女"));
outtextxy(428, 351, _T("查兄弟"));
}
int main()
{
char name[100];
int n;
char a[100], b, c[100], d[100], e[100];
int generation;
fstream file;
file.open("D:\\算法\\家谱系统\\jiapu.txt", ios::in);
file >> a >> generation >> b >> c >> d >> e;
Tree node1 = createNode(a, generation, b, c, d);
while (!file.eof())
{
file >> a >> generation >> b >> c >> d >> e;
Tree node2 = createNode(a, generation, b, c, d);
Tree node3 = searchNode(node1, e);
insertChild(node3, node2);
}
initgraph(1000, 700);
IMAGE backgroung;
loadimage(&backgroung, _T("D:\\SteamLibrary\\steamapps\\workshop\\content\\431960\\2931161999\\preview.jpg"), 1000, 700);
putimage(0, 0, &backgroung);
anjian();//按键
fanhui();//返回按键
while (1)
{
BeginBatchDraw();
putimage(0, 0, &backgroung);
anjian();
MOUSEMSG msg = GetMouseMsg();
if (msg.x > 20 && msg.x < 220 && msg.y>50 && msg.y < 100 && msg.uMsg == WM_LBUTTONDOWN)//显示家谱
{
IMAGE bg;
loadimage(&bg, _T("D:\\SteamLibrary\\steamapps\\workshop\\content\\431960\\2953870227\\preview.jpg"), 1000, 700);
putimage(0, 0, &bg);
settextcolor(RED);
settextstyle(25, 0, _T("楷体"));
outtextxy(130, 1, _T("第一代"));
outtextxy(260, 1, _T("第二代"));
outtextxy(390, 1, _T("第三代"));
outtextxy(510, 1, _T("第四代"));
outtextxy(640, 1, _T("第五代"));
outtextxy(770, 1, _T("第六代"));
outtextxy(900, 1, _T("第七代"));
traverseTree(node1);
huanyuan();
fanhui();
while (1)
{
BeginBatchDraw();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if (msg.x > 20 && msg.x < 220 && msg.y>150 && msg.y < 200 && msg.uMsg == WM_LBUTTONDOWN)//查找成员
{
IMAGE bg;
loadimage(&bg, _T("D:\\SteamLibrary\\steamapps\\workshop\\content\\431960\\2809204709\\preview.jpg"), 1000, 700);
putimage(0, 0, &bg);
fanhui();
chazhaoanjian();
while (1)
{
BeginBatchDraw();
putimage(0, 0, &bg);
chazhaoanjian();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 130 && m1.x < 230 && m1.y>1 && m1.y < 26 && m1.uMsg == WM_LBUTTONDOWN)//查姓名
{
IMAGE b1;
loadimage(&b1, _T("C:\\Users\\86178\\Pictures\\Saved Pictures\\085237m64ya4rfleumyxe4.jpg"), 1000, 700);
putimage(0, 0, &b1);
char s[100];
InputBox(s, 100, "请输入姓名");
chazhao(node1, s);
fanhui();
while (1)
{
BeginBatchDraw();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if (m1.x > 430 && m1.x < 530 && m1.y>1 && m1.y < 26 && m1.uMsg == WM_LBUTTONDOWN)//查辈分
{
IMAGE b2;
loadimage(&b2, _T("C:\\Users\\86178\\Pictures\\Saved Pictures\\e40a20ca39dbb6fd24061bf14c24ab18952b37de.jpg"), 1000, 700);
putimage(0, 0, &b2);
char str[100];
InputBox(str, 100, "请输入要查找的辈分");
n = atoi(str);
beifen(node1,n);
fanhui();
while (1)
{
BeginBatchDraw();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if (m1.x > 726 && m1.x < 826 && m1.y>1 && m1.y < 26 && m1.uMsg == WM_LBUTTONDOWN)//查父母
{
IMAGE b3;
loadimage(&b3, _T("D:\\SteamLibrary\\steamapps\\workshop\\content\\431960\\2954397085\\preview.jpg"), 1000, 700);
putimage(0, 0, &b3);
char str[100];
InputBox(str, 100, "请输入要查找谁的父母");
Tree node = searchNode(node1, str);
Tree node2 = findParent(node1, node);
settextcolor(RED);
settextstyle(25, 0, _T("楷体"));
outtextxy(500, 50, "他的家长是:");
outtextxy(500, 100, node2->name);
fanhui();
while (1)
{
BeginBatchDraw();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if(m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if (msg.x > 20 && msg.x < 220 && msg.y>250 && msg.y < 300 && msg.uMsg == WM_LBUTTONDOWN)//添加成员
{
IMAGE bg;
loadimage(&bg, _T("D:\\SteamLibrary\\steamapps\\workshop\\content\\431960\\2954915142\\preview.jpg"), 1000, 700);
putimage(0, 0, &bg);
fanhui();
addMember(node1);
while (1)
{
BeginBatchDraw();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if (msg.x > 20 && msg.x < 220 && msg.y>350 && msg.y < 400 && msg.uMsg == WM_LBUTTONDOWN)//修改成员
{
IMAGE bg;
loadimage(&bg, _T("D:\\SteamLibrary\\steamapps\\workshop\\content\\431960\\2771613746\\preview.jpg"), 1000, 700);
putimage(0, 0, &bg);
fanhui();
modifyMember(node1);
while (1)
{
BeginBatchDraw();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if (msg.x > 20 && msg.x < 220 && msg.y>450 && msg.y < 500 && msg.uMsg == WM_LBUTTONDOWN)//删除成员
{
IMAGE bg;
loadimage(&bg, _T("C:\\Users\\86178\\Pictures\\Saved Pictures\\20220726235757_54919.jpeg"), 1000, 700);
putimage(0, 0, &bg);
fanhui();
deleteMember(node1);
while (1)
{
BeginBatchDraw();
fanhui();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 900 && m1.x < 1000 && m1.y>600 && m1.y < 650 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
FlushBatchDraw();
}
}
else if (msg.x > 20 && msg.x < 120 && msg.y>550 && msg.y < 600 && msg.uMsg == WM_LBUTTONDOWN)// 退出
{
tuichu();
IMAGE backgroung;
loadimage(&backgroung, _T("D:\\SteamLibrary\\steamapps\\workshop\\content\\431960\\2934572611\\preview.jpg"), 1100, 800);
putimage(0, 0, &backgroung);
while (1)
{
BeginBatchDraw();
tuichu();
MOUSEMSG m1 = GetMouseMsg();
if (m1.x > 170 && m1.x < 470 && m1.y>100 && m1.y < 150 && m1.uMsg == WM_LBUTTONDOWN)
{
break;
}
else if (m1.x > 610 && m1.x < 960 && m1.y>100 && m1.y < 150 && m1.uMsg == WM_LBUTTONDOWN)
{
goto GG;
}
FlushBatchDraw();
}
closegraph();
GG:
continue;
}
FlushBatchDraw();
}
system("pause");
}
4:文件内容在这里
唐晨 1 M 1000 1222 无
唐昊 2 M 1022 1225 唐晨
唐三 3 M 1122 1322 唐昊
唐舞桐 4 F 1206 1348 唐三
唐雨浩 5 M 1265 1451 唐舞桐
唐小桐 5 M 1268 1436 唐舞桐
唐二桐 6 F 1309 1559 唐小桐
唐皮蛋 7 M 1333 1540 唐二桐
唐三桐 7 F 1315 1594 唐小桐
唐建国 8 M 1343 1585 唐三桐
唐舞麟 4 F 1224 1374 唐三
唐轩宇 5 M 1266 1486 唐舞麟
唐小轩 6 M 1300 1560 唐轩宇
唐二轩 7 F 1330 1532 唐小轩
图片的话你可以找你喜欢的。
对了,查找中查兄弟,查子女我还没写,后续再写,所以你点了那里没反应正常。
都看到这里了,点个赞再走吧!