数据结构单链表通讯录.docx
《数据结构单链表通讯录.docx》由会员分享,可在线阅读,更多相关《数据结构单链表通讯录.docx(27页珍藏版)》请在冰豆网上搜索。
![数据结构单链表通讯录.docx](https://file1.bdocx.com/fileroot1/2023-6/25/e84deee5-ebe9-4bdb-ac25-20f8409ee374/e84deee5-ebe9-4bdb-ac25-20f8409ee3741.gif)
数据结构单链表通讯录
实验报告
实验名称单链表通讯录
一、实验目的
1.熟练掌握线性表的类型定义方法、存储方法及其基本运算(元素的插入、删除等)的实现方法,培养综合运用所学知识,根据具体问题进行数据结构设计和算法设计的能力。
二、实验内容
1.●用带头结点的单链表作存储结构,实现通讯录单链表的建立、查询、修改、排序、合并、统计、结点的查找、移动以及通讯录链表的输出功能。
三、实验要求
●设计要求:
为了实现通讯录管理的操作功能,首先设计一个含有多个菜单项的主控菜单程序,然后再为这些菜单项配上相应的功能。
主控菜单设计要求:
♦菜单内容
程序运行后,给出9个菜单项的内容和输入提示:
1.创建通讯录链表;
2.将姓名为Name的好友的手机号改为MTel;
3.输出通讯录;
4.插入姓名为Name、手机号为MTel的好友信息,将链表中姓名≤Name的结点放到该结点的前面,将姓名>Name的结点放到该结点后面
5.将通讯录按照好友姓名进行非递减排序;
6.将两个按姓名非递减排序的通讯录合并为一个,姓名相同且手机号相同的好友记录在结果中只保留一个;
7.统计籍贯是“大连”的好友人数;
8.将通讯录中倒数第k个结点之后的所有结点移到头结点后面(保持结点间的先后顺序);
9.将通讯录的正中间位置结点之后的全部结点倒置;
0.退出管理系统
请选择0—9:
♦菜单设计要求:
使用数字0—9来选择菜单项,其它输入则不起作用。
四、实验概要设计
1)功能框图
五.使用说明
1.运行环境:
VC6.0
2.首先选择主控菜单中的操作1,即建表,然后进行其它操作.
六.实验截图
(见下页)
七实验体会
附源程序代码:
#include
#include
#include
#defineNewsp(TxlList*)malloc(sizeof(structTxlList))
typedefstructTxlList
{
charName[16];//姓名
charMTel[11];//手机号
charTel[9];//固定电话
charEMail[16];//邮箱地址
charBornAddr[20];//籍贯(值域:
"北京"、"上海"、"大连"等等,只写城市名称)
charBroadN[50];//博客名
structTxlList*next;//指针域
}TxlList,*TxlLink;
voidLbuild1(TxlLink&T){//创建文件
FILE*fp;
TxlLinkq;
q=Newsp;
q=T;
intNUM;
charfilename[20];
printf("\n*请输入要创建的通讯录名:
\n");
gets(filename);
if((fp=fopen(filename,"wb"))==NULL){/*以写方式在当前目录打开(新建)文件*/
printf("can'topenfile!
!
!
\n");
exit(0);//如果文件无法打开,关闭已经打开的其它文件,结束程序。
}
printf("*请输入要储存的人数:
");
scanf("%d",&NUM);
getchar();
for(inta=0;aTxlLinkp;
p=Newsp;
printf("\n*请输入第%d个人的数据,按回车键结束,数据若为空请输“无”",a+1);
printf("\n*姓名:
");
gets(p->Name);
printf("*手机号:
");
gets(p->MTel);
printf("*固定电话:
");
gets(p->Tel);
printf("*邮箱地址:
");
gets(p->EMail);
printf("*籍贯:
");
gets(p->BornAddr);
printf("*博客名:
");
gets(p->BroadN);
p->next=NULL;
q->next=p;
q=q->next;
if(fprintf(fp,"%s%s%s%s%s%s\n",p->Name,p->MTel,p->Tel,p->EMail,p->BornAddr,p->BroadN)==1)//向文件中一次写一个结构体量值
{
printf("filewriteerror\n");
break;
}
}
fclose(fp);
}
voidLbuild2(TxlLink&T){//读取文件
FILE*fp;
TxlLinkq;
q=Newsp;
q=T;
charfilename[20];
printf("\n*请输入要读取的通讯表名:
\n");
gets(filename);
if((fp=fopen(filename,"rb"))==NULL){
printf("can'topenfile!
!
!
\n");
exit(0);//如果文件无法打开,关闭已经打开的其它文件,结束程序。
}
while(!
feof(fp)){
TxlLinkp;
p=Newsp;
fscanf(fp,"%s%s%s%s%s%s",p->Name,p->MTel,p->Tel,p->EMail,p->BornAddr,p->BroadN);
q->next=p;
p->next=NULL;
q=q->next;
}
fclose(fp);
}
voidBuild(TxlLink&T){//选择建立方式的函数
intChoice;
printf("*******************************************************************");
printf("\n*请输入想要实现的功能编号:
\n");
printf("*1.新建通讯录;\n*2.输出已有有通讯录;\n*其它-退出。
\n*选择为:
");
scanf("%d",&Choice);
printf("*******************************************************************");
getchar();
switch(Choice){
case1:
{
Lbuild1(T);
break;
}
case2:
{
Lbuild2(T);
break;
}
default:
{
printf("无通讯录\n\n");
break;
}
}
}
voidUpdate(TxlLink&T,char*Name,char*MTel){//将姓名为Name的好友的手机号改为MTel;
TxlLinkp;
p=T->next;
while(p){
if(strcmp(p->Name,Name)==0){
strcpy(p->MTel,MTel);
}
p=p->next;
}
}
voidBuildnew(TxlLink&T){//创建一个空资料单元
chara[]="无";
strcpy(T->Name,a);
strcpy(T->MTel,a);
strcpy(T->EMail,a);
strcpy(T->BornAddr,a);
strcpy(T->BroadN,a);
strcpy(T->Tel,a);
T->next=NULL;
}
voidOutPut(TxlLinkT){//输出通讯表数据
TxlLinkp;
p=Newsp;
p=T->next;
printf("*******************************************************************");
printf("\n*通讯录信息:
\n姓名,手机号,固定电话,邮箱地址,籍贯,博客名分别为:
\n");
while(p){
printf("%s%s%s%s%s%s\n",p->Name,p->MTel,p->Tel,p->EMail,p->BornAddr,p->BroadN);
p=p->next;
}
}
voidSort(TxlLink&T){//将该通讯录按照好友姓名进行非递减排序
TxlLinkp,q,r;
p=T;
q=p->next;
intSUM=0;
while(q){//记录通讯表数据个数
SUM++;
q=q->next;
}
q=p->next;
for(inti=0;ifor(intj=0;jr=q->next;
if(r){
if(strcmp(q->Name,r->Name)>0){
p->next=r;
q->next=r->next;
r->next=q;
}
p=p->next;
q=p->next;
}
}
p=T;
q=p->next;
r=q->next;
}
}
voidMerge(TxlLink&T1,TxlLink&T2){//将两个按姓名非递减排序的通讯录合并为一个,姓名相同且手机号相同的好友记录在结果中只保留一个
Sort(T1);
Sort(T2);
TxlLinkp,q,r,t,head;
p=T1->next;
q=T2->next;
head=T1;
while(p||q){
r=p;
t=q;
if(strcmp(p->Name,q->Name)>0)
{
q=q->next;
head->next=t;
head=head->next;
head->next=NULL;
printf("w");
}
elseif(strcmp(p->Name,q->Name)<0)
{
p=p->next;
head->next=r;
head=head->next;
head->next=NULL;
}
else{
if(strcmp(p->MTel,q->MTel)>0){
q=q->next;
head->next=t;
head=head->next;
head->next=NULL;
}
elseif(strcmp(p->MTel,q->MTel)<0){
p=p->next;
head->next=r;
head=head->next;
head->next=NULL;
}
else{
p=p->next;
free(r);
printf("x");
}
}
if(!
p){
while(q){
head->next=q;
q=q->next;
head=head->next;
head->next=NULL;
}
}
if(!
q){
while(p){
head->next=p;
p=p->next;
head=head->next;
head->next=NULL;
}
}
}
T2=T1;
}
voidInsert(TxlLink&T,char*Name,char*MTel){//插入姓名为Name、手机号为MTel的好友信息,将链表中姓名≤Name的结点放到该结点的前面,将姓名>Name的结点放到该结点后面;
Sort(T);
TxlLinkp,q,r;
intn=1;
r=Newsp;
Buildnew(r);
strcpy(r->Name,Name);
strcpy(r->MTel,MTel);
p=T->next;
q=p->next;
while(q){
if(strcmp(p->Name,r->Name)>=0)
{
T->next=r;
r->next=p;
n=0;
break;
}
if(strcmp(p->Name,r->Name)<=0){
if(strcmp(q->Name,r->Name)>=0)
{
p->next=r;
r->next=q;
n=0;
break;
}
}
p=p->next;
q=q->next;
}
if(n==1){
p->next=r;
}
}
intCount(TxlLinkT){//统计籍贯是某地的好友人数;
intx=0;
charBornAddr[20];
TxlLinkp;
p=T->next;
printf("*请输入要查询的地址:
");
gets(BornAddr);
while(p){
if(strcmp(p->BornAddr,BornAddr)==0)
x++;
p=p->next;
}
returnx;
}
intNumber1(TxlLinkp,TxlLink&r,TxlLink&t,intk){//运用递归方法找到倒数第k个结点的地址
intx=0;
TxlLinkq;
if(p){
q=p;
p=p->next;
x=Number1(p,r,t,k)+1;
}
if(k==x)
r=q;
if((k+1)==x)
t=q;
returnx;
}
intNumber2(TxlLinkp,TxlLink&r,TxlLink&t,int&k){//运用递归方法找到倒数第k个的地址
intx=0;
TxlLinkq;
if(p){
q=p;
k++;
p=p->next;
x=Number2(p,r,t,k)+1;
}
if((k/2)==x)
r=q;
if((k/2+1)==x)
t=q;
returnx;
}
voidMoveK(TxlLink&T,intk){//将通讯录中倒数第k个结点之后的所有结点移到头结点后面
intx;
TxlLinkp,q,r,t;
p=T->next;
x=Number1(p,r,t,k);
T->next=r;
t->next=NULL;
while(r){
q=r;
r=r->next;
}
q->next=p;
}
voidReverseN(TxlLinkT){//将通讯录的正中间位置结点之后的全部结点倒置
intk=0;
TxlLinkp,q,r,t;
p=T->next;
Number2(p,r,t,k);
T->next=r;
t->next=NULL;
while(r){
q=r;
r=r->next;
}
q->next=p;
}
intmain(void){
TxlLinkP;
intx=1;
P=Newsp;
Build(P);
intChoice;
while(x){
printf("\n*请输入想要实现的功能编号:
\n");
printf("*1.排序;\n*2.插入信息;\n*3.更改手机;\n*4.合并;\n*5.统计籍贯人数;\n*6.移节点;\n*7.倒置链表;\n*其它-退出。
\n*选择为:
");
scanf("%d",&Choice);
getchar();
switch(Choice)
{
case1:
{
printf("*******************************************************************");
printf("\n************************排序前的通讯表*************************\n");
OutPut(P);
Sort(P);
printf("\n************************排序后的通讯表*************************\n");
OutPut(P);
break;
}
case2:
{
printf("\n*************************插入前的通讯录*************************\n");
OutPut(P);
charname[16],mtel[11];
printf("\n*请输入要插入的好友姓名:
");
gets(name);
printf("\n*请输入要插入的好友号码:
");
gets(mtel);
Insert(P,name,mtel);
printf("\n*************************插入后的通讯录*************************\n");
OutPut(P);
printf("********************************************************************");
break;
}
case3:
{
printf("\n*************************改写前的通讯录*************************\n");
OutPut(P);
charname[16],mtel[11];
printf("\n*请输入要改写的好友姓名:
");
gets(name);
printf("\n*请输入要改写的好友号码:
");
gets(mtel);
Update(P,name,mtel);
printf("\n*************************改写后的通讯录*************************\n");
OutPut(P);
printf("********************************************************************");
break;
}
case4:
{
TxlLinkQ;
Q=Newsp;
printf("********************************************************************");
printf("\n*建立另一个通讯录\n");
Build(Q);
printf("\n*第一个通讯录\n");
OutPut(P);
printf("\n*第二个通讯录\n");
OutPut(Q);
Merge(P,Q);
printf("\n**********************合并并排序后的通讯录***********************\n");
OutPut(P);
printf("********************************************************************");
break;
}
case5:
{
intN;
printf("\n***************************输出通讯录***************************\n");
OutPut(P);
N=Count(P);
printf("\n*统计结果为:
\n*共%d个人\n",N);
printf("********************************************************************");
break;
}
case6:
{
intn;
printf("\n*请输入移动节点数:
\nn=");
scanf("%d",&n);
printf("\n*移动前的通讯录:
\n");
OutPut(P);
MoveK(P,n);
printf("\n*移动后的通讯录:
\n");
OutPut(P);
break;
}
case7:
{
printf("\n*************************倒置前的通讯录*************************\n");
OutPut(P);
ReverseN(P);
printf("\n*************************倒置后的通讯录*************************\n");
OutPut(P);
printf("********************************************************************");
break;
}
default:
{
x=0;
break;
}
}
}
return0;
}