2 weixin 37227218 weixin_37227218 于 2017.01.01 23:25 提问

求解课设过程中出现的这个问题

使用二叉树完成的通讯录管理,输出的时候重复输出。。
代码:#include
#include
#include
#include
using namespace std;
/*****************************************************
Description: 基于二叉排序树的通讯录管理系统
Function List:
initdata() 初始化内置数据
insert() 添加联系人
find() 查找联系人
change() 修改联系人信息
del() 删除联系人
destory() 释放空间
*******************************************************/

typedef struct student
{
char name[12];
char sex[2];
char hometown[20];
char tel_num[20];
char post[6];
char email[20];
char QQ[20];
}student; //定义二叉链表结构体

//查找结果标记
student myClass[50];
int count = 0; //通讯录人数初始化
int flag;

typedef struct tree
{
struct student *people;
struct tree *left;
struct tree *right;
}tree; //定义树

tree *root = NULL; //根节点初始化为空

void initdata() //内置的联系人的初始化
{
strcpy( myClass[count].name,"张小三");
strcpy( myClass[count].sex,"男");
strcpy( myClass[count].hometown,"南京");
strcpy( myClass[count].tel_num,"152****6578");
strcpy( myClass[count].post,"222666");
strcpy( myClass[count].email,"871011891@qq.com");
strcpy( myClass[count].QQ,"871011891");
count++;
strcpy( myClass[count].name,"李小四");
strcpy( myClass[count].sex,"男");
strcpy( myClass[count].hometown,"上海");
strcpy( myClass[count].tel_num,"134****1786");
strcpy( myClass[count].post,"222787");
strcpy( myClass[count].email,"789455511@qq.com");
strcpy( myClass[count].QQ,"789455511");
count++;
strcpy( myClass[count].name,"王二虎");
strcpy( myClass[count].sex,"女");
strcpy( myClass[count].hometown,"北京");
strcpy( myClass[count].tel_num,"177****4572");
strcpy( myClass[count].post,"244761");
strcpy( myClass[count].email,"1543694145@qq.com");
strcpy( myClass[count].QQ,"1543694145");
root = (tree *)malloc(sizeof(tree));
root->people = &myClass[0]; //记录下people的初始地址
root->left = NULL;
root->right = NULL;
}

void insert(tree * root,student *q) //排序二叉树按姓名递归插入
{
flag = 0;
if(strcmp(root->people->name,q->name) == 0)
{
printf("插入不成功,相同姓名的人已存在\n");
flag = 1;
return;
}
if( strcmp(root->people->name,q->name) > 0 )//调用strcmp函数比较字符串,判断是否有名字重复
{
if(root->left == NULL)
{
tree *p = (tree *)malloc(sizeof(tree)); //给指针p分配一个tree型结构体大小的内存
p->people = q;
p->left = NULL;
p->right = NULL;
root->left = p;
}
else
{
insert(root->left,q); //递归调用insert插入联系人
}
}
else
{
if( root->right == NULL)
{
tree *p = (tree *)malloc(sizeof(tree));
p->people= q;
p->left = NULL;
p->right = NULL;
root->right = p;
}
else
{
insert(root->right,q);
}
}
}

