#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include"mem.txt"
int found=0;
int count=0;
typedef struct Mem {
char name[20];
int generation;
struct Mem* parent;
struct Mem* lchild;
struct Mem* rchild;
} Mem;
Mem* familyRoot = NULL;
Mem* findMem(Mem* bt,char *na)
{
Mem *lresult,*rresult;
if(!bt)
{
return NULL;
}
if(strcmp(bt->name,na)==0)
return bt;
else
{
lresult=findMem(bt->lchild,na);
rresult=findMem(bt->rchild,na);
return lresult?lresult:(rresult?rresult:NULL);
}
}
void findDescendants(Mem* mem) {
if (mem == NULL) {
return;
}
if (mem->lchild != NULL) {
findDescendants(mem->lchild);
}
if (mem->rchild != NULL) {
findDescendants(mem->rchild);
}
printf("%s ", mem->name);
}
void findAncestors(Mem* mem) {
if(mem==NULL)
{
printf("无祖先\n");
return;
}
while (mem != NULL) {
printf("%s ", mem->name);
mem = mem->parent;
}
}
void printGeneration(char* name) {
Mem* mem = findMem(familyRoot,name);
if (mem == NULL) {
printf("%s 成员不存在\n", name);
} else {
printf("%s 的辈分为 %d\n", name, mem->generation);
}
}
void printByGeneration(Mem* p,int root) {
if(p==NULL) return;
//printf("第 %d 辈成员:\n", root);
if(p->generation==root)
{
printf("%s ",p->name);
found=1;
}
printByGeneration(p->lchild,root);
printByGeneration(p->rchild,root);
}
void addMem(char* name, char* parentName) {
Mem* mem= (Mem*)malloc(sizeof(Mem));
strcpy(mem->name, name);
mem->generation = -1; // 先默认为-1,之后再计算
mem->parent = NULL;
mem->lchild = NULL;
mem->rchild = NULL;
if (familyRoot == NULL) { // 如果还没有根节点,则当前成员为根节点
familyRoot = mem;
}
else {
Mem* parent = findMem(familyRoot,parentName);
if (parent == NULL) { // 如果父亲不存在,则直接将新成员挂到根节点下
mem->parent = familyRoot;
familyRoot->lchild = mem;
}
else {
if (parent->lchild == NULL) {
parent->lchild = mem;
}
else if (parent->rchild == NULL) {
parent->rchild = mem;
}
else { // 父亲已有两个孩子,不能再添加了
printf("无法添加 %s 成员,因为 %s 已经有两个孩子了\n", name, parent->name);
free(mem);
return;
}
mem->parent = parent; // 设置父亲指针
}
}
// 计算成员辈分
Mem* p = mem;
int gen = 1;
while (p->parent !=NULL) {
gen++;
p = p->parent;
}
mem->generation = gen;
printf("%s 成员添加成功,辈分为 %d\n", name, gen);
}
void deleteMem(Mem* mem) {
if (mem == NULL) {
return;
}
deleteMem(mem->lchild);
deleteMem(mem->rchild);
if (mem->parent == NULL) {
return;
}
else {
if (mem->parent->lchild == mem) {
mem->parent->lchild = NULL;
}
else {
mem->parent->rchild = NULL;
}
}
printf("%s 成员删除成功\n", mem->name);
free(mem);
}
Mem* findL(Mem* m1, Mem* m2) {
if (m1 == NULL || m2 == NULL) {
return NULL;
}
if (m1 == m2) {
return m1;
}
Mem* p1 = m1;
while (p1 != NULL) {
Mem* p2 = m2;
while (p2 != NULL) {
if (p1 == p2) {
return p1;
}
p2 = p2->parent;
}
p1 = p1->parent;
}
return NULL;
}
int countson(Mem* gen)
{
if(!gen) return 0;
return countson(gen->lchild)+countson(gen->rchild)+1;
}
int main() {
int num;
char name[20];
char parentname[20];
int root;
Mem* mem1;
Mem* mem2;
FILE* fp = fopen("mem.txt", "r");
if (fp == NULL) {
printf("无法打开文件:mem.txt\n");
return 1;
}
char line[100];
while (fgets(line, 100, fp) != NULL) {
sscanf(line, "%s %s", name, parentname);
addMem(name, parentname);
}
fclose(fp);
while (1) {
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(" 9. 输出节点所有子孙数\n");
printf(" 10. 退出程序\n");
printf("---------------------------------\n");;
printf("请输入选项(1-9):");
scanf("%d", &num);
switch (num) {
case 1:
printf("请输入成员姓名:");
scanf("%s", name);
mem1 = findMem(familyRoot,name);
if (mem1 == NULL) {
printf("%s 成员不存在\n", name);
}
else {
printf("%s 成员辈分为 %d,父亲是 %s\n", name, mem1->generation,
mem1->parent == NULL ? "NULL" : mem1->parent->name);
}
break;
case 2:
printf("请输入成员姓名:");
scanf("%s", name);
mem1 = findMem(familyRoot,name);
if (mem1 == NULL) {
printf("%s 成员不存在\n", name);
}
else {
printf("%s 的所有子孙为:", name);
if(mem1->lchild)
findDescendants(mem1->lchild);
if(mem1->rchild)
findDescendants(mem1->rchild);
printf("\n");
}
break;
case 3:
printf("请输入成员姓名:");
scanf("%s", name);
mem1 = findMem(familyRoot,name);
if (mem1 == NULL) {
printf("%s 成员不存在\n", name);
}
else {
printf("%s 的所有祖先为:", name);
findAncestors(mem1->parent);
printf("\n");
}
break;
case 4:
printf("请输入成员姓名:");
scanf("%s", name);
printGeneration(name);
break;
case 5:
printf("请输入辈份:");
scanf("%d", &root);
printf("第 %d 辈成员:\n", root);
printByGeneration(familyRoot,root);
if (!found) {
printf("没有第 %d 辈的成员\n", root);
}
printf("\n");
found=0;
break;
case 6:
printf("请输入成员姓名和父亲姓名(用空格分隔):");
scanf("%s %s", name, parentname);
addMem(name, parentname);
break;
case 7:
printf("请输入成员姓名:");
scanf("%s", name);
mem1 = findMem(familyRoot,name);
if (mem1 == NULL) {
printf("%s 成员不存在\n", name);
}
else {
deleteMem(mem1);
}
break;
case 8:
printf("请输入两个成员的姓名(用空格分隔):");
scanf("%s %s", name, parentname);
mem2 = findMem(familyRoot,parentname);
mem1 = findMem(familyRoot,name);
if (mem1 == NULL || mem2 == NULL) {
printf("至少有一个成员不存在\n");
}
else {
Mem* l = findL(mem1, mem2);
if (l == NULL) {
printf("%s 和 %s 没有最近公共祖先\n", name, parentname);
}
else {
printf("%s 和 %s 的最近公共祖先为 %s\n", name, parentname, l->name);
}
}
break;
case 9:
printf("请输入要查寻的名字\n");
scanf("%s",&name);
mem1=findMem(familyRoot,name);
if(mem1==NULL)
{
printf("不存在该名字");
}
else{
//countson(mem1);
printf("该节点的子孙数为 %d\n",countson(mem1)-1);
}
count = 0;
break;
case 10:
return 0;
default:
printf("输入错误,请重新输入\n");
}
}
return 0;
}
初始族谱使用文本输入
格式为:第一行为根节点姓名,之后每一行两个名字,第一个名字为第二个名字的孩子,用空格隔开
标签:LYU,name,mem,系统,Mem,mem1,printf,NULL,族谱 From: https://blog.csdn.net/CYL408/article/details/139623976