当前位置:文档之家› 数据结构单链表通讯录

数据结构单链表通讯录

实验报告实验名称单链表通讯录一、实验目的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.02.首先选择主控菜单中的操作1,即建表,然后进行其它操作.六.实验截图(见下页)七实验体会附源程序代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#define Newsp (TxlList *)malloc(sizeof(struct TxlList))typedef struct TxlList{char Name[16]; //姓名char MTel[11]; //手机号char Tel[9]; //固定电话char EMail[16]; //邮箱地址char BornAddr[20];//籍贯(值域:"北京"、"上海"、"大连"等等,只写城市名称)char BroadN[50]; //博客名struct TxlList *next; //指针域}TxlList, *TxlLink;void Lbuild1(TxlLink &T){//创建文件FILE *fp;TxlLink q;q=Newsp;q=T;int NUM;char filename[20];printf("\n*请输入要创建的通讯录名:\n");gets(filename);if ((fp=fopen(filename, "wb"))==NULL) { /*以写方式在当前目录打开(新建)文件*/printf("can't open file!!!\n");exit(0); //如果文件无法打开,关闭已经打开的其它文件,结束程序。

}printf("*请输入要储存的人数:");scanf("%d",&NUM);getchar();for(int a=0;a<NUM;a++){TxlLink p;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->Broad N)==1)//向文件中一次写一个结构体量值{printf("file write error\n");break;}}fclose(fp);}void Lbuild2(TxlLink &T){//读取文件FILE *fp;TxlLink q;q=Newsp;q=T;char filename[20];printf("\n*请输入要读取的通讯表名:\n");gets(filename);if((fp=fopen(filename,"rb"))==NULL){printf("can't open file!!!\n");exit(0); //如果文件无法打开,关闭已经打开的其它文件,结束程序。

}while(!feof(fp)){TxlLink p;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);}void Build(TxlLink &T){//选择建立方式的函数int Choice;printf("*******************************************************************") ;printf("\n*请输入想要实现的功能编号:\n");printf("*1.新建通讯录;\n*2.输出已有有通讯录;\n*其它-退出。

\n*选择为:");scanf("%d",&Choice);printf("*******************************************************************") ;getchar();switch(Choice){case 1:{Lbuild1(T);break;}case 2:{Lbuild2(T);break;}default:{printf("无通讯录\n\n");break;}}}void Update(TxlLink &T, char *Name, char *MTel){//将姓名为Name的好友的手机号改为MTel;TxlLink p;p=T->next;while(p){if(strcmp(p->Name,Name)==0){strcpy(p->MTel,MTel);}p=p->next;}}void Buildnew(TxlLink &T){//创建一个空资料单元char a[]="无";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;}void OutPut(TxlLink T){//输出通讯表数据TxlLink p;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->BornAd dr,p->BroadN);p=p->next;}}void Sort(TxlLink &T){ //将该通讯录按照好友姓名进行非递减排序TxlLink p,q,r;p=T;q=p->next;int SUM=0;while(q){//记录通讯表数据个数SUM++;q=q->next;}q=p->next;for(int i=0;i<SUM;i++){for(int j=0;j<SUM-i;j++){r=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;}}void Merge(TxlLink &T1, TxlLink &T2){ //将两个按姓名非递减排序的通讯录合并为一个,姓名相同且手机号相同的好友记录在结果中只保留一个Sort(T1);Sort(T2);TxlLink p,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 ");}else if(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;}else if(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;}void Insert(TxlLink &T, char *Name, char *MTel){ //插入姓名为Name、手机号为MTel的好友信息,将链表中姓名≤Name的结点放到该结点的前面,将姓名>Name的结点放到该结点后面;Sort(T);TxlLink p,q,r;int n=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;}}int Count(TxlLink T){//统计籍贯是某地的好友人数;int x=0;char BornAddr[20];TxlLink p;p=T->next;printf("*请输入要查询的地址:");gets(BornAddr);while(p){if(strcmp(p->BornAddr,BornAddr)==0)x++;p=p->next;}return x;}int Number1(TxlLink p,TxlLink &r,TxlLink &t,int k){//运用递归方法找到倒数第k个结点的地址int x=0;TxlLink q;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;return x;}int Number2(TxlLink p,TxlLink &r,TxlLink &t,int &k){//运用递归方法找到倒数第k个的地址int x=0;TxlLink q;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;return x;}void MoveK(TxlLink &T, int k){//将通讯录中倒数第k个结点之后的所有结点移到头结点后面int x;TxlLink p,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;}void ReverseN(TxlLink T){//将通讯录的正中间位置结点之后的全部结点倒置int k=0;TxlLink p,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;}int main(void){TxlLink P;int x=1;P=Newsp;Build(P);int Choice;while(x){printf("\n*请输入想要实现的功能编号:\n");printf("*1.排序;\n*2.插入信息;\n*3.更改手机;\n*4.合并;\n*5.统计籍贯人数;\n*6.移节点;\n*7.倒置链表;\n*其它-退出。

相关主题