int find(tree root,char *p) //先跟遍历查找
{
int flag;
if( root!= NULL )
{
if( strcmp(root->people->name,p) == 0)
{
printf("已找到该联系人:\n");
printf("姓名:%s 性别:%s 家乡:%s 电话:%s 邮编:%s Email:%s QQ:%s\n",root->people->name,root->people->sex,root->people->hometown,root->people->tel_num,root->people->post,root->people->email,root->people->QQ);
return 1; //查找成功标记
}
flag = find(root->left,p);
if(flag>0)
{
return 1;
}
flag = find(root->right,p);
if(flag > 0)
{
return 1;
}
}
return 0;
}
/
修改联系人信息操作*/
int change(tree *root,char *p) //先根遍历,查找到后修改
{
int flag;
if(root != NULL)
{
if( strcmp(root->people->name,p) == 0)
{
int accept = 0;
char buff[20];
while(1)
{
if(accept == 6)
{
system("cls");
break;
}
printf("姓名:%s 性别:%s 家乡:%s 电话:%s 邮编:%s Email:%s QQ:%s\n",root->people->name,root->people->sex,root->people->hometown,root->people->tel_num,root->people->post,root->people->email,root->people->QQ);
printf("请输入要修改的选项:\n");
printf("1 修改姓名\n");
printf("2 修改性别\n");
printf("3 修改家乡\n");
printf("4 修改电话\n");
printf("5 修改邮编\n");
printf("6 修改Email\n");
printf("7 修改QQ\n");
printf("8 退出\n");
printf("请输入:");
scanf("%d",&accept);
switch(accept)
{
case 1:
{
system("cls");
printf("你想把名字修改为:");
scanf("%s",buff);
strcpy(root->people->name,buff);
printf("修改成功\n");
break;
}
case 2:
{
system("cls");
printf("你想把性别修改为:");
scanf("%s",buff);
strcpy(root->people->sex,buff);
printf("修改成功\n");
break;
}
case 3:
{

                system("cls");
                printf("你想家乡把修改为:");
               scanf("%s",buff);
                strcpy(root->people->hometown,buff);
                printf("修改成功\n");
                break;
           }
              case 4:
               {
                system("cls");
                printf("你想把电话修改为:");
                scanf("%s",buff);
                strcpy(root->people->tel_num,buff);
               printf("修改成功\n");
                break;
           }
              case 5:
            {
                system("你想把邮编修改为:");
                scanf("%s,buff");
                strcpy(root->people->post,buff);
                break;
            }
              case 6:
            {
                system("你想把Email修改为:");
                scanf("%s,buff");
                strcpy(root->people->email,buff);
                break;
            }
             case 7:
                  {
                system("你想把QQ修改为:");
                scanf("%s,buff");
                strcpy(root->people->QQ,buff);
                break;
            }
              case 8:{
                     break;}
             default:
                {
                printf("输入有误,请重新输入\n");
                break;
           }

      }

      }
      return 1;
}
 flag = change(root->left,p);
 if(flag >0 )
 {
    return 1;
 }
flag = change(root->right,p);
 if(flag >0)
 {
     return 1;
 }
}
 return 0;

}
/*打印出联系人信息*/
void print(tree *root)
{
if(root != NULL)
{
printf("姓名:%s 性别:%s 家乡:%s 电话:%s 邮编:%s Email:%s QQ:%s\n",root->people->name,root->people->sex,root->people->hometown,root->people->tel_num,root->people->post,root->people->email,root->people->QQ);
print(root->left);
putchar('\n');
print(root->right);
}
}

tree * findparent(char *p,tree *root,tree *parent) //找寻待删除结点的父母结点
{
if( root != NULL)
{
if( strcmp(root->people->name,p) == 0 )
{
return parent; //和返回结点所在层次类似
}
parent = findparent(p,root->left,root);
if(parent != NULL)
{
return parent;
}
parent = findparent(p,root->right,root);
if(parent != NULL)
{
return parent;
}
}
return NULL;
}

void my_remove(tree parent,tree *child) //删除结点
{
if(child->left == NULL && child->right == NULL) //叶子节点
{
tree *temp = child;
if(temp == root) //删除的是根
{
root = NULL;
free(temp);
return;
}
if(parent->left == child) //判断是父母的左孩子还是右孩子
{
parent->left = NULL;
}
else
{
parent->right = NULL;
}
free(temp);
}
else
{
if( child->left != NULL && child->right == NULL) //1度结点
{
if(parent == NULL) //删除的是根结点
{
root = root->left;
free(child);
return;
}
if( parent->left == child) //判断左右孩子,由其父母收养
{
parent->left = child->left;
}
else
{
parent->right = child->left;
}
free(child);
}
else
if( child->left == NULL && child->right != NULL)
{
if(parent == NULL)
{
root = root->right;
free(child);
return;
}
if( parent->left == child)
{
parent->left = child->right;
}
else
{
parent->right = child->right;
}
free(child);
}
else //二度结点
{
tree *temp,*temppar;
temp = child->right;
temppar = child;
while(temp->left != NULL) //找其中根遍历下的后继结点
{
temppar = temp;
temp = temp->left;
}
strcpy(child->people->name,temp->people->name);
strcpy(child->people->sex,temp->people->sex);
strcpy(child->people->hometown,temp->people->hometown);
strcpy(child->people->tel_num,temp->people->tel_num);
strcpy(child->people->post,temp->people->post);
strcpy(child->people->email,temp->people->email);
strcpy(child->people->QQ,temp->people->QQ);
if( temppar == child) //后继结点为待删除结点右孩子
{ //注意这种情况
temppar->right = temp->right;
}
else
{
temppar->left = temp->right;
}
free(temp);
}
}
}
/
联系人的删除操作*/
void del(char *q)
{
tree *parent;
parent = findparent(q,root,NULL);
if( parent == NULL && ( strcmp( root->people->name,q) != 0 ))//判断通讯录是否为空以及传进来的联系人是否存在
{
printf("通讯录中没有此联系人,删除失败\n");
return;
}
if( parent == NULL) //调用my_remove函数,//删除分两步,先找到其父母结点,再分情况删除

 {                                      my_remove(parent,root);
}
  else
 {
     if(  parent->left != NULL && (strcmp(parent->left->people->name,q) == 0 ) )
 {
    my_remove(parent,parent->left);
 }
 else
 {
     my_remove(parent,parent->right);
 }
 }

}

