out.close();//关闭文档
}
voidSetName(charna[])//修改姓名
{
strcpy(Name,na);
}
voidSetOfficePhone(intop)//修改办公室电话
{
OfficePhone=op;
}
voidSetHomePhone(inthp)//修改住宅电话
{
HomePhone=hp;
}
voidSetMobilePhone(charmp[])//修改手机号码
{
strcpy(MobilePhone,mp);
}
voidSetE_Mail(charem[])//修改电子邮箱地址
{
strcpy(E_Mail,em);
}
friendclassAddressList;//将AddressList类说明为友元类
};
classAddressList
{
Node*HeadPtr;//链表首指针
Node*TailPtr;//链表尾指针
intTag;//排序状态标志
public:
AddressList()//构造函数,创建空链表,将Tag的值置为1
{
HeadPtr=NULL;//设置首指针的初始值为空
TailPtr=NULL;//设置尾指针的初始值为空
Tag=1;//Tag的初始值为1
}
voidAddTail(Node*p)//将p指向的结点加入到链表的尾部
{
if(HeadPtr==NULL)//如果链表为空,将数据添加在第一条
{
HeadPtr=TailPtr=p;//链表为空,首尾指针均指向p
}
else
{
TailPtr->Next=p;//如果不为空,则尾指针的Next指向p
TailPtr=p;//将p的值赋给TailPtr
TailPtr->Next=NULL;//使TailPtr的成员Next为空
}
}
voidAddSort(Node*p)//将p指向的结点按Tag指定的顺序插入到链表中
{
if(HeadPtr==NULL)//当链表为空时
{
HeadPtr=TailPtr=p;//直接将数据记录在第一条
p->Next=NULL;
}
else//如果链表不为空
{
Node*p1=HeadPtr,*p2=HeadPtr;//定义两个Node型指针变量
if(Tag==1)//按姓名排列
{
p1=HeadPtr;//将首指针赋给p1
while(strcmp(p->Name,p1->Name)>0&&p1->Next!
=NULL)//比较p中Name和p1中的大小
{
p2=p1;p1=p1->Next;
}//如果p大,就将下一个数据赋给p1,否则跳出循环
if(strcmp(p->Name,p1->Name)<=0)//如果p的成员Name比较小
{
p->Next=p1;//将p的下一个指向p1
if(HeadPtr==p1)HeadPtr=p;//如果首指针等于p1,则将p的值赋给首指针
elsep2->Next=p;
}//如果p1是第一个将p赋给HeadPtr,否则p2下一个指向p
else//如果找不到比p的Name小的数据,就将p插在链表末尾
{
p1->Next=p;//将p赋给p的下一条记录
p->Next=NULL;//而p的下一条为空
}
}
if(Tag==2)//按办公室电话排列,同按姓名排列的方法
{
p1=HeadPtr;
while((p->OfficePhone)>(p1->OfficePhone)&&p1->Next!
=NULL)
{
p2=p1;p1=p1->Next;
}
if((p->OfficePhone)<=(p1->OfficePhone))
{
p->Next=p1;
if(HeadPtr==p1)HeadPtr=p;
elsep2->Next=p;
}
else
{
p1->Next=p;
p->Next=NULL;
}
}
if(Tag==3)//按家庭电话排列,同按姓名排列的方法
{
p1=HeadPtr;
while((p->HomePhone)>(p1->HomePhone)&&p1->Next!
=NULL)
{
p2=p1;p1=p1->Next;
}
if((p->HomePhone)<=(p1->HomePhone))
{
p->Next=p1;
if(HeadPtr==p1)HeadPtr=p;
elsep2->Next=p;
}
else
{
p1->Next=p;
p->Next=NULL;
}
}
if(Tag==4)//按手机号码排列,同按姓名排列的方法
{
p1=HeadPtr;
while(strcmp(p->MobilePhone,p1->MobilePhone)>0&&p1->Next!
=NULL)
{
p2=p1;p1=p1->Next;
}
if(strcmp(p->MobilePhone,p1->MobilePhone)<=0)
{
p->Next=p1;
if(HeadPtr==p1)HeadPtr=p;
elsep2->Next=p;
}
else
{
p1->Next=p;
p->Next=NULL;
}
}
if(Tag==5)//按电子邮箱地址排列,同按姓名排列的方法
{
p1=HeadPtr;
while(strcmp(p->E_Mail,p1->E_Mail)>0&&p1->Next!
=NULL)
{
p2=p1;p1=p1->Next;
}
if(strcmp(p->E_Mail,p1->E_Mail)<=0)
{
p->Next=p1;
if(HeadPtr==p1)HeadPtr=p;
elsep2->Next=p;
}
else
{
p1->Next=p;
p->Next=NULL;
}
}
}
}
Node*LookUp(char*name)//按姓名查找结点,返回该结点指针
{
Node*p=HeadPtr;//定义一个Node型指针,初始值为HeadPtr
while(p!
=NULL)//当链表不为空时
{
if(strcmp(p->Name,name)==0)//循环比较数据中的Name成员
returnp;//如果存在,返回结点
p=p->Next;//将p的下一组数据赋给p
}
returnNULL;//如果不存在,返回值为空
}
voidDelete(char*name)//删除指定姓名的结点
{
Node*p1,*p2;
if(HeadPtr==NULL)//当链表为空时
{
cout<<"通讯录为空,无结点可删!
\n";
}
p1=HeadPtr;
while(strcmp(p1->Name,name)!
=0&&p1->Next!
=NULL)//查找所在位置
{
p2=p1;//将p1的值赋给p2
p1=p1->Next;//p1指向下一条记录
}
if(strcmp(p1->Name,name)==0)//若找到该姓名对应的数据,删除该数据
{
if(p1==HeadPtr)//如果p1在第一条,则将首指针指向下一条记录,将p1空出
HeadPtr=p1->Next;
else//否则将p1的上一个记录的成员Next直接指向p1的下一条记录
p2->Next=p1->Next;
deletep1;//释放p1的空间
cout<<"删除了一个数据!
\n";
}
else//若找不到,则输出"通讯录上没找到该条记录!
"
cout<\n";
}
voidDeleteAll()//删除链表中全部结点
{
Node*p;//定义一个Node型指针变量p
while(HeadPtr)//当首指针不为0时,进行循环
{
p=HeadPtr;//将head赋给p
HeadPtr=HeadPtr->Next;//将head的下一条数据赋给head
deletep;//释放p的空间
}
}
voidSort(inttag)//按Tag指定的关键字重新排序
{Tag=tag;//将tag的值赋给Tag
Node*p1,*p;//定义两个Node型指针变量p1,p
p=HeadPtr;//将首指针的值赋给p
HeadPtr=NULL;//将首指针置为空
while(p)//当首指针不为空时,进行循环
{p1=p;//将p的值赋给p1
p=p->Next;//p指向下一条记录
p1->Next=NULL;//p1的成员Next指向空
AddSort(p1);//调用公有成员函数,将p1重新按关键字排序
}
}
voidShowAll()//显示全部结点,每10个显示一屏
{
Node*p=HeadPtr;//定义一个Node型指针p,初始化为首指针的值
inti=1;//定义一个整型变量,计算现实的数据个数
system("cls");//清屏
while(p)//当p不为空时,进行循环
{cout<
p->Show();//循环输出数据p
p=p->Next;//将下一条记录的值赋给p
if(!
(i++%10))//当i是10的倍数时,暂停程序并清屏
{system("pause");
system("cls");
}
}
}
voidSetTag(intt)//重置Tag的值
{
Tag=t;
}
intGetTag()//获取Tag的值
{
return(Tag);//返回Tag的值
}
intCount()//计算链表中有多少个结点
{
Node*p;//定义一个Node型指针p
intt=0;//定义一个整型变量t,用来计算链表中结点的个数
p=HeadPtr;//将首指针的值赋给p
while(p->Next!
=NULL)//当链表不为空时
{
t=t+1;//每当数据不为空时,t就加1
p=p->Next;//p指向下一条记录
}t=t+1;//因为当p->Next=NULL是就退出程序,所以末尾t要加1
returnt;//返回t
}
Node*GetHeadPtr()//获取链表首指针
{
returnHeadPtr;//返回首指针
}
~AddressList()//析构函数,释放链表空间
{Node*p;//定义一个Node型的指针变量
while(HeadPtr!
=NULL)//链表不为空,进行循环
{
p=HeadPtr;//将第一条数据赋给p
HeadPtr=HeadPtr->Next;//将下一条数据赋给首指针
deletep;//释放p的空间
}
}
#defineLensizeof(classNode)//定义常量Len为Node类数据的长度
voidCreateList(char*filename)//从二进制文件中读入数据,构造链表
{
Node*p[100];//定义一个有100个数据空间的指针数组
inti=0,j=0;//定义两个整型变量,来记录第几条数据和读取数据的个数
fstreamfile(filename,ios:
:
in|ios:
:
binary);//定义一个文件流对象
if(!
filename)//当文件为空时,无法打开
{
cout<<"不能打开文件:
"<exit
(1);
}
file.read((char*)&Tag,sizeof(int));//从文件中读取Tag
file.read((char*)&j,sizeof(int));//从文件中读取数据的个数
p[0]=newNode;//申请一个p的动态存储空间
while(file.read((char*)p[i],Len)!
=0)//从文件中读取Len长度的数据不为0
{
p[i+1]=newNode;
AddSort(p[i+1]);//调用公有成员函数AddSort(),将文件中数据读取后,重新排序
}
file.close;//关闭文件
}
voidWriteToFile(char*filename)//将链表中的数据写入指定的二进制文件
{
Node*p;//定义一个Node型的指针变量
p=HeadPtr;//将首指针的值赋给p
fstreamfile(filename,ios:
:
in|ios:
:
binary);//定义一个文件流对象
if(!
filename)//当文件为空时,无法打开文件
{
cout<<"不能打开文件:
"<exit
(1);
}
while(p!
=0)//当数据不为0时,将数据写入文件中
{
file.write((char*)p,Len);//将p写入文件中
p=p->Next;
}
file.close;//关闭文件
}
voidouttxt(char*file)//将数据从文件file导出
{Node*p=HeadPtr;//定义一个Node型指针变量,初始值为HeadPtr
intn=1;//定义一个整型变量,作为数据的序号
fstreamout(file,ios:
:
out);//以写入的方式打开正文文件
if(!
out)//定义一个输出文件流对象
{cout<<"不能打开该文件:
"<exit
(1);
}
while(p)
{out<p=p->Next;
}
out.close();
}
};
intmenu_select()//菜单实现
{
char*a[]={"1.AddRecord","2.DeleteRecord","3.DisplayAllRecord","4.Query",
"5.ModifyRecord","6.AddfromaTextFile","7.WritetoaTextFile",
"8.Sort","9.DeletAll","0.Quit",NULL};//将菜单的选项赋给数组
inti,choice;//定义两个整型变量,一个用于输出选项,一个用于选择,并调用相关函数
do{
system("cls");
cout<<"\n\n========AddressBookManagingSyetem========\n\n";
for(i=0;a[i];i++)//循环输出选项
cout<cout<<"\n================================================\n";
cout<<"Input1-9,0:
";
cin>>choice;//输入choice
}while(choice<0||choice>9);//在0到9的菜单中做出选择
return(choice);//返回所选的值
}
voidadd(AddressList&addrlist)//增加记录
{
Node*p[50];//一次需要输入的数据
charn[100],m[100],o[100];//姓名,手机,电子邮箱
intq,r;//办公和家庭电话
inti,j;
cout<<"请输入本次需要输入的数据的个数(0~100):
";
cin>>j;
cout<<"请依次输入姓名、办公电话、家庭电话、手机号码和电子邮箱地址:
";
for(i=0;i{
cin>>n>>q>>r>>m>>o;//输入数据的各个成员
p[i]=newNode;//申请动态存储空间
p[i]->SetName(n);//调用公用成员函数,修改姓名
p[i]->SetOfficePhone(q);//调用公用成员函数,修改办公电话
p[i]->SetHomePhone(r);//调用公用成员函数,修改家庭电话
p[i]->SetMobilePhone(m);//调用公用成员函数,修改手机
p[i]->SetE_Mail(o);//调用公用成员函数,修改电子邮箱
addrlist.AddSort(p[i]);//调用公有函数AddSort()
}
}
voiddel(AddressList&addrlist)//删除记录
{
Node*p;
p=addrlist.GetHeadPtr();//调用GetHeadPtr()函数,获取首指针
if(p==0)//当链表中没有数据时
cout<<"无数据!
"<else
{
char*n;
n=newchar;
ints;
cout<<"请输入要删除的记录的个数"<cin>>s;//输入需要删除的数据个数
for(inti=0;i
{
cout<<"请输入要删除的姓名"<cin>>n;//输入要删除的数据的姓名
addrlist.Delete(n);//调用公有函数删除记录
}
}//删除多条记录
}
voidshowall(AddressList&addrlist)//显示所有记录
{Node*p;
p=addrlist.GetHeadPtr();//调用GetHeadPtr()函数,获取首指针
if(p==0)
cout<<"无数据!
"<else
addrlist.ShowAll();//调用公有成员函数,