族谱管理

族谱(或称家谱)是一种以表谱形式,记载一个以血缘关系为主体的家族世系繁衍和重要人物事迹的特殊图书体裁。族谱是中国特有的文化遗产,是中华民族的三大文献(国史,地志,族谱)之一,属珍贵的人文资料,对于历史学、民俗学、人口学、社会学和经济学的深入研究,均有其不可替代的独特功能。本题对族谱管理进行简单的模拟,以实现查看祖先和子孙个人信息、插入家族成员、删除家族成员、修改家族成员信息、按事迹查找家族成员、列出全部家族成员及关系等功能。家族成员至少包括姓名、性别、生卒年月、配偶、简介等信息,数据结构可自行设计。

#include <stdio.h>
#include <malloc.h>
#include<string.h>
#define maxsize 100
typedef struct
{
    char name[maxsize];         //姓名
    char sex[maxsize];          //性别
    char bir[maxsize];          //出生日期
    char mate[maxsize];         //配偶
    char info[maxsize];         //简介
    int generation;             //第几代
}ElemType;
typedef struct node
{
    ElemType data;
    struct node *brother;       //左孩子
    struct node *child;         //右孩子
} BTNode;

void print(BTNode *&p)//输出节点内容
{
    printf("姓名:%s\n",p->data.name);
    printf("性别:%s\n",p->data.sex);
    printf("出生日期:%s\n",p->data.bir);
    printf("配偶:%s\n",p->data.mate);
    printf("简介:%s\n",p->data.info);
}
BTNode *create()//创建一个节点
{
    BTNode *p;
    p = (BTNode *)malloc(sizeof(BTNode));
    printf("请输入姓名:\n");
    scanf("%s",p->data.name);
    printf("请输入性别:\n");
    scanf("%s",p->data.sex);
    printf("请输入出生年月日:\n");
    scanf("%s",p->data.bir);
    printf("请输入配偶的姓名:\n");
    scanf("%s",p->data.mate);
    printf("请输入简介:\n");
    scanf("%s",p->data.info);
    printf("信息写入成功!\n");
    p->child = NULL;
    p->brother = NULL;
    return p;
}

BTNode *createFirst()//创建祖先
{
    BTNode *head;
    head = (BTNode *)malloc(sizeof(BTNode));
    printf("请输入祖先姓名:\n");
    scanf("%s",head->data.name);
    printf("请输入祖先性别:\n");
    scanf("%s",head->data.sex);
    printf("请输入祖先出生年月日:\n");
    scanf("%s",head->data.bir);
    printf("请输入祖先的配偶的姓名:\n");
    scanf("%s",head->data.mate);
    printf("请输入对祖先的简介:\n");
    scanf("%s",head->data.info);
    head ->data.generation = 1;
    head->brother = NULL;
    head->child = NULL;
    printf("祖先写入成功!\n");
    return head;
}

BTNode *preOrder(BTNode *&b,char name_[])//遍历查找
{
    BTNode *q;
    if(b == NULL)
        return NULL;
    if(strcmp(b->data.name,name_) == 0)
        return b;
    if(b->brother)
    {
        q=preOrder(b->brother,name_);  //在兄弟中找
        if(q)
            return q;
    }
    if(b->child)
    {
        q=preOrder(b->child,name_);   //在孩子中找
        if(q)
            return q;
    }
    return NULL;
}

void lookBrother(BTNode *&h)
{
    if(h != NULL)
    {
        printf("%s ",h->data.name);
        lookBrother(h->brother);
    }
}

void printAll(BTNode *&h)
{
    if(strcmp(h->data.name," ") != 0)
    {
        printf("第%d代的%s的孩子有:\n", h->data.generation, h->data.name);
        lookBrother(h->child);
        printf("\n");
    }
    if(h->child)
        printAll(h->child);
    if(h->brother)
        printAll(h->brother);
}

