基于二叉排序树写的通讯录

#include"stdio.h"
#include"stdlib.h"
#include"string.h"
/****************************************************  
 copyright: self_chou  
 Filename:  carpark.c  
 AUthour : self_chou   Version: 1.0     Date: 2012.07  
 Description: 基于二叉排序树写的通讯录   
 Function List: 
              initdata()  初始化内置数据
              insert()    添加联系人
              find()      查找联系人
              change()    修改联系人信息
              delete()    删除联系人
              destory()   释放空间
*******************************************************/  

typedef struct student
{
    char name[10];
    char sno[10];
    char bir[10];
    char tel[10];
}student;

student class[50];
int current = 0;                  
int flag;                        //查找结果标记

typedef struct tree
{
    struct student *people;
    struct tree *left;
    struct tree *right;
}tree;

tree *root = NULL;

void initdata()                      //内置的联系人
{
    strcpy( class[current].name,"赵一");
    strcpy( class[current].bir,"19910214");
    strcpy( class[current].tel,"12345678");
    strcpy( class[current].sno,"20125");
    current++;
    strcpy( class[current].name,"钱二");
    strcpy( class[current].bir,"19900304");
    strcpy( class[current].tel,"09876543");
    strcpy( class[current].sno,"20126");
    current++;
    strcpy( class[current].name,"孙三");
    strcpy( class[current].bir,"19910708");
    strcpy( class[current].tel,"56780934");
    strcpy( class[current].sno,"20127");
    current++;
    strcpy( class[current].name,"李四");
    strcpy( class[current].bir,"19890506");
    strcpy( class[current].tel,"09874532");
    strcpy( class[current].sno,"20122");
    root = (tree *)malloc(sizeof(tree));
    root->people = &class[0];
    root->left = NULL;
    root->right = NULL;
}


void insert(tree * root,student *q)              //排序二叉树按学号递归插入
{
    flag = 0;
    if(strcmp(root->people->sno,q->sno) == 0)
    {
        printf("插入不成功,相同学号的人已存在\n");
	flag = 1;
	return;
    }
    if( strcmp(root->people->sno,q->sno) > 0 )
    {
        if(root->left == NULL)
	{
	    tree *p = (tree *)malloc(sizeof(tree));
	    p->people = q;
	    p->left = NULL;
	    p->right = NULL;
	    root->left = p;
	}
	else
	{
	    insert(root->left,q);
	}
    }
    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\n",root->people->name,root->people->sno,root->people->bir,root->people->tel);
             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 == 5)
                 {
		     system("clear");
		     break;
		 }
                 printf("姓名:%s      学号:%s      生日:%s      电话:%s\n",root->people->name,root->people->sno,root->people->bir,root->people->tel);
	         printf("请输入要修改的选项:\n");
                 printf("1 修改姓名\n");
		 printf("2 修改学号\n");
		 printf("3 修改生日\n");
		 printf("4 修改电话\n");
		 printf("5 退出\n");
	         printf("请输入:");
		 scanf("%d",&accept);
		 switch(accept)
		 {
		     case 1:
		           {
			       system("clear");
			       printf("你想把名字修改为:");
			       scanf("%s",buff);
			       strcpy(root->people->name,buff);
			       printf("修改成功\n");
			       break;
			   }
	             case 2:
		           {
			       system("clear");
			       printf("你想把学号修改为(5位2012开头):");
			       scanf("%s",buff);
			       strcpy(root->people->sno,buff);
			       printf("修改成功\n");
			       break;
			   }
	             case 3:
		           {
			       
			       system("clear");
			       printf("你想生日把修改为:");
			       scanf("%s",buff);
			       strcpy(root->people->bir,buff);
			       printf("修改成功\n");
			       break;
			   }
	             case 4:
		           { 
			       system("clear");
			       printf("你想把电话修改为(8位):");
			       scanf("%s",buff);
			       strcpy(root->people->tel,buff);
			       printf("修改成功\n");
			       break;
			   }
	             case 5:
		           {
			       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\n",root->people->name,root->people->sno,root->people->bir,root->people->tel);
        print(root->left);
	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->bir,temp->people->bir);
	    strcpy(child->people->tel,temp->people->tel);
	    strcpy(child->people->sno,temp->people->sno);
	    if( temppar == child)                              //后继结点为待删除结点右孩子
	    {                                                  //注意这种情况
	        temppar->right = temp->right;
	    }
	    else
	    {
	        temppar->left = temp->right;
	    }
	    free(temp);
	}
    }
}

void delete(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(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("clear");
		      if(root == NULL)
		      {
		          current++;
		          root = (tree *)malloc(sizeof(tree));
		          printf("请输入要添加的联系人姓名\n");
		          scanf("%s",accept);
                          strcpy(class[current].name,accept);
		          printf("请输入要添加联系人学号(5位:2012开头)\n");
		          scanf("%s",accept);
                          strcpy(class[current].sno,accept);
		          printf("请输入要添加的联系人生日\n");
		          scanf("%s",accept);
                          strcpy(class[current].bir,accept);
		          printf("请输入要添加的联系人电话(8位)\n");
		          scanf("%s",accept);
                          strcpy(class[current].tel,accept);
			  root->people = &class[current];
			  root->left = NULL;
			  root->right = NULL;
			  printf("添加完成\n");
			  break;
		      }
		      current++;
		      printf("请输入要添加的联系人姓名\n");
		      scanf("%s",accept);
                      strcpy(class[current].name,accept);
		      printf("请输入要添加的联系人学号(5位:2012开头)\n");
		      scanf("%s",accept);
                      strcpy(class[current].sno,accept);
		      printf("请输入要添加的联系人生日\n");
		      scanf("%s",accept);
                      strcpy(class[current].bir,accept);
		      printf("请输入要添加的联系人电话(8位)\n");
		      scanf("%s",accept);
                      strcpy(class[current].tel,accept);
		      insert(root,&class[current]);
		      if(flag == 1)
		      {
		          break;
		      }
		      printf("添加完成\n");
		      break;
		  }
            case 2:
	          {
		       system("clear");
		       if(root == NULL)
		       {
		           printf("通讯录为空\n");
			   break;
		       }
		       printf("请输入要修改的联系人姓名:\n");
		       scanf("%s",accept);
		       fun = change(root,accept);
		       if(fun == 0)
		       {
		           printf("没有你要联系人\n");
		       }
		       break;
		  }
            case 3:
	          {
		       system("clear");
		       if(root == NULL)
		       {
		           printf("通讯录为空\n");
			   break;
                       }
		       printf("请输入要查找的联系人姓名:\n");
		       scanf("%s",accept);
		       fun = find(root,accept);
		       if(fun == 0)
		       {
		           printf("联系人未找到\n");
		       }
		       break;
		  }
            case 4:
	          {
		      system("clear");
		      if( root == NULL)
		      {
		          printf("通讯录为空\n");
			  break;
		      }
		      printf("请输入要删除的联系人姓名:");
		      scanf("%s",accept);
		      delete(accept);
		      break;
		  }
            case 5:
	          {
		      system("clear");
		      printf("正在清除数据\n");
		      destory(root);
		      printf("欢迎使用本通讯录,seeyou!\n");
                      exit(0);
		  }
            default:
	           {
		       system("clear");
		       printf("输入有误,请重新输入!\n");
		       break;
	           }

	}
    }
}

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



 

你可能感兴趣的:(基于二叉排序树写的通讯录)