哈希表的实现
我数据结构课程设计的题目,如有不足之处还望大家批评指正。
在vc 6.0下面调试通过。
file:<HashList.h>
#define HashMaxsize 40
#define NullTag -100
#define DeleteTag -200
typedef int Keytype;
struct Elemtype{
int key;
char name[20];
char telephone[15];
char address[20];
int search;
};
typedef struct Elemtype HashList[HashMaxsize];
file:<main.cpp>
#include <iostream.h>
#include <string.h>
#include <process.h>
#include <conio.h>
#include <iomanip.h>
#include "HashList.h"
int n=7,m=19;
int count,index[HashMaxsize];
Elemtype people[]={{0,"one","027-86532287","湖北武汉",0},{0,"two","027-86532287","湖北襄樊",0},{0,"three","027-86532285","湖北公安",0},{0,"four","027-86532284","贵州织金",0},{0,"five","027-86532283","湖北武汉",0},{0,"six","027-86532282","安徽裴岗",0},{0,"eight","027-86532280","湖北汉川"}};
HashList ht;
HashList ht1;
void ClearHashList(HashList ht)//清空散列表
{
int i;
for(i=0;i<HashMaxsize;i++)
{
ht[i].key=NullTag;
}
}//ClearHashList
int HashFunction1(Keytype key,int m)//散列函数1
{
return key%m;
}//HashFunction1
int HashFunction2(Keytype key,int m) //散列函数2
{
return 1+key%(m-2);
}//HashFunction2
int ProduceKey(char *p)//产生数字关键字
{
int sum=0,i,length;
length=strlen(p);
for(i=0;i<length;i++)
{
if(p[i]>0)
{
sum<<=2; //sum 左移两位
sum=sum+p[i];
}
else
{ sum<<=2;
sum=sum-p[i];
}
}
return sum%10000;
}//ProduceKey
istream & operator >>(istream & in, Elemtype& str)//输入操作符重载
{
cout<<"请输入学生的姓名:"<<endl;
cin>>str.name;
cout<<"请输入学生的电话号码:"<<endl;
cin>>str.telephone ;
cin.get();//吸收掉换行回车符
cout<<"请输入家庭住址:"<<endl;
cin>>str.address;
str.key=ProduceKey(str.name );
cout<<endl;
return in;
}
ostream & operator <<(ostream & out, Elemtype& str)//输出操作符重载
{
cout<<setiosflags(ios::left)<<setw(15)<<str.key<<setw(15)<<str.name<<setw(15)<<str.address<<setw(20)<<str.telephone<<setw(15)<<str.search ;
cout<<endl;
return out;
}
void PrintHashList(HashList ht,int m)//输出散列表
{
int i,total=0;
float sum=0.0;
cout<<"散列表为:\n"<<endl;
cout<<setiosflags(ios::left)<<setw(15)<<"下标"<<setw(15)<<"关键字"<<setw(15)<<"姓名"<<setw(15)<<"家庭地址"<<setw(20)<<"联系电话"<<setw(15)<<"搜索次数"<<endl;
for(i=0;i<m;i++)
{
if(ht[i].key!=NullTag&& ht[i].key!=DeleteTag)
{ cout<<setiosflags(ios::left)<<setw(15)<<i;
cout<<ht[i];
sum+=ht[i].search;
total++;
}
}
cout<<"\n\t\t\t\t平均搜索长度为:"<<sum/total<<endl;
}//PrintHashList
/////////
bool Insert(HashList ht,int m,Elemtype x)//添加新的记录
{
x.key =ProduceKey(x.name );
int d=HashFunction1(x.key,m);
x.search =1;
int temp=d;
while(ht[d].key!=NullTag&&ht[d].key!=DeleteTag)
{
d=(d+HashFunction2(x.key ,m))%m;
x.search++;
if(d==temp)
{
cout<<"散列表空间已被占满,应重新建立!"<<endl;
return false;
}
}
ht[d]=x;
return true;
}//Insert
bool Insert1(HashList ht,int m,Elemtype x)
{
x.key =ProduceKey(x.telephone);
int d=HashFunction1(x.key,m);
x.search =1;
int temp=d;
while(ht[d].key!=NullTag&&ht[d].key!=DeleteTag)
{
d=(d+HashFunction2(x.key ,m))%m;
x.search++;
if(d==temp)
{
cout<<"散列表空间已被占满,应重新建立!"<<endl;
return false;
}
}
ht[d]=x;
return true;
}
void InitHashList(HashList ht) //初始化散列表
{
int i;
for(i=0;i<HashMaxsize;i++)
{
ht[i].key=NullTag;
}
for(i=0;i<n;i++)
{
Insert(ht,m,people[i]);
}
}//InitHashList
void InitHashList1(HashList ht)
{
int i;
for(i=0;i<HashMaxsize;i++)
{
ht[i].key=NullTag;
}
for(i=0;i<n;i++)
{
Insert1(ht,m,people[i]);
}
}
void Search(HashList ht,int m,int * index) //查找记录
{
char ch1[20];
cout<<"\n请输入要查询的姓名:";
cin>>ch1;
int i,temp;
int k=ProduceKey(ch1);
int d=HashFunction1(k,m);
temp=d;
int visit[HashMaxsize];
int test;
for(i=0;i<m;i++)
{
visit[i]=0;
}
count=0;
while(ht[d].key!=NullTag)
{
visit[d]=1;
if(ht[d].key==k)
{
index[count]=d;
count++;
}
d=(d+HashFunction2(k,m))%m;
test=1;
for(i=0;i<m;i++)
{
if(visit[i]==0)
{
test=0;
}
}
if(test)
{
exit(0);
}
}
}
void Search1(HashList ht,int m,int * index)
{
char ch1[20];
cout<<"\n请输入要查询的电话号码:";
cin>>ch1;
int i,temp;
int k=ProduceKey(ch1);
int d=HashFunction1(k,m);
temp=d;
int visit[HashMaxsize];
int test;
for(i=0;i<m;i++)
{
visit[i]=0;
}
count=0;
while(ht[d].key!=NullTag)
{
visit[d]=1;
if(ht[d].key==k)
{
index[count]=d;
count++;
}
d=(d+HashFunction2(k,m))%m;
test=1;
for(i=0;i<m;i++)
{
if(visit[i]==0)
{
test=0;
}
}
if(test)
{
exit(0);
}
}
}
void CreateHashList(HashList ht) //以默认的数据建立散列表
{
Elemtype x;
int i;
cout<<"\n从键盘输入待散列元素的个数n和散列表的长度m:";
do{
cin>>n>>m;
if(n>m-1||m>HashMaxsize)
{
cout<<"输入错误,n应小于m,";
}
if(m%2==0)
{
cout<<"m应该为奇数,";
}
cout<<"请重新输入:";
}while(n>m-1||m>HashMaxsize||m%2==0);
for(i=0;i<n;i++)
{
cin>>x;
Insert(ht,m,x);
}
}
void MainMenu() //系统主菜单
{
cout<<"请输入操作菜单:"<<endl;
cout<<"\t①.建立散列表"<<endl;
cout<<"\t②.显示散列表(姓名为关键字)"<<endl;
cout<<"\t③.显示散列表(电话为关键字)"<<endl;
cout<<"\t④.按姓名查询"<<endl;
cout<<"\t⑤.按电话查询"<<endl;
cout<<"\t⑥.添加记录"<<endl;
cout<<"\t⑦.清除屏幕"<<endl;
cout<<"\t⑧.退出系统"<<endl;
}
void MainChoice()
{
char ch;
bool flag1=false;
bool flag2=true;
do{
MainMenu();
ch=getch();
if(ch=='1')
{
char ch1;
cout<<"你已经建立了散列表,是否要重新建立(Y/N)?"<<endl;
ch1=getch();
if(ch1=='Y'||ch1=='y')
{
ClearHashList(ht);
CreateHashList(ht);
ClearHashList(ht1);
for(int i=0;i<m;i++)
{
if(ht[i].key!=NullTag)
{
ht1[i]=ht[i];
ht1[i].key=ProduceKey(ht[i].telephone);
}
}
flag1=true;
flag2=false;
}
else if(ch1=='N'||ch1=='n')
{
}
}
else if(ch=='2')
{
cout<<"\n以姓名为关键字建立的";
PrintHashList(ht,m);
}
else if(ch=='3')
{
cout<<"\n以电话号码为关键字建立的";
PrintHashList(ht1,m);
}
else if(ch=='4')
{
if(flag1||flag2)
{
//int index[HashMaxsize];
Search(ht,m,index);
if(count==0)
{
cout<<"查询失败,没有找到要查询的记录!\n\n"<<endl;
}
else
{
int p;
cout<<"查询结果如下:"<<endl;
cout<<setiosflags(ios::left)<<setw(10)<<"下标"<<setw(15)<<"关键字"<<setw(15)<<"姓名"<<setw(15)<<"家庭地址"<<setw(15)<<"联系电话"<<setw(10)<<"搜索次数"<<endl;
for(int i=0;i<count;i++)
{
cout<<setw(10)<<index[i];
p=index[i];
cout<<ht[p];
}
}
}
else
{
cout<<"\n你还没有建立散列表!\n\n"<<endl;
}
}
else if(ch=='5')
{
if(flag1||flag2)
{
//int index[HashMaxsize];
Search1(ht1,m,index);
if(count==0)
{
cout<<"查询失败,没有找到要查询的记录!\n\n"<<endl;
}
else
{
cout<<"查询结果如下:"<<endl;
cout<<"下标\t"<<"关键字\t\t"<<"姓名\t\t"<<"家庭地址\t\t"<<"联系电话\t"<<"搜索次数"<<endl;
for(int i=0;i<count;i++)
{
cout<<index[i]<<"\t";
cout<<ht1[index[i]];
}
}
}
else
{
cout<<"\n你还没有建立散列表!\n\n"<<endl;
}
}
else if(ch=='6')
{
if(flag1||flag2)
{
Elemtype x;
cin>>x;
Insert(ht,m,x);
Insert1(ht1,m,x);
}
else
{
cout<<"\n你还没有建立散列表!\n\n"<<endl;
}
}
else if(ch=='7')
{
system("cls");
}
else if(ch=='8')
{
return ;
}
else
{
cout<<"输入错误!!"<<endl;
}
}while(1);
}
void main() //主函数
{
InitHashList(ht);
InitHashList1(ht1);
MainChoice();
}