一、 实验目的:
学习设计哈希表,并采用一定的方法解决冲突,将哈希表显示出来。有兴趣还可以练习一下哈希表的查找。
二、 实验要求:
使用自己熟悉的一门语言编写算法,实现实验内容。
三、 使用仪器、设备:
一台安装了VC++ 6.0 软件的计算机
四、 实验内容:
1.问题描述
设计哈希表实现电话号码查询系统
(1) 设每个记录有下列数据项:电话号码,用户名、地址
(2) 从键盘输入各记录,以电话号码为关键字建立哈希表
(3) 采用链地址法解决冲突
(4) 显示建立好的哈希表,对于学有余力的可以实现哈希表的查找
2.说明
(1)采用除留余数法进行哈希表的散列,即以电话号码作为主关键字,将电话号码的11位相加,按照模7取余。
(2)解决冲突用链地址法
五、 程序源代码如下:
#include <iostream.h>
#include <string.h>
#define MaxSize 8
#define NULL 0
int key;
typedef struct node
{
char name[8],address[20],num[11];
node *next;
}*HashNode;
node **Hash;
void initHash()
{#include <iostream.h>
#include <string.h>
#define MaxSize 8
#define NULL 0
int key;
typedef struct node
{
char name[8],address[20],num[11];
node *next;
}*HashNode;
node **Hash;
void initHash()
{
int i;
Hash=new HashNode[MaxSize];
for(i=0;i<MaxSize;i++)
{
Hash[i]=new node;
Hash[i]->next=NULL;
}
}
void HashByNum(char num[11])//以电话号码为关键字建立哈希函数
{
int i=1;
key=(int)num[0]-48;
while(num[i]!=NULL)
{
key+=(int)num[i]-48;
i++;
}
key=key%7;
}
void insertHash()
{
node *temp;
temp=new node;
temp->next=NULL;
cout<<"输入姓名:"<<endl;
cin>>temp->name;
cout<<"输入住址:"<<endl;
cin>>temp->address;
cout<<"输入电话:"<<endl;
cin>>temp->num;
temp->next=NULL;
HashByNum(temp->num);
temp->next=Hash[key]->next;
Hash[key]->next=temp;
}
void printHash()
{
int i;
node *p;
for(i=0;i<MaxSize-1;i++)
{
cout<<i;
p=Hash[i]->next;
while(p)
{
cout<<"---->";
cout<<p->name<<" "<<p->address<<" "<<p->num;
p=p->next;
}
cout<<endl;
}
}
void findByNum(char num[11])
{
HashByNum(num);
node *q=Hash[key]->next;
while(q!=NULL)
{
if(strcmp(num,q->num)==0)
break;
q=q->next;
}
if(q)
cout<<q->name<<" "<<q->address<<" "<<q->num<<endl;
else
cout<<"无此记录"<<endl;
}
int main()
{
char num[11];
initHash();
int sel;
while(1)
{
cout<<" 哈希表通讯录"<<endl;
cout<<" 0.添加记录"<<endl;
cout<<" 1.查找记录"<<endl;
cout<<" 2.显示列表"<<endl;
cout<<" 3.清空记录"<<endl;
cout<<" 4.退出系统"<<endl;
cin>>sel;
switch(sel)
{
case 0:
cout<<"输入要添加的内容:"<<endl;
insertHash();
break;
case 1:
cout<<"输入电话号码:"<<endl;
cin>>num;
cout<<"输出查找的信息:"<<endl;
findByNum(num);
break;
case 2:
cout<<"显示的结果:"<<endl;
printHash();
break;
case 3:
cout<<"列表已清空"<<endl;
initHash();
break;
default:
return 0;
}
}
}
int i;
Hash=new HashNode[MaxSize];
for(i=0;i<MaxSize;i++)
{
Hash[i]=new node;
Hash[i]->next=NULL;
}
}
void HashByNum(char num[11])//以电话号码为关键字建立哈希函数
{
int i=1;
key=(int)num[0]-48;
while(num[i]!=NULL)
{
key+=(int)num[i]-48;
i++;
}
key=key%7;
}
void insertHash()
{
node *temp;
temp=new node;
temp->next=NULL;
cout<<"输入姓名:"<<endl;
cin>>temp->name;
cout<<"输入住址:"<<endl;
cin>>temp->address;
cout<<"输入电话:"<<endl;
cin>>temp->num;
temp->next=NULL;
HashByNum(temp->num);
temp->next=Hash[key]->next;
Hash[key]->next=temp;
}
void printHash()
{
int i;
node *p;
for(i=0;i<MaxSize-1;i++)
{
cout<<i;
p=Hash[i]->next;
while(p)
{
cout<<"---->";
cout<<p->name<<" "<<p->address<<" "<<p->num;
p=p->next;
}
cout<<endl;
}
}
void findByNum(char num[11])
{
HashByNum(num);
node *q=Hash[key]->next;
while(q!=NULL)
{
if(strcmp(num,q->num)==0)
break;
q=q->next;
}
if(q)
cout<<q->name<<" "<<q->address<<" "<<q->num<<endl;
else
cout<<"无此记录"<<endl;
}
int main()
{
char num[11];
initHash();
int sel;
while(1)
{
cout<<" 0.添加记录 1.查找记录 2.显示列表 3.清空记录 4.退出系统"<<endl;
cin>>sel;
switch(sel)
{
case 0:
cout<<"输入要添加的内容:"<<endl;
insertHash();
break;
case 1:
cout<<"输入电话号码:"<<endl;
cin>>num;
cout<<"输出查找的信息:"<<endl;
findByNum(num);
break;
case 2:
cout<<"显示的结果:"<<endl;
printHash();
break;
case 3:
cout<<"列表已清空"<<endl;
initHash();
break;
default:
return 0;
}
}
}
五、 程序截图如下:
六、 实验心得:
这次实验总的来说不是很难,但是需要注意的细节很多。首先,先要确定要用哪种存储方式建立哈希表,我采用的是邻接链表,用除留余数法,确定哈希地址,然后就是解决冲突,,老师要求的使用链地址法,链地址法解决冲突构造的哈希表是个动态表,更适合造表之前无法确定记录个数的情况,最后就是查找操作,以电话号码作为关键字,依次查找。程序中出现了一个以前没有注意到的一个知识点:key=(int)num[0]-48;是将字符串转换为整形,很重要,要记住。