设计散列表实现通讯录查找系统
基于散列表电话管理系统

1 实验目的:熟练并掌握查找的过程、方法和应用2 实验内容:问题描述:设计一个电话号码查找程序,为来查询人提供电话号码的查询服务。
基本要求:(1)以你所在的班级为查询范围,假设人名为中国人姓名的汉语拼音形式。
人数不能少于10人。
(2)完成根据人名来查找相应的电话号码。
测试数据:由同学们根据实际情况指定3 实验要求:任选一种高级程序语言编写源程序,并调试通过,测试正确。
源代码:#include<iostream>#include<cstring>using namespace std;const int MaxSize = 10000;const int MOD = 9973;struct User{ // 每个用户的数据结构。
char name[20];char tel_num[20];};struct Node{ // hash表内每个结点的数据结构。
User user;Node *next;};int user_num;Node *hashtable[MaxSize]; // hash表的表头指针数组。
int ELFhash(char *key){ // hash函数:著名的ELFhash算法。
unsigned long h = 0;while(*key){h = (h<<4) + *key++;unsigned long g = h&0Xf0000000L;if(g) h ^= g>>24;h &= ~g;}return h % MOD;}void add_record(char *name, char *tel_num){ // 添加一个记录。
int key = ELFhash(name);Node *node = new Node;strcpy(node->, name);strcpy(node->user.tel_num, tel_num);node->next = hashtable[key];hashtable[key] = node;}bool query(char *name, char *tel_num){ // 查询一个记录。
散列表实现电话号码查找系统

printf(" haha !!%s\n",person[j].name);
printf("input person %d tel:",i+1);
scanf("%d",&person[j].tel);
scanf("%d",&choice);
}
else{
switch(choice){
case 1:INPUT();break;
case 2:DISPLAY();break;
case 3:SORT();break;
case 0:EXIT(0);break;
}
else{ printf("apple!\n");
for(j=y+1;j<=y+5;j++){
if(person[j].name[0]=='\0'){
strcpy(person[j].name,a);//把字符数组a复制给散列表;
y=x%29;
if(person[y].name!='\0'&&person[y].tel!='\0'&&person[y].addr!='\0'){ //判断是否有信息;
if(strcmp(person[y].name,a)==0){
{
printf(" 1---input telephoto infoumantion.\n");
printf(" 2---display all students informantion.n\n");
通讯录查询系统的设计与实现

通讯录查询系统的设计与实现目录一、设计要求(包括内容描述)------------------------------------------------3二、设计作用与目的-------------------------------------------------------------- 3三、所用软件------------------------------------------------------------------------3四、系统设计----------------------------------------------------------------------- 34.1系统总体设计(附系统总体结构框图)------------------------------- 3 4.2 各子模块设计(附程序流程图)--------------------------------------- 4 4.3相关函数分析--------------------------------------------------------- -------8 4.4 源程序设计------------------------------------------------------------------ 9五、实验调试结果(附运行效果图)----------------------------------------- 13六、设计中的问题及解决方法-------------------------------------------------- 17七、设计心得----------------------------------------------------------------------- 18八、参考文献----------------------------------------------------------------------- 18一、设计要求设计一通讯录程序,包括通讯人的:姓名、性别、手机号码、工作单位、邮箱、等信息。
E41514068_周永涛_通讯录查询系统的设计与实现

if(H->elem[pp]!=NULL && bj(tel,H->elem[pp]->tel) == 1)
{
printf("\n\t\t\t 查找成功\n\n");
printf("\t 姓 名 :
%s\n\n\t 电 话 号 码 :
址: %s\n",H->elem[pp]->name,H->elem[pp]->tel,H->elem[pp]->add);
}
else
printf("\n\t 此人不存在,失败!\n");
printf("\n\t 按 Esc 键,返回主菜单");
FRI tel;
int p,pp;
printf("\n\t 输入要查找的号码: ");
gets(tel);
p = HASH(tel);
pp = p;
while(H->elem[pp]!=NULL && bj(tel,H->elem[pp]->tel) == 0)
pp = collision(p,c);
void Menu() {
system("cls"); int n; printf("\n\n\n\n\n\n\n\n\n\t\t\t 输入 1(汉语)、 2(英语) 选择语言: "); scanf("%d",&n); system("cls"); if(n == 1) {
Pr1(); Pr2(); } }
void Pr6() {
printf("\n\t\t* * * * * * * * * * * * * * * * * * * * * * * *\n"); printf("\t\t\t\t 删除某人的信息\n\n"); printf("\t\t* * * * * * * * * * * * * * * * * * * * * * * *\n\n"); }
基于散列表的电话号码查询系统 完整版

#include<iostream> //cout,cin语句的头文件#include<stdlib.h> //清屏函数头文件:使用csl时调用system#include<string> //字符串头文件#include<stdio.h>#include<fstream>#define MAXSIZE 100 //电话薄记录的数量#define MAX_SIZE 50 //用户名、电话号码、地址的最大长度#define HASHSIZE 400 //定义表长#define SUCCESS 1 //查找#define UNSUCCESS -1#define LEN sizeof(HashTable) // 哈希表的长度using namespace std;typedef int Status;//typedef用来定义类型的别名。
此处用status作为int别名,目的表达int 变量是一个状态变量。
typedef char NA[MAX_SIZE]; //NA作为char的别名typedef struct{ // 自定义一个记录用户名、电话号码、联系地址的结构体的别名recordNA name,tel,add,way;}Record;Record a[HASHSIZE];typedef struct{ //散列表Record *elem[HASHSIZE]; //数据元素存储地址int count; //数据元素个数int size; //容量}HashTable;Status eq(NA x,NA y){ //关键字比较,相等返回SUCCESS;否则返回UNSUCCESSif(strcmp(x,y)==0)//2个字符串的大小比较s1=s2,strcmp(s1,s2) == 0; s1>s2, strcmp(s1,s2) == 1; s1<s2, strcmp(s1,s2) == -1;return SUCCESS;elsereturn UNSUCCESS;}Status NUM_BER; //记录的个数void getin(Record* a){ // 键盘输入联系人的信息,Record*调用Record函数;a是参数cout<<"请输入要添加的联系人的个数:\n";cin>>NUM_BER;int i;for(i=0;i<NUM_BER;i++){cout<<"请输入第"<<i+1<<"个记录的用户名:\n";cin>>a[i].name;cout<<"请输入第"<<i+1<<"个记录的电话号码:\n";cin>>a[i].tel;cout<<"请输入第"<<i+1<<"个记录的地址:\n";cin>>a[i].add;}}void ShowInformation(Record* a)//显示输入的用户信息{int i;for( i=0;i<NUM_BER;i++)cout<<"\n第"<<i+1<<"个用户信息:\n 姓名:"<<a[i].name<<"\n 电话号码:"<<a[i].tel<<"\n 联系地址:"<<a[i].add<<"\n--------\n";}long fold(NA s) //人名的折叠处理:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址{char *p;long sum=0;NA ss;strcpy(ss,s);//复制字符串,不改变原字符串的大小写strupr(ss);//将字符串ss转换为大写形式p=ss;while(*p!='\0')sum+=*p++;return sum;}int Hash1(NA str){//哈希函数long n;int m;n=fold(str);//先将用户名进行折叠处理m=n%HASHSIZE; //折叠处理后的数,用除留余数法构造哈希函数return m; //并返回模值}int Hash2(NA str){//哈希函数long n;int m;n = atoi(str);//把字符串转换成整型数.m=n%HASHSIZE; //用除留余数法构造哈希函数return m; //并返回模值}Status collision(int p,int &c){ // 冲突处理函数,采用二次探测再散列法解决冲突int i,q;i=c/2+1;while( i < HASHSIZE ){if(c%2==0){c++;q=(p+i*i)%HASHSIZE;if(q>=0) return q;else i=c/2+1;}else{q=(p-i*i)%HASHSIZE;c++;if(q>=0) return q;else i=c/2+1;}}return UNSUCCESS;}int searchHash( HashTable * &H, NA key, int &p, int &c ,int way ){if( way == 1 ){p=Hash1( key );while(H->elem[p]!=NULL && !eq( key, H->elem[p]->name ) )//若哈希地址冲突,进行冲突处理collision( p ,++c );if( eq( key, H->elem[p]->name ) )return 1;elsereturn 0;}else{p=Hash2( key );while(H->elem[p]!=NULL && !eq( key, H->elem[p]->tel ) )//若哈希地址冲突,进行冲突处理collision( p ,++c );if( eq( key, H->elem[p]->tel ) )return 1;elsereturn 0;}}// 建表,若哈希地址冲突,进行冲突处理void CreateHash(HashTable* H ,Record* a){cout<<"\n 〓〓〓〓〓〓建立散列表〓〓〓〓〓〓〓";cout<<"\n ⑴. 以姓名建立散列表(再散列法解决冲突) ";cout<<"\n ⑵. 以电话号码建立散列表(再散列法解决冲突) ";cout<<"\n ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆";cout<<"请输入选择:";int num,i,p=-1,c;cin>>num;for(i=0;i<NUM_BER;i++){c=0;if( num==1 ){p=Hash1( a[i].name );while(H->elem[p]!=NULL && !eq( a[i].name, H->elem[p]->name ) )//若哈希地址冲突,进行冲突处理collision( p ,++c );}else{p=Hash2( a[i].tel );while(H->elem[p]!=NULL && !eq( a[i].tel, H->elem[p]->tel ) )//若哈希地址冲突,进行冲突处理collision( p ,++c );}H->elem[p]=a+i; //求得哈希地址,将信息存入H->count++;cout<<"第"<<i+1<<"个记录冲突次数为"<<c<<"。
数据结构课程设计-通讯录查询系统的设计与实现

通讯录查询系统的设计与实现一、需求分析1、问题描述为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的电话与地址。
设计散列表存储,设计并实现通讯录查找系统。
2、基本要求a.每个记录有下列数据项:电话号码、用户名、地址;b.从键盘输入各记录,分别以电话号码为关键字建立散列表;c.采用二次探测再散列法解决冲突;d.查找并显示给定电话号码的记录;e.通讯录信息文件保存。
二、概要设计1.数据结构本程序需要用到两个结构体,分别为通讯录message以及哈希表HxList2.程序模块本程序包含两个模块,一个是实现功能的函数的模块,另一个是主函数模块。
系统子程序及功能设计本系统共有三个子程序,分别是:int Hx(long long key,int data)//哈希函数void BulidHx(HxList &L)//建立通讯录int Search(HxList &L)//查找3.各模块之间的调用关系以及算法设计主函数调用BulidHx以及Search函数。
函数BulidHx调用函数Hx。
三、详细设计1.数据类型定义typedef struct{char *name;char *add;long long phonenumber;}message;typedef struct{message *list;int number;//记录数}HxList;2.系统主要子程序详细设计a. 建立通讯录void BulidHx(HxList &L)//建立通讯录{FILE *f = fopen("E:\\tongxunlu.txt", "w");char buf[20]={0},str[20]={0};long long key;cout<<"输入要建立的记录数:";cin>>L.number;L.number+=1;L.list=new message[L.number];//分配哈希表的存储空间for(int i=0;i<L.number;i++){L.list[i].phonenumber=-1;}L.list[L.number-1].name=NULL;L.list[L.number-1].add=NULL;cout<<"输入记录信息(电话号码用户名地址)"<<endl; for(int i=0;i<L.number-1;i++){cin>>key>>buf>>str;int pose=Hx(key,L.number);//获取理论上的存储位置if(L.list[pose].phonenumber==-1){}else{//用二次探测再散列法解决冲突//1^2 -1^2 2^2 -2^2int di,count=1;xunhuan: if(count%2==0)di=-(count/2)*(count/2);elsedi=((count/2)+1)*((count/2)+1);int site=Hx(key+di,L.number);if(site>=0){if(L.list[site].phonenumber==-1){pose=site;}else{count++;goto xunhuan;}}else{site=L.number-abs(site);if(L.list[site].phonenumber==-1){pose=site;}else{count++;goto xunhuan;}}}L.list[pose].phonenumber=key;fprintf(f,"%lld",key);fprintf(f," ");L.list[pose].name=new char[strlen(buf)+1];strcpy(L.list[pose].name,buf);fprintf(f,"%s",buf);fprintf(f," ");L.list[pose].add=new char[strlen(str)+1];strcpy(L.list[pose].add,str);fprintf(f,"%s",str);fprintf(f,"\n");}}b.查找int Search(HxList &L)//查找{long long key;cout<<"输入要查找记录的关键字(电话号码):";cin>>key;int pose=Hx(key,L.number);//计算理论上的位置if(L.list[pose].phonenumber==key){}else{int count=1,di;//二次探测再散列,查找xunhuan: if(count%2==0){di=-(count/2)*(count/2);}else{di=((count/2)+1)*((count/2)+1);}int site=Hx(key+di,L.number);if(site>=0){if(L.list[site].phonenumber==key){pose=site;}else{count++;if(L.list[site].phonenumber==-1){cout<<"没有找到"<<endl;return -1;//没有找到}goto xunhuan;}}else{site=L.number-abs(site);if(L.list[site].phonenumber==key){pose=site;}else{count++;if(L.list[site].phonenumber==-1){cout<<"没有找到"<<endl;return -1;//没有找到}goto xunhuan;}}}if(L.list[pose].phonenumber==key){cout<<"电话号码\t"<<"用户名\t"<<"地址"<<endl;cout<<L.list[pose].phonenumber<<"\t"<<L.list[pose].name<<"\t"<<L.list[pose].add< <endl;return pose;}}四、测试与分析1.显示主菜单,运行程序可以显示出如下界面。
数据结构课程设计通讯录管理系统报告

数据结构课程设计通讯录管理系统报告前言通讯录管理系统是一种常见的应用程序,用于帮助用户有效地组织和管理他们的联系人信息。
本报告旨在介绍和分析一个基于数据结构设计的通讯录管理系统,其中实现了基本的通讯录功能,并且通过合适的数据结构和算法进行优化。
功能需求通讯录管理系统需要实现以下基本功能: - 添加联系人信息 - 查找联系人信息 - 删除联系人信息 - 更新联系人信息 - 显示所有联系人信息数据结构选择为了实现通讯录管理系统的功能,我们选择使用链表作为数据结构。
链表是一种简单而灵活的数据结构,可以动态地添加或删除节点,非常适合存储联系人信息这种动态的数据。
在这里,我们采用双向链表,使得查找、插入和删除操作更加高效。
算法设计添加联系人信息添加联系人信息时,我们需要遍历链表找到合适的位置插入新节点,这里的算法复杂度为O(n),其中n表示链表的长度。
查找联系人信息查找联系人信息时,我们需要遍历链表查找目标节点,这里的算法复杂度为O(n)。
删除联系人信息删除联系人信息时,我们同样需要遍历链表找到目标节点并删除,其算法复杂度为O(n)。
更新联系人信息更新联系人信息时,我们首先需要查找到目标节点,然后进行更新操作,其算法复杂度也为O(n)。
系统优化为了提高系统的性能,我们可以通过以下几种方式进行优化: - 使用哈希表索引联系人信息,减少查找联系人的时间复杂度; - 引入缓存机制,减少频繁的IO 操作。
总结通过本报告的介绍和分析,我们了解了一个基于数据结构设计的通讯录管理系统的实现原理和优化方法。
在实际应用中,针对具体需求和场景,我们可以进一步优化系统性能,提升用户体验。
通讯录管理系统作为一种简单而实用的应用程序,将在日常生活中发挥重要作用。
[数据结构课程设计通讯录查询系统实验报告范文及源代码]数据结构通讯录
![[数据结构课程设计通讯录查询系统实验报告范文及源代码]数据结构通讯录](https://img.taocdn.com/s3/m/e16be22d657d27284b73f242336c1eb91a3733b4.png)
[数据结构课程设计通讯录查询系统实验报告范文及源代码]数据结构通讯录工程名称:停车管理系统姓名:学号:专业:软件工程1.需求分析为某个单位建立一个员工通讯录管理系统,可以方便查询每一个员工的与地址。
设计散列表存储,设计并实现通讯录查找系统。
1.根本要求〔1〕每个记录有以下数据项:号码、用户名、地址;〔2〕从键盘输入各记录,分别以号码为关键字建立散列表;〔3〕采用二次探测再散列法解决冲突;〔4〕查找并显示给定号码的记录;〔5〕通讯录信息文件保存。
2.重点、难点重点:〔1〕通过实验深入理解哈希表既是一种存储形式,又是一种查找方法;〔2〕哈希表的构造;〔3〕哈希冲突方案的设计。
难点:哈希表的构造与哈希冲突方案的设计输入的形式和输入值的范围;输入三个字符串:分别是号码,姓名,地址,每行一个数据字符串长度适当如:号码〔纯数字〕姓名地址输出的形式;如:姓名号码地址程序所能到达的功能。
1:并且通过号码为关键字,用二次再散列法寻找地址储存在哈希表中。
2:3:4:5:显示通讯录6:把通讯录写入文件储存。
2.概要设计(1)数据结构tructlit{chara[12];charname[15];charadd[15];intf=0;};用连续的内存空间构建哈希表tructqtack{tructlit某bae;inti;};(2)程序模块1:构建二次再散列:inti;for(i=1;i<25;i++)d[2某i]=-1某i某i;for(i=1;i<25;i++)/某构造二次再散列某/d[i+i-1]=i某i;2:主菜单:voidinterface(){inti;printf("某某某某某某某某某某某某某某某某某某某某\n");printf("某某某某某某某某某某某某某某某某某某某某\n");canf("%d",&i);witch(i){cae0:return;break;cae1:huru();break;cae2:print();break;cae3:each();break;cae4:del();break;cae5:change();break;cae6:write();break;};}3:输入voidhuru()4:存入哈希表,采用二次探测再散列法解决冲突;voidtore(char某a,char某name,char某add)voideach();voidchange()Voiddel〔〕;voidwrite()(3)各模块之间的调用关系以及算法设计3.详细设计4.测试与分析主界面:构建哈希表,允许号码重复可以支持姓名,,地址三个关键字的查找可以按照姓名地址删除写文件:创立文件通讯录.t某t 如图:5.附录3.cpp#include<tdio.h>#include<tdlib.h>#include<tring.h>#include<iotream>#include<tring.h>uingnamepacetd;intd[50];/某再散列某/tructlit{chara[12];charname[15];charadd[15];intf=0;};tructqtack{tructlit某bae;inti;};tructqtackS;voidtore(char某a,char某name,char某add){intkey;key=int(a[0])+int(a[3])+int(a[7]);/某以号码的第1,4,8位作为关键字构造哈希函数某/S.i=key%20;intj=1;while(true){if((S.bae+S.i)->f==0){trcpy((S.bae+S.i)->a,a);trcpy((S.bae+S.i)->name,name);trcpy((S.bae+S.i)->add,add);(S.bae+S.i)->f=1;break;}S.i=(key%20+d[j])%20;j++;}}voidhuru(){voidinterface();cout<<"请输入:\n例如:\n小王\n安徽省合肥市\n输入0结束\n"; chara[12];charname[15];charadd[15];while(true){canf("%",a);if(a[0]=='0')break;canf("%",name);canf("%",add);printf("%已保存\n",name);tore(a,name,add);/某将输入保存到哈希表某/}interface();}voidprint(){voidinterface();inti;printf("姓名号码地址\n");for(i=0;i<20;i++){if((S.bae+i)->f==1){printf("%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add);}}interface();}voideach(){voidinterface();inti;intff=0;intb;chara[15];printf("输入1按号码查找,输入2按姓名查找,输入3按地址查找\n");canf("%d",&b);witch(b){cae1:printf("请输入号码\n");canf("%",a);for(i=0;i<20;i++)if(trcmp(a,(S.bae+i)->a)==0){printf("%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add); ff=1;}if(ff==0)printf("找不到该用户\n");break;cae2:printf("请输入姓名\n");canf("%",a);for(i=0;i<20;i++)if(trcmp(a,(S.bae+i)->name)==0){printf("%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add); ff=1;}if(ff==0)printf("找不到该用户\n");break;cae3:printf("请输入地址\n");canf("%",a);for(i=0;i<20;i++)if(trcmp(a,(S.bae+i)->add)==0){printf("%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add); ff=1;}if(ff==0)printf("找不到该用户\n");break;}interface();}voiddel(){voidinterface();inti;intff=0;chara[15];printf("输入1按号码删除,输入2按姓名删除,输入3按地址删除\n");canf("%d",&b);witch(b){cae1:printf("请输入号码\n");canf("%",a);for(i=0;i<20;i++)if(trcmp(a,(S.bae+i)->a)==0){(S.bae+i)->f=0;Print(“已删除:%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add);ff=1;}if(ff==0)printf("找不到该用户\n");cae2:printf("请输入姓名\n");canf("%",a);for(i=0;i<20;i++)if(trcmp(a,(S.bae+i)->name)==0){(S.bae+i)->f=0;printf("已删除:%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add);ff=1;}if(ff==0)printf("找不到该用户\n");break;cae3:printf("请输入地址\n");canf("%",a);for(i=0;i<20;i++)if(trcmp(a,(S.bae+i)->add)==0){(S.bae+i)->f=0;printf("已删除:%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add);ff=1;}if(ff==0)printf("找不到该用户\n");break;}interface();}voidchange(){voidinterface();inti;intff=0;intb;chara[15];printf("请输入姓名\n");canf("%",a);for(i=0;i<20;i++)if(trcmp(a,(S.bae+i)->name)==0){printf("您要修改的是:%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add);printf("请输入新信息\n");canf("%",(S.bae+i)->a);canf("%",(S.bae+i)->name);canf("%",(S.bae+i)->add);printf("已修改成:%%%\n",(S.bae+i)->name,(S.bae+i)->a,(S.bae+i)->add);ff=1;}if(ff==0)printf("找不到该用户\n");interface();}voidwrite()voidinterface();inti=0;FILE某fp;if((fp=fopen("通讯录.t某t","wb"))==NULL){printf("openfileerror\n");e某it(1);}for(i=0;i<=20;i++){intch=32;if((S.bae+i)->f==1){fprintf(fp,"%",(S.bae+i)->name);fputc(ch,fp); fprintf(fp,"%",(S.bae+i)->a);fputc(ch,fp);ch=10;fprintf(fp,"%",(S.bae+i)->add);fputc(ch,fp); }fcloe(fp);interface();}voidinterface(){inti;printf("某某某某某某某某某某某某某某某某某某某某\n"); printf("某某某某某某某某某某某某某某某某某某某某\n"); canf("%d",&i);witch(i){cae0:return;break;cae1:huru();break;cae2:print();break;cae3:each();break;cae4:del();break;cae5:change();break;cae6:write();break;}intmain(){ytem("color70");//可以写成red调出颜色组S.bae=(tructlit某)malloc(20某izeof(tructlit)); ytem("date/T");ytem("TIME/T");inti;for(i=1;i<25;i++)d[2某i]=-1某i某i;for(i=1;i<25;i++)/某构造二次再散列某/d[i+i-1]=i某i;interface();}6.用户使用手册根据主菜单提示选择所想要的操作0:结束程序小华安徽合肥可以根据姓名,,地址分别作为关键字进行查询谢谢使用!。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
长春理工大学
学生实习报告
2010 —2011 学年第一学期
实习类别:课程设计
学院:软件学院
专业:软件开发与测试
班级:
姓名:
建通讯录
【问题描述】
设计散列表实现通讯录查找系统。
【基本要求】
(1) 设每个记录有下列数据项:电话号码、用户名、地址;
(2) 从键盘输入各记录,分别以电话号码为关键字建立散列表;
(3) 采用二次探测再散列法解决冲突;
(4) 查找并显示给定电话号码的记录;
(5) 通讯录信息文件保存;
(6) 要求人机界面友好,使用图形化界面;
【实现提示】
主函数:根据选单的选项调用各函数,并完成相应的功能。
Menu()的功能:显示英文提示选单。
Quit()的功能:退出选单。
Create()的功能:创建新的通讯录。
Append()的功能:在通讯录的末尾写入新的信息。
Find():查询某人的信息,如果找到了,则显示该人的信息,如果没有则提示通讯录中没有此人的信息。
Alter()的功能:修改某人的信息,如果未找到要修改的人,则提示通讯录中没有此人的信息。
Delete()的功能:删除某人的信息,如果未找到要删除的人,则提示通讯录中没有此人的信息。
List()的功能:显示通讯录中的所有记录。
Save()的功能:保存通讯录中的所有记录到指定文件中。
Load()的功能:从指定文件中读取通讯录中的记录。
(一).需求分析:
(1) 设每个记录有下列数据项:电话号码、用户名、地址;
(2) 从键盘输入各记录,分别以电话号码为关键字建立散列表
(3) 采用二次探测再散列法解决冲突
(4) 查找并显示给定电话号码的记录
(5) 通讯录信息文件保存
(6) 要求人机界面友好,使用图形化界面
(二)概要设计:(流程图)
总流程图:
1.Append()的功能:在通讯录的末尾写入新的信息,并返回选单.
2.Find():查询某人的信息,如果找到了,则显示该人的信息,如果没有则提示通讯录中没有此人的信息.
3.Alter()的功能:修改某人的信息,如果未找到要修改的人,则提示通讯录中没有此人的信息.
4.Delete()的功能:删除某人的信息,如果未找到要删除的人,则提示通讯录中没有此人的信息.
5.Menu()的功能:显示英文提示选单。
6.Quit()的功能:退出选单。
7.Create()的功能:创建新的通讯录。
8.List()的功能:显示通讯录中的所有记录。
9.Save()的功能:保存通讯录中的所有记录到指定文件中。
10.Load()的功能:从指定文件中读取通讯录中的记录。
(三)详细设计(重要函数、存储结构、类型定义):
//--------通讯录数据类型定义-------------------
typedefstruct Information
{
char Name[20];
char PhoneNO[12]; //以电话号码为关键字建立散列表
char Address[30];
}Inform;
//--------电话本结构设计----------------
typedefstruct Record
{
Inform *base;
intnum; //记录记录的个数
}Record;
//---------哈希表结构定义-------------------
typedefstruct Hash
{
char key[12];
int address;
}Hash;
Record record; //将记录设置为全局变量
Hash *f; //将哈希表设置为全局变量
//-----------二次探测再散列数组定义---
int research[MOD/2];
//-----------二次探测数组初始化-------
void ArrayIni() //±12,±22,±32,±42……±(MOD/2)2.
{
inti,j;
for (i=0,j=-1;i<MOD/2;i=i+2)
{
research[i]=(i+1)*(i+1);
if(i+1<MOD/2)
research[i+1]=j*(i+1)*(i+1);
}
}
//---------------菜单数据定义---------------------
typedefenum{Create,Append,Find,Alter,Delete,List,Save,Load,Quit}DO;
四)调试分析:
1,遇到的问题:
问题1: 将电话号作为关键字在哈希表中存储时,需要将字符串转换为整形,而直接将11位字符串转换为整形将超出int型的最大范围,故不可直接将字符串直接转换为int,要先截取一定长度的字符串,然后转换为整形,再用:Hi=(H(key)%MOD)m 换算在该记录哈希表中的位置。
key=change(phoneNum);
addr=key%MOD;
while((EQ(f[addr].key,phoneNum)!=1)&&i<MOD/2)
{
addr=(key+research[i++])%MOD;
}
问题2: 电话号的前几位一般是相同的,故用于转换为关键字的串需要是电话号的后几位,而现有的strncpy()功能是截取字符串的前几位,故需要自己定义一个转换函数.为此可以先将字符串反转,去前几位,然后将取得的字符串再反转,即得到原来电话号的后几位字符串。
//----------电话号码到关键字的转换---------------
intchange(char phoneNum[])
{
charstr[4];
int key;
strrev(phoneNum);
strncpy(str,phoneNum,3);
str[3]='\0';
strrev(str);
key=atoi(str);
return key;
}
问题3: 图形界面的实现.
因知识水平的限制,MFC中的图形界面用的不熟练,故选择擅长的c来做此通讯录,但c中找不到实用的图形界面头文件.所以就需要自己绘制图形界面。
cout<<" !*********迷你电话本************!"<<endl;
cout<<" |------------------( ^* _ *^ )----------------------|"<<endl;
cout<<" |**【新建电话】请输入: 0 ***|"<<endl;
cout<<" |**【添加记录】请输入: 1 ***|"<<endl;
cout<<" |**【查找记录】请输入: 2 ***|"<<endl;
cout<<" |**【修改记录】请输入: 3 ***|"<<endl;
cout<<" |**【删除记录】请输入: 4 ***|"<<endl;
cout<<" |**【浏览记录】请输入: 5 ***|"<<endl;
cout<<" |**【保存电话本】请输入: 6 ***|"<<endl;
cout<<" |**【打开电话本】请输入: 7 ***|"<<endl;
cout<<" |**【退出】请输入: 8 ***|"<<endl;
cout<<" !---------------------------------------------------!"<<endl;
cout<<" 使用说明:其他操作之前请先新建电话本"<<endl;
cout<<" --------请选择操作的序列号!----------------"<<endl;
2.课程设计过程的收获
通过课程设计让我学习到一个程序正确运行需要各个子程序正确结合,以及严密的语法结构,还要有清晰的流程图。
3.在课程设计过程中对《数据结构》课程的认识
数据结构锻炼的是我们的逻辑思维能力,能增加我们编程过程中的思维的严密性与可行性。
数据结构考察的是程序的时间复杂度,与空间复杂度。
它们直接反映了算法的优劣程度。
故在将算法实现为程序的时候就需要注意实现语言,循环结构的选择,以及变量的类型等。