一、实验目的
- 掌握Dev-C++环境下的编译、调试和执行的方法及步骤。
- 掌握哈希表的线性探测法处理冲突的方式。
- 理解创建、查找、删除关键字的算法实现过程。
二、实验内容
设计一个程序实现哈希表的相关运算,并在此基础上完成如下功能:
(1)建立{16,74,60,43,54,90,46,31,29,88,77}哈希表A[0..12],哈希函数为:H(k)=key%p,p=m,并采用线性探查法解决冲突。
(2)在上述哈希表中查找关键字为29的记录;
(3)在上述哈希表中删除关键字为77的记录,再将其插入;
(4)(选做)输出该哈希表的成功和不成功的平均查找长度。(需给出不成功查找时的比较次数)
三、实验设计
1. 新建项目,定义哈希表的类型。
①新建项目,项目里新建文件“hash.h”,在该文件里定义哈希表的类型如下:
typedef int KeyType;
typedef char InfoType;
typedef struct
{
KeyType key; //关键字
InfoType data; //其他数据
int count; //探查次数
} HashTable; //哈希表类型
②关键字类型为整数,将哈希表中空闲单元的关键字设置为特殊值-1,被删元素的关键字设置为特殊值-2,以示区分。相关宏定义如下,注意放置位置。
#define NULLKEY -1 //定义空关键字值
#define DELKEY -2 //定义被删关键字值
2. 在“hash.h”中,实现开放地址法构造哈希表的运算算法。
①//将关键字k插入到哈希表中(请参考课本代码)
void InsertHT(HashTable *ha, int &n, KeyType k, int p)
②//创建哈希表(请参考课本代码)
void CreateHT(HashTable *ha, KeyType x[], int n, int m, int p)
③//输出哈希表(参考下图自己设计)
void DispHT(HashTable *ha, int m)
实现界面如下:
3. 在“main.cpp”里,给定初始数据,构造哈希表并完成题目要求。
①构造初始的哈希表如下:
int x[] = {16,74,60,43,54,90,46,31,29,88,77}; //初始数据
int n=11, m=13, p=13;
//n为数据个数,m为表长,p为哈希函数中的除数p,k为查找关键字
HashTable ha[MaxSize];
CreateHT(ha, x, n, m, p);
DispHT(ha, n, m);
②编译运行之后,应有如上图所示的结果。
4. 在“hash.h”中,实现查找关键字和删除关键字的代码。
①//在哈希表中查找关键字k(请参考课本代码)
int SearchHT(HashTable *ha, int p, KeyType k)
②//删除哈希表中的关键字k(请参考课本代码)
int DeleteHT(HashTable *ha, int p, int k, int &n)
5. 在“main.cpp”里,完成实验内容(2)和(3)。
①查找关键字29,参考代码如下:
int k=29;
int i = SearchHT(ha, p, k);
if(i != -1)
printf("ha[%d].key = %d\n", i, k);
else
printf("提示:未找到%d\n", k);
②删除关键字77后,再搜索,参考代码如下:
k=77;
printf("\n删除关键字%d\n", k);
DeleteHT(ha, p, k, n);
DispHT(ha, n, m);
printf("删除后再搜索关键字%d:",k);
i = SearchHT(ha, p, k);
if(i != -1)
printf(" ha[%d].key=%d", i, k);
else
printf("提示:未找到%d\n", k);
③在哈希表中插入关键字77,参考代码如下:
printf("\n插入关键字%d\n", k);
InsertHT(ha, n, k, p);
DispHT(ha, n, m);
- (选做)实现求平均查找长度的算法
①在“hash.h”中,增加ASL的实现代码
//成功和不成功的平均查找长度(请参考课本代码,需给出不成功查找时的比较次数,代码需略做修改)
void ASL(HashTable ha[], int n, int m, int p)
②在“main.cpp”里,调用求查找长度算法,代码如下:
ASL(ha, n, m, p);
四、测试结果
1. 显示初始哈希表截图
2. 查找关键字29的实现截图
3. 删除关键字77之后再将其插入的实现截图
4. (选做)求平均查找长度的实现截图
- 哈希表输出如下所示,请给具体的算法实现
void DispHT(HashTable *ha, int m)
{
int j;
printf("哈希表地址:\t");
for(int i=0;i<m;i++)
printf("%d\t",i);
printf("\n哈希表关键字:\t");
for(int i=0;i<m;i++)
{
if(ha[i].key>0)
printf("%d\t",ha[i].key);
else if(ha[i].key<0) printf(" ");
}
printf("\n搜索次数:\t");
for(int i=0;i<m;i++)
{
if(ha[i].key>0)
printf("%d\t",ha[i].count);
else if(ha[i].count==0) printf(" ");
}
}
void DispHT2(HashTable *ha, int m)
{
int j;
printf("哈希表地址:\t");
for(int i=0;i<m;i++)
printf("%d\t",i);
printf("\n哈希表关键字:\t");
for(int i=0;i<m;i++)
{
if(ha[i].key>0)
printf("%d\t",ha[i].key);
else if(ha[i].key<0) printf(" ");
}
printf("\n搜索次数:\t");
for(int i=0;i<m;i++)
printf("%d\t",ha[i].data);
}