int addChild(BTNode *&head)
{
    char name[20];
    printf("请输入该孩子的父节点名称:\n");
    scanf("%s", name);
    BTNode *p,*q;
    p = create();
    q = preOrder(head,name);
    if(q->child == NULL)
    {
        p->data.generation = q->data.generation + 1;
        q->child = p;
        return 1;
    }
    else
    {
        q = q->child;
        while(q->brother != NULL)
        {
            q = q->brother;
        }
        p->data.generation = q->data.generation;
        q->brother = p;
        return 1;
    }
}

void printName(BTNode *&head)   //按姓名查询
{
    BTNode *node;
    char name[20];
    printf("请输入要查询的姓名:");
    scanf("%s", name);
    node = preOrder(head, name);
    print(node);
}

void deleteName(BTNode *&head)  //按姓名查询
{
    BTNode *node;
    char name[20];
    printf("请输入要删除的姓名:");
    scanf("%s", name);
    node = preOrder(head, name);
    node->child = NULL;
    strcpy(node->data.name," ");
    printf("已删除!\n");
}

void alterName(BTNode *&head)//按姓名修改
{
    BTNode *node, *newNode;
    char name[20];
    printf("请输入要修改的姓名:");
    scanf("%s", name);
    node = preOrder(head, name);
    newNode = create();
    strcpy(node->data.name, newNode->data.name);
    strcpy(node->data.bir, newNode->data.bir);
    strcpy(node->data.mate, newNode->data.mate);
    strcpy(node->data.info, newNode->data.info);
    strcpy(node->data.sex, newNode->data.sex);
}

void GetNextval(char line[], int nextval[])//对模式串求next[]值
{
    int j=0,k=-1;
    nextval[0]=-1;
    while(j<strlen(line))
    {
        if(k==-1 || line[j]==line[k])//k为-1或字符相等时
        {
            j++;
            k++;
            if(line[j]!=line[k])
                nextval[j]=k;
            else
                nextval[j]=nextval[k];
        }
        else k=nextval[k];
    }
}

int KMP(char s[], char line[])//kmp算法实现
{
    int sl=strlen(s);
    int ll=strlen(line);
    int nextval[maxsize],i=0,j=0;
    GetNextval(line,nextval);
    while(i< sl&& j<ll)
    {
        if(j==-1 || s[i]==line[j])
        {
            i++;
            j++;
        }
        else
        {
            j=nextval[j];
        }
        sl=strlen(s);
        ll=strlen(line);
    }
    if(j>=strlen(line))
        return (i-strlen(line));//返回匹配模式串的首字符下标
    else
		return -1;//返回不匹配标志
}

BTNode *keySearch(BTNode *&b,char name[])//关键字查找
{
    BTNode *q;

    if(b == NULL)
        return NULL;
    if(KMP(b->data.info,name) != -1)
        return b;
    if(b->brother)
    {
        q=keySearch(b->brother,name);   //在兄弟中找
        if(q)
            return q;
    }
    if(b->child)
    {
        q=keySearch(b->child,name);     //在孩子中找
        if(q)
            return q;
    }
    return NULL;
}

void printStory(BTNode *&head)//按关键字查找
{
    BTNode *key;
    char story[50];
    printf("请输入关键字或词:");
    scanf("%s",story);
    key = keySearch(head,story);
    print(key);
}

void menu()
{
    printf("1.添加家谱祖先\n");
    printf("2.添加孩子\n");
    printf("3.按姓名查询\n");
    printf("4.按事迹查询\n");
    printf("5.按姓名删除\n");
    printf("6.按姓名修改\n");
    printf("7.打印全部家族成员及其关系\n");
    printf("0.退出\n");
}
int main()
{
    BTNode *head;
    int m;
    while(1)
    {
        menu();
        printf("请输入选项:");
        scanf("%d",&m);
        switch(m)
        {
        case 1:
                head = createFirst();       //添加家谱祖先
                break;
        case 2:
                addChild(head);             //添加孩子
                break;
        case 3:
                printName(head);            //按姓名查询
                break;
        case 4:
                printStory(head);          //按事迹查询
                break;
        case 5:
                deleteName(head);           //按姓名删除
                break;
        case 6:
                alterName(head);            //按姓名修改
                break;
        case 7:
                printAll(head);             //列出全部家族成员及关系
                break;
        case 0:
                return 0;                    //退出
        }
    }
    return 0;
}

  

