#include"stdio.h" /*I/O函数*/
#include"stdlib.h" /*其它说明*/
#include"string.h" /*字符串函数*/
#include"conio.h" /*屏幕操作函数*/
#include"dos.h" /*声音*/
typedef int Status;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef struct Telephone
{
char name[20];
char mobile[15];
char email[20];
char qq[15];
char identity_card[30];
}telephone;
typedef struct BiTNode
{
Telephone data;
BiTNode *lchild,*rchild;
}*BiTree;
Telephone P;
BiTree Tree1;
Status SearchBST_name(BiTree &Tree1,char *name,BiTree f1,BiTree &p1) // 算法9.5(b)
{ // 在根指针T所指二叉排序树中递归地查找其关键字等于name的数据元素,若查找成功,
// 则指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上访问的最后一个结点
// 并返回FALSE,指针f指向T的双亲,其初始调用值为NULL
if(!Tree1) // 查找不成功
{
p1=f1; // p指向查找路径上访问的最后一个结点
return FALSE;
}
else if(!strcmp(name,Tree1->data.name)) // 查找成功
{
p1=Tree1; // p指向该数据元素结点
return TRUE;
}
else if(strcmp(name,Tree1->data.name)>0)
{// name小于T所指结点的关键字
return SearchBST_name(Tree1->rchild,name,Tree1,p1); // 在左子树中继续递归查找
}
else
{// name大于T所指结点的关键字
return SearchBST_name(Tree1->lchild,name,Tree1,p1); // 在右子树中继续递归查找
}
}
Status InsertBST_name(BiTree &Tree1)
{ // 若二叉排序树T中没有关键字等于e.key的元素,插入e并返回TRUE;否则返回FALSE。算法9.6
BiTree p,s;
if(!SearchBST_name(Tree1,P.name,NULL,p)) // 查找不成功,p指向查找路径上访问的最后一个叶子结点
{
s=(BiTree)malloc(sizeof(BiTNode)); // 生成新结点
strcpy(s->data.name,P.name);
strcpy(s->data.identity_card,P.identity_card);
strcpy(s->data.mobile,P.mobile);
strcpy(s->data.email,P.email);
strcpy(s->data.qq,P.qq);
s->lchild=s->rchild=NULL;// 给新结点的左右孩子域赋初值空
if(!p)
{// 树T空
Tree1=s; // 待插结点*s为新的根结点
}
else if (strcmp(p->data.name,P.name)>0) // 树T不空,*s的关键字小于*p的关键字
p->lchild=s; // 待插结点*s为p所指结点的左孩子
else // 树T不空,*s的关键字大于*p的关键字
p->rchild=s; // 待插结点*s为p所指结点右孩子
return TRUE;
}
else
return FALSE; // 树中已有关键字相同的结点,不再插入
}
Status InsertBST_name(BiTree &Tree1,char *e)
{ // 若二叉排序树T中没有关键字等于e.key的元素,插入e并返回TRUE;否则返回FALSE。算法9.6
BiTree p,s;
if(!SearchBST_name(Tree1,e,NULL,p)) // 查找不成功,p指向查找路径上访问的最后一个叶子结点
{
s=(BiTree)malloc(sizeof(BiTNode)); // 生成新结点
strcpy(s->data.name,e);
strcpy(s->data.identity_card,P.identity_card);
strcpy(s->data.mobile,P.mobile);
strcpy(s->data.email,P.email);
strcpy(s->data.qq,P.qq);
s->lchild=s->rchild=NULL;// 给新结点的左右孩子域赋初值空
if(!p)
{// 树T空
Tree1=s; // 待插结点*s为新的根结点
}
else if (strcmp(p->data.name,e)>0) // 树T不空,*s的关键字小于*p的关键字
p->lchild=s; // 待插结点*s为p所指结点的左孩子
else // 树T不空,*s的关键字大于*p的关键字
p->rchild=s; // 待插结点*s为p所指结点右孩子
return TRUE;
}
else
return FALSE; // 树中已有关键字相同的结点,不再插入
}
void Delete1(BiTree &Tree1)/*删除记录*/
{
BiTree q,s,p;
char a[20];
{
printf("\n\t\t请输入要删除人的姓名:");
scanf("%s",a);
if(SearchBST_name(Tree1,a,NULL,p))
{
if(!p->rchild)
{
q=p;
p=p->lchild;
free(q);
}
else
{
if(!p->lchild)
{
q=p;
p=p->rchild;
free(q);
}
else // p的左右子树均不空
{
s=p->lchild; // s指向待删除结点的左孩子(s由p转左)
while(s->rchild) // s有右孩子
{
q=s; // q指向s
s=s->rchild; // s指向s的右孩子
} // s向右到尽头(s指向待删结点的前驱结点,q指向s的双亲结点)
p->data=s->data; // 将待删结点前驱的值取代待删结点的值
if(q!=p) // 情况①,待删结点的左孩子有右子树
q->rchild=s->lchild; // 重接*q的右子树
else // 情况②,待删结点的左孩子没有右子树
q->lchild=s->lchild; // 重接*q的左子树
free(s); // 释放s所指结点
}
}
printf("\n\t\t删除成功!\n\n");
}
else
printf("\n\t\t电话本中无此姓名,请重新输入!\n\n");
}
}
void Modify1(BiTree &Tree1)/*修改记录*/
{
BiTree p;
char a[20];
printf("\n\t\t请输入要修改人的姓名:");
scanf("%s",a);
if(SearchBST_name(Tree1,a,NULL,p)!=0)
{
printf("\n\t\t请按要求输入!-----谢谢!\n");
getchar();
printf("\n\t\t请输入姓名(中文4):");
gets(P.name);
printf("\n\t\t请输入EMAIL地址(英文20):\n");
printf("\t\t******** @ .COM******\n\t\t");
gets(P.email);
printf("\n\t\t请输入电话(数字11):");
gets(P.mobile);
printf("\n\t\t请输入QQ号码(8):");
gets(P.qq);
printf("\n\t\t请输入身份证号码(数字18):");
gets(P.identity_card);
printf("\n\t\t修改成功!\n\n");
InsertBST_name(Tree1,P.name);
}
else
printf("\n\t\t请仔细查对,电话本中此名字!\n\n");
}
void find_name(BiTree &Tree1)
{
BiTree q;
char c;
char a[20];
printf("\n\t\t请输入要查找人的姓名:");
scanf("%s",&a);
if(SearchBST_name(Tree1,a,NULL,q)==0)
{
printf("\n\t\t电话本中无此姓名,请查对一下姓名再查找!\n\n");
getchar();
return;
}
else
{
printf("\n\t\t\t要查找的资料如下所示:\n");
printf("\n************************** ****************************\n");
printf("\t姓名 email地址 电话 QQ号码 身份证号码\n");
printf("\t%-10s%-10s%-15s%-10s%-15s%--\n",q->data.name,q->data.email,q->data.mobile,q->data.qq,
q->data.identity_card);
printf("\t\t删除(d)/修改(m)/退出这一步(s)\n");
printf("\n\t\t请输入您的选择(d/m/s):\n\t\t");
getchar();
scanf("%c",&c);
switch(c)
{
case 'D':
case 'd': Delete1(Tree1); break;
case 'M':
case 'm': Modify1(Tree1);break;
default : break;
}
}
}
void Preordertraverse1(BiTree &Tree1)
{
if(Tree1)
{
printf("\n\t\t******************************************************\n");
printf("\t\t姓名 email地址 电话 QQ号码 身份证号码\n");
printf("\t\t******************************************************\n");
if(strlen(Tree1->data.name))
printf("\t\t%-8s%-10s%-10s%-10s%",Tree1->data.name,Tree1->data.email,Tree1->data.mobile,Tree1->data.qq,Tree1->data.identity_card);
Preordertraverse1(Tree1->lchild);
Preordertraverse1(Tree1->rchild);
}
}
void save1(BiTree &Tree1)/*记录保存为文件*/
{
FILE *fp;
fp=fopen("telephone.txt","w");
if(!fp)
{
printf("无法打开目标文件!程序退出!\n");
getchar();
exit(0);
}
else
{
if(Tree1)
{
fprintf(fp,"%s %s %s %s %s %s",Tree1->data.name,Tree1->data.email,Tree1->data.mobile,Tree1->data.qq, Tree1->data.identity_card);
save1(Tree1->lchild);
save1(Tree1->rchild);
printf("\n\t\t保存成功!\n\n");
}
fclose(fp);
}
}
void Init_data1(BiTree &Tree1)
{
int n,i;
printf("\n\t\t请按要求输入!-----谢谢!\n");
printf("\n\t\t请输入加入人数:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
getchar();
printf("\n\t\t请输入姓名(中文4):");
gets(P.name);
printf("\n\t\t请输入EMAIL地址(英文20):");
printf("\n\t\t ******** @ .COM*******\n\t\t");
gets(P.email);
printf("\t\t请输入电话(数字11):");
gets(P.mobile);
printf("\n\t\t请输入QQ号码(8):");
gets(P.qq);
printf("\n\t\t请输入身份证号码(数字18):");
gets(P.identity_card);
InsertBST_name(Tree1,P.name);
printf("\n\t\t添加成功!\n");
}
}
void main()
{
FILE *fp;
void UserInterface();
int flag=0;
int choice=0;
fp=fopen("telephone.txt","r");
if(!fp)
{
printf("\n\t通信录不存在,请先新增联系人!\n\n按任意键继续... ...");
getchar();
exit(0);
}
while(1)
{
fread(&P,sizeof(telephone),1,fp);
if(feof(fp))
break;
else