数据结构报告——散列表、哈希表
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数
据
结
构
实
验
报
告
班级:姓名:学号:时间:
一、题目
散列表的设计
二、要求
1、问题描述
针对某个集体中人名设计一个散列表,使得平均查找长度不超过R,并完成相应的建表和查表程序。
2、基本要求
假设人名为中国人姓名的汉语拼音形式,待填入散列表的人名共有30个,取平均查找长度上限为2。散列函数用除留余数法构造,用伪随机探测再散列法处理冲突
3、测试数据
取读者周围较熟悉的30人的姓名。
4、实现提示
如果随机函数自行构造,则应首先调整好随机函数,使其发布均匀。人名的长度不超过20个字符。可先对过长的人名作折叠处理。
三、设计思想
1、散列函数的构造方法:
散列列函数的构造方法有四种:平方取中法、除余法、相乘取整法、随机数法。
这里用了除余法,该方法是最为简单常用的一种方法。它是以表长m来除关键字,取其余数作为散列地址,即 h(key)=key%m
该方法的关键是选取m。选取的m应使得散列函数值尽可能与关键字的各位相关。m最好为素数。
【例】若选m是关键字的基数的幂次,则就等于是选择关键字的最后若干位数字作为地址,而与高位无关。于是高位不同而低位相同的关键字均互为同义词。
【例】若关键字是十进制整数,其基为10,则当m=100时,159,259,359,…,等均互为同义词。
2、冲突的处理:
(1)冲突
两个不同的关键字,由于散列函数值相同,因而被映射到同一表位置上。该现象称为冲突(Collision)或碰撞。发生冲突的两个关键字称为该散列函数的同义词(Synonym)。
(2)安全避免冲突的条件
最理想的解决冲突的方法是安全避免冲突。要做到这一点必须满足两个条件:
①其一是|U|≤m
②其二是选择合适的散列函数。
这只适用于|U|较小,且关键字均事先已知的情况,此时经过精心设计散列函数h有可能完全避免冲突。
(3)冲突不可能完全避免
通常情况下,h是一个压缩映像。虽然|K|≤m,但|U|> m,故无论怎样设计h,也不可能完全避免冲突。因此,只能在设计h时尽可能使冲突最少。同时还需要确定解决冲突的方法,使发生冲突的同义词能够存储到表中。
(4)影响冲突的因素
冲突的频繁程度除了与h相关外,还与表的填满程度相关。
设m和n分别表示表长和表中填人的结点数,则将α=n/m定义为散列表的装填因子(Load Factor)。α越大,表越满,冲突的机会也越大。通常取α≤1。
(5)冲突处理
对不同的关键字可能得到同一个哈希地址即key1≠key2,而f(key1)=f(key2)。因此,在建造哈希表时不仅要设定一个好的哈希函数,而且要设定一种处理冲突的方法。用伪随机探测法。求下一个开放地址的公式为:Hi = (H(k)+di) MOD m
Di=伪随机数序列;
3、相应的数据结构:
1)、对哈希表的操作
InitNameList()
操作结果:姓名(结构体数组)初始化
CreateHashList()
操作结果:建立哈希表
FindList()
操作结果:在哈希表中查找
Display()
操作结果:显示哈希表
2)、主程序
int main()
{
初始化;
InitNameList();CreateHashList();
do {
接受命令;
处理命令;
}while(“命令”=“退出”);return 0;
}
3 )、本程序包含的模块
1)初始化操作,结构体定义;2)姓名结构体建立模块;
3)建立哈希表模块;
4)查找模块;
5)显示哈希表模块;
4)主程序模块
四、结构图
五、流程图
注①:——散列表设计——
a.显示散列表
b.查找
c.退出
请选择:
六、测试
1.本程序运行环境为C++,生成的可执行文件为a.exe;
该可执行文件的执行环境为DOS。
用户进入演示程序后的界面为:
2.测试结果
输入:a
输出:散列表
输入:b
输入:lilei
输出:无此记录!
输入:chenlinsha
输出:姓名:chenlinsha 关键字:1053 查找长度:1
七、程序清单
#include
#include
using namespace std;
#define HASH_LENGTH 50
#define M 47
#define NAME_NO 30
typedef struct
{ char *xm;
int k;
}NAME;
NAME NameList[HASH_LENGTH];
typedef struct
{ char *xm;
int k;
int si;
}HASH;
HASH HashList[HASH_LENGTH];
void InitNameList()
{ char *f;
int r,s0,i;
for (i=0; i { NameList[i].xm = new char[64]; NameList[i].xm[0] = 0; } strcpy(NameList[0].xm, "yingjun"); strcpy(NameList[1].xm, "shengjiayan"); strcpy(NameList[2].xm, "jiangxiya"); strcpy(NameList[3].xm, "caihaipou"); strcpy(NameList[4].xm, "shengwenbing"); strcpy(NameList[5].xm, "chenlinsha"); strcpy(NameList[6].xm, "yangqifan");