东华理工大学数据结构(通讯录制作)一.设计内容(通讯录)本系统应完成一下几方面的功能:1)输入信息——enter();2)显示信息———display();3)查找以姓名作为关键字———search();4)删除信息———delete();5)存盘———save();6)装入———load();设计要求:1)每条信息至包含:姓名(NAME)街道(STREET)城市(CITY)邮编(EIP)国家(STATE)几项2)作为一个完整的系统,应具有友好的界面和较强的容错能力二.设计思路通过visualc++6.0(用的是C语言)编写一个dos界面的控制台程序,该程序通过链表的操作,文件存储来实现通讯录的基本功能structaddress{/*定义结构*/charname[10];/*姓名*/charstreet[50];/*街道*/charcity[10];/*城市*/东华理工大学数据结构(通讯录制作)charstate[15];/*国家*/chareip[7];/*邮编*/structaddress*next;/*后继指针*/structaddress*prior;/*前驱指针*/}链表的插入,删除来实现通讯录里的内容的插入删除当操作完成通过文件件来存储链表的信息,下次打开程序时,读取文件里的内容到内存中,放在链表,然后又可以对链表进行操作;在这里面,文件内容不可以在外部更改,只能通过读取到内存链表中,通过程序进行更改,然后再写入到文件,写入过程会覆盖上次的内容。structaddress*start;/*首结点*/structaddress*last;/*尾结点*/structaddress*find(char*);/*声明查找函数*/voidenter();/*函数声明*/voidsearch();/*查找,查找过程中调用find函数*/voidsave();/*存盘,将链表信息保存到文件中*/插入查找删除内存链表文件存储导入东华理工大学数据结构(通讯录制作)voidload();/*导入,将文件内容导入到内存链表中*/voidlist();/*显示当前链表中信息*/voidddelete(structaddress**,structaddress**);voidinsert(structaddress*i,structaddress**start,structaddress**last);voidinputs(char*,char*,int);voiddisplay(structaddress*);intmenu_select(void);三.详细设计1.主界面设计通过switch语句调用各种函数,实现各种操作。然后把switch嵌套到无限的for循环(for(;;))中,使完成每一步操作都回到到选择操作的主界面东华理工大学数据结构(通讯录制作)voidmain()mainmenu_selectenterddeletelistsearchsavesaveloadexitinputsinsertfinddisplay文件函数之间的相互调用东华理工大学数据结构(通讯录制作){start=last=NULL;for(;;)/*无限循环*/{switch(menu_select())/*调用主界面的选择函数,带回返回值*/{case1:enter();continue;case2:ddelete(&start,&last);continue;case3:list();continue;case4:search();continue;case5:save();continue;case6:load();continue;case7:exit(0);}}}intmenu_select(void)/*主目录*/{chars[80];intc;东华理工大学数据结构(通讯录制作)printf(………………^欢迎使用DOS通讯录系统^………………\n);printf(************请在做其它操作前先导入*************\n);printf(***********************************************\n);printf(*****************1.输入信息******************\n);printf(*****************2.删除信息******************\n);printf(*****************3.显示信息******************\n);printf(*****************4.查找******************\n);printf(*****************5.存盘******************\n);printf(*****************6.导入******************\n);printf(*****************7.退出******************\n);printf(***********************************************\n);do{printf(\nPleaseenteryourchoice:\n);gets(s);c=atoi(s);/*将获取的字符串转换成整型*/}while(c0||c7);returnc;/*返回输入值*/}2.输入信息函数东华理工大学数据结构(通讯录制作)输入函数:structaddress*info;/*定义当前结点*/for(;;){info=(structaddress*)malloc(sizeof(structaddress));/*为当前结点分配空间*/if(!info){printf(\nOutofmemory);exit(0);/*如果分配空间失败,退出程序*/}printf(输入空姓名结束:\n);inputs(请输入姓名:,info-name,10);东华理工大学数据结构(通讯录制作)if(!info-name[0])break;/*如果输入姓名为空,结束循环*/inputs(请输入街道:,info-street,50);inputs(请输入城市:,info-city,15);inputs(请输入国家:,info-state,15);inputs(请输入邮编:,info-eip,7);insert(info,&start,&last);/*调用结点插入函数*/}输入函数调用到另外两个函数,inputs和insert其中inputs中还用到fgets(str,n,fp),把键盘的输入信息传到字符串中charp[255];do{printf(prompt);fgets(p,254,stdin);/*stdin,标准输入缓存,获取键盘输入信息*/if(strlen(p)count)printf(\nTooLong\n);}while(strlen(p)count);p[strlen(p)-1]=0;strcpy(s,p);insert是关键函数,每当输入完一条信息都会调用到insert函数,将信息插入到链表中if(*last==NULL)/*如果尾结点为空,意味着当前链表为空*/{/*则将该结点赋给头尾结点*/东华理工大学数据结构(通讯录制作)i-next=NULL;i-prior=NULL;*last=i;*start=i;return;}else/*如果链表不为空,则将信息插入到链表尾,作为尾结点*/{(*last)-next=i;i-prior=*last;i-next=NULL;*last=(*last)-next;}NULLNULL插入信息会显示在链表最后*last(*last)-nextii-next东华理工大学数据结构(通讯录制作)3.删除·查找·显示函数删除函数调用find函数,通过姓名,查找到该节点,然后删除该节点信息,这其中涉及到头尾节点,及其变化;先判断是否为头结点,如果为头结点,则把原头结点的后继作为新的头结点如果不为头结点,则该节点的前驱的next指向该节点的后继如果该节点为尾结点,则让该节点的前驱作为新的尾结点structaddress*info;chars[80];inputs(请输入姓名:,s,10);info=find(s);if(info){printf(Deleting......\n);if(*start==info){*start=info-next;if(*start)(*start)-prior=NULL;东华理工大学数据结构(通讯录制作)else*last=NULL;}else{{info-prior-next=info-next;if(info!=*last)info-next-prior=info-prior;else*last=info-prior;}free(info);printf(-Ok,删除成功!\n);}与删除相比,查找就简单的多,只需要调用find的函数,找到该节点记录并显示出来就行了,在search本身里面只要调整下输出的界面就行了structaddress*find(char*name)/*查找函数,形参为欲查找结点的name域*/{structaddress*info;info=start;while(info){if(!strcmp(name,info-name))returninfo;info=info-next;东华理工大学数据结构(通讯录制作)}printf(Namenotfound.\n);returnNULL;}输出函数更简单,直接输出链表即可if(info==NULL)printf(当前记录为空!);elseprintf(姓名\t街道\t\t城市\t国家\t邮编\t\n);while(info){东华理工大学数据结构(通讯录制作)display(info);/*display为输出节点函数,一些列print组成*/if(info-next==NULL){break;}info=info-next;};4.存储与导入存储存储时通过fopen打开文件(没有该文件时则创建)fp=fopen(record.txt,wb);/*生成文件*/if(!fp){printf(Cannotopenfile.\n);return}然后通过fwrite将链表信息写入文件while(info)/*把链表写入文件*/{fwrite(info,sizeof(structaddress),1,fp);东华理工大学数据结构(通讯录制作)info=info-next;}fwrite每次从info读取一个sizeof(structaddress)长度的数据,写入fp文件中。写入完毕后即关闭文件fclose(fp);导入导入时先建立链表,为节点分配内存空间然后打开文件,将文件的内容写入内存链表中registerintt,size;structaddress*info,*temp=0;char*p;FILE*fp;/*打开文件*/if((fp=fopen(record.txt,r))==NULL){printf(Cannotopenfile!\n);return;}printf(\n\nLoading...\n);/*调用文件*/size=sizeof(structaddress);/*为结点分配内存*/start=(structaddress*)malloc(size);if(!start)/*如果读取失败,返回*/{printf(Outofmemory!\n);exit(0);}东华理工大学数据结构(通讯录制作)info=start;p=(char*)info;while((*p++=getc(fp))!=EOF){for(t=0;tsize-1;++t)*p++=getc(fp);info-next=(structaddress