一个简单的个人通讯录(基于二叉排序树)(加注释版~~~~)

来源:互联网 发布:附近的人算法 编辑:程序博客网 时间:2024/05/08 19:09

TreeNode.h:

/***********************************************************************************                            基于二叉排序树的个人通信录****** 文    件: Treenode.h* 作    者: 邹亚鹏* 部    门: 南京工程学院* 编写日期: 20012.07.19* 模块版本:* 修改记录:* ================================================================================* 版 本|  日  期  | 修改人 |* ================================================================================*      |          |        |*      |          |        |*      |          |        |* ================================================================================*************************************************************************************/#define N 50/********************定义二叉树结点数据结构体**********************/typedef struct student{    char name[N];    char studentID[N];    char brithday[N];    char tele[N];}TreeData;/**********************定义二叉树结点结构体************************/typedef struct treenode{    TreeData * stuinfo;    struct treenode * leftchild;    struct treenode * rightchild;}TREENODE;

Addressbook.h:

/***********************************************************************************                            基于二叉排序树的个人通信录****** 文    件: Addressbook.h* 作    者: 邹亚鹏* 部    门: 南京工程学院* 编写日期: 20012.07.19* 模块版本:* 修改记录:* ================================================================================* 版 本|  日  期  | 修改人 |* ================================================================================*      |          |        |*      |          |        |*      |          |        |* ================================================================================*************************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include "Treenode.h"/*********************************函数申明***************************************/extern TREENODE * mycreatetree();extern void myinsertnode(TREENODE *,TreeData *);extern void mycopy(TreeData *,char *,char *,char *,char *);extern void myeva(TreeData *);extern void preorder(TREENODE *);extern TREENODE *treeinit(TREENODE *);extern TREENODE * mysearch(TREENODE *,char *);extern int isfind(TREENODE *,char *);extern int mycorrect(TREENODE *,char *);extern TREENODE * findleaf(TREENODE *);extern TREENODE * findparent(TREENODE *,TREENODE *);extern void myremove(TREENODE *,char *);

Addressbook.c:

/***********************************************************************************                            基于二叉排序树的个人通信录****** 文    件: Addressbook.c* 作    者: 邹亚鹏* 部    门: 南京工程学院* 编写日期: 20012.07.19* 模块版本:* 修改记录:* ================================================================================* 版 本|  日  期  | 修改人 |* ================================================================================*      |          |        |*      |          |        |*      |          |        |* ================================================================================*************************************************************************************/#include "Addressbook.h"/***********************************************************************************                               赋值函数(添加学生时使用)*描述:该函数用于给结构体数据赋值。**参数:  TreeData *dest**返回值:无**注意事项:**********************************************************************************/void myeva(TreeData *dest){    printf("请输入你要添加的姓名:");    scanf("%s",dest->name);    while(1)                                 /*判断输入是否合法*/    {        printf("请输入你要添加的学号(20209XXXX):");        scanf("%s",dest->studentID);if((strlen(dest->studentID) == 9) && (dest->studentID[0] == '2')&& (dest->studentID[1] == '0')&& (dest->studentID[2] == '2')&& (dest->studentID[3] == '0')&& (dest->studentID[4] == '9')&&((dest->studentID[5] <= '9')&&(dest->studentID[5] >= '0'))&&((dest->studentID[6] <= '9')&&(dest->studentID[6] >= '0'))&&((dest->studentID[7] <= '9')&&(dest->studentID[7] >= '0'))&&((dest->studentID[8] <= '9')&&(dest->studentID[8] >= '0'))){    break;                               /*合法结束*/}else{        printf("输入有误!\n");    printf("您输入的数据必须为20209XXXX的格式(XXXX为可变数)\n");}    }    while(1)                                 /*判断输入是否合法*/    {        printf("请输入你要添加的生日(XXXX-XX-XX):");        scanf("%s",dest->brithday);if((strlen(dest->brithday) == 10) && ((dest->brithday[0] <= '9')&&(dest->brithday[0] >= '0'))&& ((dest->brithday[1] <= '9')&&(dest->brithday[1] >= '0'))&& ((dest->brithday[2] <= '9')&&(dest->brithday[2] >= '0'))&& ((dest->brithday[3] <= '9')&&(dest->brithday[3] >= '0'))&& (dest->brithday[4] == '-')&&((dest->brithday[5] <= '1')&&(dest->brithday[5] >= '0'))&&((dest->brithday[6] <= '9')&&(dest->brithday[6] >= '0'))&&(dest->brithday[7] == '-')&&((dest->brithday[8] <= '3')&&(dest->brithday[8] >= '0'))&&((dest->brithday[9] <= '9')&&(dest->brithday[9] >= '0'))){    if(dest->brithday[5] == '1')    {        if(dest->brithday[6] <= '2'){    ;}else{    goto loop;}    }    if(dest->brithday[8] == '3')    {        if(dest->brithday[9] <= '1'){    ;}else{    goto loop;}    }    break;                            /*合法结束*/}else{    loop:            printf("输入有误!\n");    printf("您输入的数据必须为XXXX-XX-XX的格式\n");}    }    while(1)                              /*判断输入是否合法*/    {        printf("请输入你要添加的电话:");        scanf("%s",dest->tele);if((strlen(dest->tele) == 11)&&((dest->tele[0] <= '9')&&(dest->tele[0] >= '0'))&&((dest->tele[1] <= '9')&&(dest->tele[1] >= '0'))&&((dest->tele[2] <= '9')&&(dest->tele[2] >= '0'))&&((dest->tele[3] <= '9')&&(dest->tele[3] >= '0'))&&((dest->tele[4] <= '9')&&(dest->tele[4] >= '0'))&&((dest->tele[5] <= '9')&&(dest->tele[5] >= '0'))&&((dest->tele[6] < '9')&&(dest->tele[6] >= '0'))&&((dest->tele[7] <= '9')&&(dest->tele[7] >= '0'))&&((dest->tele[8] <= '9')&&(dest->tele[8] >= '0'))&&((dest->tele[9] <= '9')&&(dest->tele[9] >= '0'))&&((dest->tele[10] <= '9')&&(dest->tele[10] >= '0'))){        break;                             /*合法结束*/}else{        printf("输入有误!\n");    printf("您输入的数据必须为11位数字!\n");}    }}/***********************************************************************************                               赋值函数(初始化时使用)*描述:该函数用于给结构体数据赋值。**参数:  TreeData *dest char *name  char *studentID  char *brithday   char *tele**返回值:无**注意事项:方便赋值**********************************************************************************/void mycopy(TreeData *dest,char *name,char *studentID,char *brithday,char *tele){    strcpy(dest->name,name);    strcpy(dest->studentID,studentID);    strcpy(dest->brithday,brithday);    strcpy(dest->tele,tele);}/***********************************************************************************                               寻找叶子结点函数*描述:该函数用于寻找叶子结点。**参数:TREENODE *root**返回值:TREENODE**注意事项:**********************************************************************************/TREENODE * findleaf(TREENODE *root){    static TREENODE * leaf = NULL;    if(root != NULL)                /*root位NULL返回NULL*/    {        if((root->leftchild == NULL) && (root->rightchild == NULL))  /*左右孩子为空,返回当前结点*/{    leaf = root;    return leaf;}        findleaf(root->leftchild);               /*递归调用左孩子*/findleaf(root->rightchild);                   /*递归调用右孩子*/    }    return leaf;}/***********************************************************************************                               查找父亲结点函数*描述:该函数用于查找某一叶子结点的父结点。**参数:  TREENODE *root    TREENODE *leaf**返回值:TREENODE ***注意事项:**********************************************************************************/TREENODE *findparent(TREENODE *root,TREENODE *leaf){    static TREENODE *parent = NULL;    if(root->leftchild != NULL)        /*有左孩子*/    {        if(root->leftchild == leaf)    /*判断左孩子是否为要找的孩子*/{    parent = root;}else{    findparent(root->leftchild,leaf);   /*不是就递归调用左孩子*/}    }    if(root->rightchild != NULL)     /*有右孩子*/    {        if(root->rightchild == leaf)   /*判断右孩子是否为要找的孩子*/        {            parent = root;}        else{    findparent(root->rightchild,leaf);  /*不是就递归调用右孩子*/}    }    return parent;}/***********************************************************************************                               删除函数*描述:该函数用于对指定姓名的结点进行删除。**参数:TREENODE *root,char *info**返回值:无**注意事项:删除一个结点,将一个叶子结点拉上来,并删除叶子结点**********************************************************************************/void myremove(TREENODE *root,char *info){    TREENODE *find = (TREENODE *)malloc(sizeof(TREENODE));    TREENODE *leaf = (TREENODE *)malloc(sizeof(TREENODE));    TREENODE *parent = (TREENODE *)malloc(sizeof(TREENODE));    int ret = isfind(root,info);          /*判断是否在树中*/    if(ret == 0)    {        printf("没有此人!\n");    }    else    {        find = mysearch(root,info);       /*查找结点*/        printf("确定要删除此学生:\n");        printf("确定/取消?(Y/N):");        char yn;        setbuf(stdin,NULL);               /*清输入缓存区*/        scanf("%c",&yn);        if(yn == 'Y')        {            leaf = findleaf(root);        /*找到叶子结点*/            parent = findparent(root,leaf);/*找到叶子的父亲结点*/            if(leaf == find)               /*要删除结点为叶子结点*/            {                free(find);                /*直接删除*/        if(parent->leftchild == leaf)        {            parent->leftchild = NULL;  /*将其父亲结点的对应指针置空*/        }         else        {            parent->rightchild = NULL;        }        find = NULL;           }           else           {                strcpy(find->stuinfo->name,leaf->stuinfo->name);                strcpy(find->stuinfo->studentID,leaf->stuinfo->studentID);                strcpy(find->stuinfo->brithday,leaf->stuinfo->brithday);                strcpy(find->stuinfo->tele,leaf->stuinfo->tele);        free(leaf);                        /*删除叶子*/        if(parent->leftchild == leaf)        {            parent->leftchild = NULL;        }        else        {            parent->rightchild = NULL;        }        leaf = NULL;            }    }    }}TREENODE * mycreatetree(){    TREENODE *root = NULL;    return root;}/***********************************************************************************                               添加函数*描述:该函数用于添加学生。**参数: TREENODE *root,TreeData *data**返回值:无**注意事项:**********************************************************************************/void myinsertnode(TREENODE *root,TreeData *data){    if(strcmp(root->stuinfo->studentID,data->studentID) < 0)   /*插入左孩子*/    {        if(root->leftchild == NULL)                           /*左孩子为空直接插入*/{    TREENODE *new = (TREENODE *)malloc(sizeof(TREENODE));    new->stuinfo = data;    new->leftchild = NULL;    new->rightchild = NULL;    root->leftchild = new;}else                                                     /*不为空递归调用*/{    myinsertnode(root->leftchild,data);}    }    else                                                    /*插入左孩子*/    {        if(root->rightchild == NULL)                         /*左孩子为空直接插入*/{    TREENODE *new = (TREENODE *)malloc(sizeof(TREENODE));    new->stuinfo = data;    new->leftchild = NULL;    new->rightchild = NULL;    root->rightchild = new;}else                                                   /*不为空递归调用*/{    myinsertnode(root->rightchild,data);}    }}/***********************************************************************************                               输出函数*描述:该函数用于先跟遍历输出一颗二叉树。**参数:  TREENODE *root**返回值:无**注意事项:**********************************************************************************/void preorder(TREENODE *root){    if(root != NULL)    {        printf("姓名:%s\t学号:%s\t生日:%s\t电话:%s\n",root->stuinfo->name,root->stuinfo->studentID,root->stuinfo->brithday,root->stuinfo->tele);preorder(root->leftchild);preorder(root->rightchild);    }}/***********************************************************************************                               查找函数*描述:该函数用于查找指定姓名的结点是否在树中。**参数: TREENODE *root   char *info**返回值:int**注意事项:**********************************************************************************/int isfind(TREENODE *root,char *info){    return ((root != NULL) && ((strcmp(root->stuinfo->name,info) == 0) || (isfind(root->leftchild,info) || isfind(root->rightchild,info))));}/***********************************************************************************                               查找函数*描述:该函数用于查找指定姓名的结点信息。**参数: TREENODE *root   char *info**返回值:TREENODE ***注意事项:**********************************************************************************/TREENODE * mysearch(TREENODE *root,char *info){    int ret = isfind(root,info);    static int flt = 0;                 /*第一次未找到置1,后面不在输出为找到*/    static TREENODE *find = NULL;    if((ret == 0) && (flt == 0))    {        printf("系统为找到此人!\n");    return;    }    else                                /*先根遍历查找此人*/    {    flt = 1;    if(root != NULL)    {        if(strcmp(root->stuinfo->name,info) == 0){    find = root;            printf("姓名:%s\t学号:%s\t生日:%s\t电话:%s\n",root->stuinfo->name,root->stuinfo->studentID,root->stuinfo->brithday,root->stuinfo->tele);    return find;}mysearch(root->leftchild,info);               /*递归调用左孩子*/mysearch(root->rightchild,info);              /*递归调用右孩子*/    }    }    return find;}/***********************************************************************************                               修改函数*描述:该函数用于对指定姓名结点的信息进行修该。**参数:  TREENODE *root,char *info**返回值:int**注意事项:**********************************************************************************/int mycorrect(TREENODE *root,char *info){    int ret = isfind(root,info);    static int flt = 0;                      /*第一次未找到置1,后面不在输出为找到*/    if((ret == 0) && (flt == 0))    {        printf("系统为找到此人!\n");printf("请按Enter键继续...");getchar();getchar();return;                                  /*为找到结束函数*/    }    else    {    flt = 1;    if(root != NULL)    {        if(strcmp(root->stuinfo->name,info) == 0){            printf("姓名:%s\t学号:%s\t生日:%s\t电话:%s\n",root->stuinfo->name,root->stuinfo->studentID,root->stuinfo->brithday,root->stuinfo->tele);            printf("/**************************************/\n");            printf("/*************** 1.姓名 ***************/\n");            printf("/*************** 2.学号 ***************/\n");            printf("/*************** 3.生日 ***************/\n");            printf("/*************** 4.电话 ***************/\n");            printf("/*************** 5.取消 ***************/\n");            printf("/**************************************/\n");    int choose;    char yn;    char *buffer = (char *)malloc(sizeof(char));    printf("请输入你想修改的内容或按5取消修改:");    scanf("%d",&choose);    while((choose > 5) || (choose < 1))    {        printf("输入有误!\n");printf("请重新输入要修改的内容或按5取消:");scanf("%d",&choose);    }    switch(choose)    {        case 1:                {    printf("请输入要新的姓名:");    scanf("%s",buffer);    printf("您确定要将%s更改为%s吗?(Y/N):",root->stuinfo->name,buffer);    setbuf(stdin,NULL);    scanf("%c",&yn);    if(yn == 'Y')    {        strcpy(root->stuinfo->name,buffer);printf("修改成功\n");printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();getchar();    }    else    {        printf("数据没有修改!\n");        printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();getchar();    }    break;                }                case 2:                {                    printf("请输入要新的学号:");                    scanf("%s",buffer);                    printf("您确定要将%s更改为%s吗?(Y/N):",root->stuinfo->studentID,buffer);    setbuf(stdin,NULL);                    scanf("%c",&yn);                    if(yn == 'Y')    {                        strcpy(root->stuinfo->studentID,buffer);                        printf("修改成功\n");printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();getchar();    }    else    {        printf("数据没有修改!\n");printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();getchar();    }                    break;                }                case 3:{                    printf("请输入要新的生日:");                    scanf("%s",buffer);                    printf("您确定要将%s更改为%s吗?(Y/N):",root->stuinfo->brithday,buffer);    setbuf(stdin,NULL);                    scanf("%c",&yn);                    if(yn == 'Y')                    {                        strcpy(root->stuinfo->brithday,buffer);printf("修改成功\n");printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();getchar();    }    else    {        printf("数据没有修改!\n");printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();getchar();    }    break;}                case 4:                {                    printf("请输入要新的电话:");                    scanf("%s",buffer);                    printf("您确定要将%s更改为%s吗?(Y/N):",root->stuinfo->tele,buffer);    setbuf(stdin,NULL);                    scanf("%c",&yn);                    if(yn == 'Y')                    {                        strcpy(root->stuinfo->tele,buffer);                        printf("修改成功\n");printf("请按Enter键继续...");getchar();getchar();                    }    else    {        printf("数据没有修改!\n");printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();getchar();    }                    break;                }                case 5:                {                    break;                }    }//switend    goto end;} //if==endmycorrect(root->leftchild,info);mycorrect(root->rightchild,info);} // if==NULLend} //else endend:return;}/***********************************************************************************                               菜单函数*描述:该函数用于对屏幕进行初始化。**参数:TREENODE *root**返回值:无**注意事项:**********************************************************************************/void display(TREENODE *root){    int choose;    system("clear");    printf("\n\n\n\n\n\n\n\n\n\n\n");    printf("\t\t\t   欢迎使用通讯录管理系统!\n");    printf("\n\n\n\n\n\n\n\n\n\n\n");    sleep(2);    system("clear");    while(1)    {        system("clear");        printf("/************通讯录管理系统************/\n");        printf("/*************** 1.查看 ***************/\n");        printf("/*************** 2.修改 ***************/\n");        printf("/*************** 3.添加 ***************/\n");        printf("/*************** 4.查找 ***************/\n");        printf("/*************** 5.删除 ***************/\n");        printf("/*************** 6.退出 ***************/\n");        printf("/**************************************/\n");        printf("请输入您的选择(1-6):");        scanf("%d",&choose);if((choose > 6) || (choose < 1))                /*判断输入是否合法*/{    printf("输入有误,您的选择必须在1-5之间!\n");    printf("请重新输入:");    scanf("%d",&choose);}switch(choose){    case 1:    {        system("clear");                      /*清屏*/        preorder(root);printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();        break;    }    case 2:    {        system("clear");                     /*清屏*/char *info = (char *)malloc(sizeof(char));printf("请输入要修改的人的姓名:");scanf("%s",info);mycorrect(root,info);        break;    }    case 3:    {        system("clear");                   /*清屏*/        TreeData *info = (TreeData *)malloc(sizeof(TreeData));        myeva(info);printf("您确定要添加学生:\n");                printf("姓名:%s\t学号:%s\t生日:%s\t电话:%s\n",info->name,info->studentID,info->brithday,info->tele);printf("确定/取消(Y/N)?");char yn;setbuf(stdin,NULL);scanf("%c",&yn);if(yn == 'Y'){        if(root == NULL){    root = (TREENODE *)malloc(sizeof(TREENODE));    root->stuinfo = info;    root->leftchild = NULL;    root->rightchild = NULL;}else{    myinsertnode(root,info);}printf("添加成功!\n");}else{    printf("取消添加!\n");}printf("请按Enter键继续...");getchar();getchar();        break;    }    case 4:    {        system("clear");                    /*清屏*/char *info = (char *)malloc(sizeof(char));printf("请输入要查找的人的姓名:");scanf("%s",info);mysearch(root,info);printf("请按Enter键继续...");setbuf(stdin,NULL);getchar();        break;    }    case 5:    {        system("clear");                    /*清屏*/char *info = (char *)malloc(sizeof(char));printf("请输入要删除的人的姓名:");scanf("%s",info);myremove(root,info);printf("请按Enter键继续...");getchar();                getchar();break;    }    case 6:    {        system("clear");                   /*清屏*/                printf("\n\n\n\n\n\n\n\n\n\n\n");                printf("\t\t\t\t欢迎再次使用!\n");                printf("\n\n\n\n\n\n\n\n\n\n\n");sleep(2);system("clear");        exit(0);    }    default:    {        ;    }}    }}/***********************************************************************************                               菜单函数*描述:该函数用于对屏幕进行初始化。**参数:TREENODE *root**返回值:无**注意事项:**********************************************************************************/TREENODE * treeinit(TREENODE *root){    TreeData * info[4];             /*初始化四个人,题目要求*/    int i;    for(i = 0; i < 4; i++)    {        if((info[i] = (TreeData *)malloc(sizeof(TreeData))) == NULL){    printf("分配空间失败!\n");}    }    mycopy(info[0],"张一","202090116","1990-10-11","15298377000");    mycopy(info[1],"张二","202090114","1990-10-12","15298377111");    mycopy(info[2],"张三","202090115","1990-10-13","15298377222");    mycopy(info[3],"张四","202090118","1990-10-14","15298377333");    root = (TREENODE *)malloc(sizeof(TREENODE));    root->stuinfo = info[0];    root->leftchild = NULL;    root->rightchild = NULL;    myinsertnode(root,info[1]);    myinsertnode(root,info[2]);    myinsertnode(root,info[3]);    return root;}/***********************************************************************************                               主函数*描述:主函数**参数:无**返回值:int**注意事项:**********************************************************************************/int main(){    TREENODE * root = NULL;    root = mycreatetree();    root = treeinit(root);    display(root);    return 0;}




 

原创粉丝点击