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

xiaoxiao2021-03-01  36

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==end mycorrect(root->leftchild,info); mycorrect(root->rightchild,info); } // if==NULLend } //else end end: 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; }

相关资源:基于二叉搜索树实现的电话簿程序
转载请注明原文地址: https://www.6miu.com/read-4199944.html

最新回复(0)