转载于:https://www.cnblogs.com/mjn1/p/11278307.html

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
家谱软件是应海峡姓氏研究之约开发的族谱管理软件。 该软件是最新开发和上市的族谱管理软件,经过专业人士的指导和专业团队的开发,是目前国内性价比很高的专业族谱管理软件。 该软件具有管理大家族的能力,扩充能力在千万、亿级别,适合修全国统谱。可以谱修全国各个姓氏的族谱,对管理姓氏无限制。在同一软件上可以管理本家族和其他家族的资料,例可以管理外亲等家族的同步资料。 经过近三年的专业团队开发已经具有完善的族谱管理功能,可以帮助专业的谱修人士完成建谱、调谱、出谱等复杂的工作。该软件已经经过专业人士的测试,指导,能够完成大部分人的修谱需求。 该软件采用最先进的开发技术,采用国外最强大的单机版数据库技术,具有无限扩充能力和功能完善能力,该数据库支持的是上亿级别的数据处理。其技术为微软的开发平台支持,是其他族谱软件所无法比拟的平台和技术支撑。采用微软的visual studio开发技术,该技术是微软的最先进开发技术,从微软创办至今一直完善的一个技术支撑。 单机版本,数据库为单一文件,不是其他族谱软件的一堆数据文件。该数据库文件可以自己备份管理,可以拷贝到其他机器硬盘等来备份。 该程序可以脱网来使用,不需要上网,完全属于自己的软件,放心,安全,不受任何网络和第三方的控制。 该软件是目前市场上唯一直接对树操作的族谱管理软件,可以在树世系图上任意增加族人,选择某一族人后可以增加兄弟或子女。增加族人人数无限制。使用鼠标右键操作,符合大家的操作习惯。可以任意修改族人在树上的位置,方便在填错父亲的情况下将其修改回原来在树上的位置。在树上的位置可以整个分支改挂到另外一个分支,调整族人分支很方便。适合先建族人后修改父亲等需求。 该软件一改以往修谱软件的特点,增加了输出word文档的功能,方便在打印前对出谱资料的二次修改,具有很强的可修改性。另外,可以将族人图形资料输出到word文档,和族人资料一起一并打印。可以打印输出族人的图形等可见信息。 可以在数据库内保存家族和族人的语音、视频、扫描资料等重要资料,由于保存在数据库内,所以具有保密性。家谱资料在数据库内可以删除、查看,方便整个家族资料的管理和完备性。 可以将世系树的结构输出到文本文档,对于家族的分支结构在树上得到很好的诠释。由于文本文档不具有格式性, 所以可以输出无限大的世系图,可以将整个家族的世系图完整输出 。 具有输出部分世系图分支的功能,可以分段输出世系图,便于将世系图分段保存和管理。配合整个世系图和分段世系图,对于某一分支可以了解自家分支的世系全貌。 可以管理多个配偶信息,配偶信息的输出是附加在族人后面,对于家庭的完整性得到很好的体现。配偶信息资料全,可以了解配偶在自家的排行、兄弟姐妹等情况。 自定义家谱输出格式,方便输出古代的五代格式。五代输出按大排行方式输出,符合大家的排行习惯。 族人输出按照大排行的顺序输出,例子老大的儿子输出要排在老二儿子的前边, 老大的孙子输出也要排在老二孙子的前边,以此类推。 可以管理家族的历史事件,历史人物,可以任意增加历史事件和历史人物,来阐述家族曾经出得辉煌。增加的人物和事件无限制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值