void destory(tree root)
{
if(root != NULL) //释放空间
{
destory(root->left);
destory(root->right);
free(root);
}
}
/
通讯录功能的展示界面以及联系人的显示界面*/
void disp()
{
int fun;
char accept[20];
while(1)
{
printf("现有联系人按先序遍历如下:\n");
print(root);
printf(" 请输入要选择的功能\n");
printf("/************************************/\n");
printf(" 1.添加联系人\n");
printf(" 2.修改联系人信息\n");
printf(" 3.查找联系人\n");
printf(" 4.删除联系人\n");
printf(" 5.退出\n");
printf("/************************************/\n");
printf("请输入:");
scanf("%d",&fun);
switch(fun)
{
case 1:
{
system("cls");
if(root == NULL)
{
count++;
root = (tree *)malloc(sizeof(tree));
printf("请输入要添加联系人的姓名\n");
scanf("%s",accept);
strcpy(myClass[count].name,accept);
printf("请输入要添加联系人的性别\n");
scanf("%s",accept);
strcpy(myClass[count].sex,accept);
printf("请输入要添加联系人的家乡\n");
scanf("%s",accept);
strcpy(myClass[count].hometown,accept);
printf("请输入要添加联系人的电话\n");
scanf("%s",accept);
strcpy(myClass[count].tel_num,accept);
printf("请输入要添加联系人的邮编\n");
scanf("%s",accept);
strcpy(myClass[count].post,accept);
printf("请输入要添加联系人的email\n");
scanf("%s",accept);
strcpy(myClass[count].email,accept);
printf("请输入要添加联系人的QQ\n");
scanf("%s",accept);
strcpy(myClass[count].QQ,accept);
root->people = &myClass[count];
root->left = NULL;
root->right = NULL;
printf("添加完成\n");
break;
}
count++;
printf("请输入要添加联系人的姓名\n");
scanf("%s",accept);
strcpy(myClass[count].name,accept);
printf("请输入要添加联系人的性别\n");
scanf("%s",accept);
strcpy(myClass[count].sex,accept);
printf("请输入要添加联系人的家乡\n");
scanf("%s",accept);
strcpy(myClass[count].hometown,accept);
printf("请输入要添加联系人的电话\n");
scanf("%s",accept);
strcpy(myClass[count].tel_num,accept);
printf("请输入要添加联系人的邮编\n");
scanf("%s",accept);
strcpy(myClass[count].post,accept);
printf("请输入要添加联系人的email\n");
scanf("%s",accept);
strcpy(myClass[count].email,accept);
printf("请输入要添加联系人的QQ\n");
scanf("%s",accept);
strcpy(myClass[count].QQ,accept);
insert(root,&myClass[count]);
if(flag == 1)
{
break;
}
printf("添加完成\n");
break;
}
case 2:
{
system("cls");
if(root == NULL)
{
printf("通讯录为空\n");
break;
}
printf("请输入要修改的联系人姓名:\n");
scanf("%s",accept);
fun = change(root,accept);
if(fun == '\0')
{
printf("没有你要联系人\n");
}
break;
}
case 3:
{
system("cls");
if(root == NULL)
{
printf("通讯录为空\n");
break;
}
printf("请输入要查找的联系人姓名:\n");
scanf("%s",accept);
fun = find(root,accept);
if(fun == 0)
{
printf("联系人未找到\n");
}
break;
}
case 4:
{
system("cls");
if( root == NULL)
{
printf("通讯录为空\n");
break;
}
printf("请输入要删除的联系人姓名:");
scanf("%s",accept);
del(accept);
break;
}
case 5:
{
system("cls");
printf("正在清除数据\n");
destory(root);
printf("欢迎使用本通讯录,seeyou!\n");
exit(0);
}
default:
{
system("cls");
printf("输入有误,请重新输入!\n");
break;
}

}
 }

}

int main()
{
int i;
printf("正在初始化系统\n");
initdata();
for(i = 1;i <= count;i++)
{
insert(root,&myClass[i]);
}
disp();
return 0;
}图片

1个回答

qq_29566841
qq_29566841   2017.01.02 00:00

对于二叉树操作的疑惑,可以参考一下这篇博客,应该会有所帮助。二叉树 C++实现

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!