文档库 最新最全的文档下载
当前位置:文档库 › 哈希表及其应用

哈希表及其应用

哈希表及其应用
哈希表及其应用

哈希表及其应用

一、定义

二、基本原理

哈希表的基本原理是:使用一个下标范围比较大的数组A来存储元素,设计一个函数h,对于要存储的线性表的每个元素node,取一个关键字key,算出一个函数值h(key),把h(key)作为数组下标,用A[h(key)]这个数组单元来存储node。也可以简单的理解为,按照关键字为每一个元素“分类”,然后将这个元素存储在相应“类”所对应的地方(这一过程称为“直接定址”)。

但是,不能够保证每个元素的关键字与函数值是一一对应的,因此极有可能出现对于不同的元素,却计算出了相同的函数值,这样就产生了“冲突”,换句话说,就是把不同的元素分在了相同的“类”之中。例如,假设一个结点的关键码值为key,把它存入哈希表的过程是:根据确定的函数h计算出h(key)的值,如果以该值为地址的存储空间还没有被占用,那么就把结点存入该单元;如果此值所指单元里已存了别的结点(即发生了冲突),那么就再用另一个函数I进行映象算出I(h(key)),再看用这个值作为地址的单元是否已被占用了,若已被占用,则再用I映象,……,直到找到一个空位置将结点存入为止。当然这只是解决“冲突”的一种简单方法,如何避免、减少和处理“冲突”是使用哈希表的一个难题。

在哈希表中查找的过程与建立哈希表的过程相似,首先计算

h(key)的值,以该值为地址到基本区域中去查找。如果该地址对应的空间未被占用,则说明查找失败,否则用该结点的关键码值与要找的key比较,如果相等则检索成功,否则要继续用函数I 计算I(h(key))的值,……。如此反复到某步或者求出的某地址空间未被占用(查找失败)或者比较相等(查找成功)为止。

三、基本概念和简单实现

1、两个集合:U是所有可能出现的关键字集合;K是实际存储的关键字集合。

2、函数h将U映射到表T[0..m-1]的下标上,可以表示成h:U→{0,1,2,...,m-1},通常称h为“哈希函数(Hash Function)”,其作用是压缩待处理的下标范围,使待处理的|U|个值减少到m 个值,从而降低空间开销(注:|U|表示U中关键字的个数,下同)。

3、将结点按其关键字的散列地址存储到哈希表(散列表)中的过程称为“散列(Hashing)”。方法称为“散列法”。

4、h(Ki)(Ki∈U)是关键字为Ki的结点的“存储地址”,亦称散列值、散列地址、哈希地址。

5、用散列法存储的线性表称为“哈希表(Hash Table)”,又称散列表。图中T即为哈希表。在散列表里可以对结点进行快速检索(查找)。

6、对于关键字为key的结点,按照哈希函数h计算出地址h(key),若发现此地址已被别的结点占用,也就是说有两个不同的关键码值key1和key2对应到同一个地址,即h(key1)=h(key2),这个现象叫做“冲突(碰撞)”。碰撞的两个(或多个)关键码称为“同义词”(相对于函数h而言)。如图1中的关键字k2和k5,

h(k2)=h(k5),即发生了“冲突”,所以k2和k5称为“同义词”。假如先存了k2,则对于k5,我们可以存储在h(k2)+1中,当然

h(k2)+1要为空,否则可以逐个往后找一个空位存放。这是另外一种简单的解决冲突的方法。

发生了碰撞就要想办法解决,必须想办法找到另外一个新地址,这当然要降低处理效率,因此我们希望尽量减少碰撞的发生。这就需要分析关键码集合的特性,找适当的哈希函数h使得计算出的地址尽可能“均匀分布”在地址空间中。同时,为了提高关键码到地址转换的速度,也希望哈希函数“尽量简单”。然而对于各种取值的关键码而言,一个好的哈希函数通常只能减少碰撞发生的次数,无法保证绝对不产生碰撞。因此散列除去要选择适当的哈希函数以外,还要研究发生碰撞时如何解决,即用什么方法存储同义词。

7、负载因子

我们把h(key)的值域所对应到的地址空间称为“基本区域”,发生碰撞时,同义词可以存放在基本区域还没有被占用的单元里,也可以放到基本区域以外另开辟的区域中(称为“溢出区”)。下面

引入散列的一个重要参数“负载因子或装填因子(Load Factor)”,它定义为:

а=

负载因子的大小对于碰撞的发生频率影响很大。直观上容易想象,а越大,散列表装得越满,则再要载入新的结点时碰上已有结点的可能性越大,冲突的机会也越大。特别当а>1时碰撞是不可避免的。一般总是取а<1,即分配给散列表的基本区域大于所有结点所需要的空间。当然分配的基本区域太大了也是浪费。例如,某校学生干部的登记表,每个学生干部是一个结点,用学号做关键码,每个学号用7位数字表示,如果分配给这个散列表的基本区域为107个存储单元,那么散列函数就可以是个恒等变换,学号为7801050的学生结点就存入相对地址为7801050的单元,这样一次碰撞也不会发生,但学校仅几百个学生干部,实际仅需要几百个单元的空间,如果占用了107个存储单元,显然太浪费了,所以这是不可取的。负载因子的大小要取得适当,使得既不过多地增加碰撞,有较快的检索速度,也不浪费存储空间。

下面结合引例说明一下上面的思想和方法。

【例1】用散列存储线性表:A=(18,75,60,43,54,90,46)。

分析:

假定选取的散列函数为:h(K)=K mod m,K为元素的关键字,m为散列表的长度,用余数作为存储该元素的散列地址。这里假定K和m均为正整数,并且m要大于等于线性表的长度n。此例n=7,故假定取m=13,则得到的每个元素的散列地址为:h(18)=18 mod 13=5 h(75)=75 mod 13 =10 h(60)=60 mod 13=8

h(43)=43 mod 13=4 h(54)=54 mod 13=2 h(90)=90 mod 13=12

h(46)=46 mod 13=7

根据散列地址按顺序把元素存储到散列表H(0:m-1)中,存储映象为:

0 1 2 3 4 5 6 7

8 9 10 11 12

54 43 18 46 60 75 90

当然这是一个比较理想的情况。假如再往表中插入第8个元素30,h(30)=30 mod 13=4,我们会发现H[4]已经存了43,此时就发生了冲突。我们可以从H[4]往后按顺序找一个空位置存放30,即可以把它插入到H[6]中。

四、哈希函数的构造方法

选择适当的哈希函数是实现散列的重中之重,构造哈希函数有两个标准:简单和均匀。简单是指哈希函数的计算要简单快速;均匀是指对于关键字集合中的任一关键字,哈希函数能以等概率将其映射到表空间的任何一个位置上。也就是说,哈希函数能将子集K随机均匀地分布在表的地址集{0,1,...,m-1}上,以使冲突最小化。

为简单起见,假定关键码是定义在自然数集合上,常见的哈希函数构造方法有:

1、直接定址法

以关键字Key本身或关键字加上某个数值常量C作为散列地址的方法。散列函数为:h(Key)= Key+C,若C为0,则散列地址就是关键字本身。

2、除余法

选择一个适当的正整数m,用m去除关键码,取其余数作为地址,即:h(Key)= Key mod m,这个方法应用的最多,其关键是m的选取,一般选m为小于某个区域长度n的最大素数(如例1中取m=13),为什么呢?就是为了尽力避免冲突。假设取

m=1000 ,则哈希函数分类的标准实际上就变成了按照关键字末三位数分类,这样最多1000类,冲突会很多。一般地说,如果m 的约数越多,那么冲突的几率就越大。

简单的证明:假设m是一个有较多约数的数,同时在数据中存在q满足gcd(m,q)=d >1 ,即有m=a*d,q=b*d,则有以下等式:q mod m= q – m* [q div m] =q – m*[b div a] 。

其中,[b div a]的取值范围是不会超过[0,b]的正整数。也就是说,[b div a]的值只有b+1种可能,而m是一个预先确定的数。因此上式的值就只有b+1种可能了。这样,虽然mod 运算之后的余数仍然在[0,m-1]内,但是它的取值仅限于等式可能取到的那些值。也就是说余数的分布变得不均匀了。容易看出,m的约数越多,发生这种余数分布不均匀的情况就越频繁,冲突的几率越高。而素数的约数是最少的,因此我们选用大素数。记住“素数是我们的得力助手”。

3、数字分析法

常有这样的情况:关键码的位数比存储区域的地址的位数多,在这种情况下可以对关键码的各位进行分析,丢掉分布不均匀的位留下分布均匀的位作为地址。

本方法适用于所有关键字已知,并对关键字中每一位的取值分布情况作出了分析。

【例2】对下列关键码集合(表中左边一列)进行关键码到地址的转换,要求用三位地址。

Key H(Key)

000319426 326

000718309 709

000629443 643

000758615 715

000919697 997

000310329 329

分析:

关键码是9位的,地址是3位的,需要经过数字分析丢掉6位。丢掉哪6位呢?显然前3位是没有任何区分度,第5位1太多、第6位基本都是8和9、第7位都是3、4、5,这几位的区分度都不好,而相对来说,第4、8、9位分布比较均匀,所以留下这3位作为地址(表中右边一列)。

4、平方取中法

将关键码的值平方,然后取中间的几位作为散列地址。具体取多少位视实际要求而定,取哪几位常常结合数字分析法。

【例3】将一组关键字(0100,0110,1010,1001,0111)平方后得(0010000,0012100,1020100,1002001,0012321),若取表长为1000,则可取中间的三位数作为散列地址集:(100,121,201,020,123)。

5、折叠法

如果关键码的位数比地址码的位数多,而且各位分布较均匀,不适于用数字分析法丢掉某些数位,那么可以考虑用折叠法。折叠法是将关键码从某些地方断开,分关键码为几个部分,其中有一部分的长度等于地址码的长度,然后将其余部分加到它的上面,如果最高位有进位,则把进位丢掉。

一般是先将关键字分割成位数相同的几段(最后一段的位数可少一些),段的位数取决于散列地址的位数,由实际需要而定,然后将它们的对应位叠加和(舍去最高位进位)作为散列地址。【例4】如关键码Key=58422241,要求转换为3位的地址码。分析:分如下3段:5 8 4 | 2 2 2 | 4 1,则相加:

5 8 4

2 2 2

4 1

8 4 7

h(Key)=847

6、基数转换法

将关键码值看成在另一个基数制上的表示,然后把它转换成原来基数制的数,再用数字分析法取其中的几位作为地址。一般取大于原来基数的数作转换的基数,并且两个基数要是互质的。如:key=(236075)10是以10为基数的十进制数,现在将它看成是以13为基数的十三进制数(236075)13,然后将它转换成十进制数。

(236075)13=2*135+3*134+6*133+7*13+5

=(841547)10

再进行数字分析,比如选择第2,3,4,5位,于是h(236075)=4154

五、哈希表支持的运算

哈希表支持的运算主要有:初始化(makenull)、哈希函数值的运算(h(x))、插入元素(insert)、查找元素(member)。设插入元素的关键字为x ,A 为哈希表,则各种运算过程如下:

1、初始化比较容易,例如:

const empty=maxlongint; {用非常大的整数代表这个位置没有存储元素}

p=9997; {根据需要设定的表的大小} procedure makenull;

var i:integer;

begin

for i:=0 to p-1 do A[i]:=empty;

End;

2、哈希函数值的运算,根据函数的不同而变化,例如除余法的一个例子:

function h(x:longint):Integer;

begin

h:= x mod p;

end;

3、我们注意到,插入和查找首先都需要对这个元素定位,因此加入一个定位的函数locate:

function locate(x:longint):integer;

var orig,i:integer;

begin

orig:=h(x);

i:=0;

while (i

P]<>x)and(A[(orig+i)mod P]<>empty) do inc(i);

{当这个循环停下来时,要么找到一个空的存储单元,

要么找到这个元素存储的单元,要么表已经满了}

locate:=(orig+i) mod P;

end;

4、插入元素:

procedure insert(x:longint);

var posi:integer;

begin

posi:=locate(x); {定位函数的返回值}

if A[posi]=empty then A[posi]:=x

else error; {error 即为发生了错误,当然这是可以避免的}

end;

5、查找元素是否已经在表中:

procedure member(x:longint):boolean;

var pos:integer;

begin

pos:=locate(x);

if A[pos]=x then member:=true

else member:=false;

end;

哈希表的设计与实现 课程设计报告

一: 需求分析 (2) 三: 详细设计(含代码分析) (4) 1.程序描述: (4) 2具体步骤 (4) 四调试分析和测试结果 (7) 五,总结 (9) 六.参考文献; (10) 七.致谢 (10) 八.附录 (11)

一: 需求分析 问题描述:设计哈希表实现电话号码查询系统。 基本要求 1、设每个记录有下列数据项:电话号码、用户名、地址 2、从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表; 3、采用再哈希法解决冲突; 4、查找并显示给定电话号码的记录; 5、查找并显示给定用户名的记录。 6、在哈希函数确定的前提下,尝试各种不同类型处理冲突的方法(至少 两种),考察平均查找长度的变化。 二: 概要设计 进入主函数,用户输入1或者2,进入分支选择结构:选1:以链式方法建立哈希表,选2:以再哈希的方法建立哈希表,然后用户输入用户信息,分别以上述确定的方法分别以用户名为检索以及以以电话号码为检索将用户信息添加到哈希表,.当添加一定量的用户信息后,用户接着输入用户名或者电话号码分别以用户名或者电话号码的方式从以用户名或电话号码为检索的哈希表查找用户信息.程序用链表的方式存储信息以及构造哈希表。 具体流程图如下所示:

三: 详细设计(含代码分析) 1.程序描述: 本程序以要求使用哈希表为工具快速快速查询学生信息,学生信息包括电话号码、用户名、地址;用结构体存储 struct node { string phone; //电话号码 string name; //姓名 string address;//地址 node *next; //链接下一个地址的指针 }; 2具体步骤 1. 要求主要用在哈希法解决冲突,并且至少尝试用两种方法解决冲突,定义两个指针数组存储信息node *infor_phone[MAX]; node *infor_name[MAX];前者以电话号码为关键字检索哈希表中的信息,后者以姓名为关键字检索哈希表中的信息 用链式法和再哈希法解决冲突: int hash(string key) //以姓名或者电话号码的前四位运算结果作为哈{ //希码 int result=1,cur=0,i; if(key.size()<=4) i=key.size()-1; else i=4; for(;i>=0;i--) { cur=key[i]-'0'; result=result*9+cur; } result%=(MOD); return result;

哈希表应用

附件4: 北京理工大学珠海学院 课程设计任务书 2010 ~2011学年第二学期 学生姓名:专业班级: 指导教师:工作部门: 一、课程设计题目 哈希表应用 二、课程设计内容(含技术指标) 【问题描述】 利用哈希表进行存储。 【任务要求】 任务要求:针对一组数据进行初始化哈希表,可以进行显示哈希表,查找元素,插入元素,删除元素,退出程序操作。 设计思想:哈希函数用除留余数法构造,用线性探测再散列处理冲突。 设计目的:实现哈希表的综合操作 简体中文控制台界面:用户可以进行创建哈希表,显示哈希表,查找元素,插入元素,删除元素。 显示元素:显示已经创建的哈希表。 查找元素:查找哈希表中的元素,分为查找成功和查找不成功。 插入元素:在哈希表中,插入一个元素,分为插入成功和失败。 删除元素:在已有的数据中,删除一个元素。 退出系统:退出程序。 【测试数据】 自行设定,注意边界等特殊情况。

三、进度安排 1.初步设计:写出初步设计思路,进行修改完善,并进行初步设计。 2.详细设计:根据确定的设计思想,进一步完善初步设计内容,按要求编写出数据结构类型定义、各算法程序、主函数。编译分析调试错误。 3.测试分析:设计几组数据进行测试分析,查找存在的设计缺陷,完善程序。 4.报告撰写:根据上面设计过程和结果,按照要求写出设计报告。 5.答辩考核验收:教师按组(人)检查验收,并提出相关问题,以便检验设计完成情况。 四、基本要求 1.在设计时,要严格按照题意要求独立进行设计,不能随意更改。若确因条件所限,必须要改变课题要求时,应在征得指导教师同意的前提下进行。 2.在设计完成后,应当场运行和答辩,由指导教师验收,只有在验收合格后才能算设计部分的结束。 3.设计结束后要写出课程设计报告,以作为整个课程设计评分的书面依据和存档材料。设计报告以规定格式的电子文档书写、打印并装订,报告格式严格按照模板要求撰写,排版及图、表要清楚、工整。 从总体来说,所设计的程序应该全部符合要求,问题模型、求解算法以及存储结构清晰;具有友好、清晰的界面;设计要包括所需要的辅助程序,如必要的数据输入、输出、显示和错误检测功能;操作使用要简便;程序的整体结构及局部结构要合理;设计报告要符合规范。 课程负责人签名: 年月日

通讯录管理系统的设计与实现精选文档

通讯录管理系统的设计与实现精选文档 TTMS system office room 【TTMS16H-TTMS2A-TTMS8Q8-

大连民族大学 计算机科学与工程学院实验报告 实验题目:1. 学生信息管理系统的设计与实现 2. 暴力算法在旅行商问题中的应用 课程名称:信息系统开发案例 实验类型:□演示性□验证性□操作性□设计性综合性 专业:软件工程班级:144 学生姓名:赵耀学号:30 实验日期:2017年3月6日—4月27日 实验地点:金石滩校区I303机房 实验学时:24学时实验成绩: 指导教师:赵戈

通讯录管理系统的设计与实现 摘要 本项目用C++语言开发了一个简单的通讯录管理系统,该系统能对联系人 信息进行“增删改查”。系统的UI设计基于Windows系统自带的控制台。测试结 果表明该通讯录管理系统可以稳定正确运行,具有较高的可靠性。 关键词:通讯录管理系统;C++语言;Windows 控制台 目录

1.选题的背景和意义 当今时代,计算机已经成为人们生活中不可或缺的一部分,它打破了地域时间限制,改变了人们的工作和生活方式。人们之间的联系越来越便捷,这就使得要经常与很多人保持着联系,而单纯依靠人脑已经很难记住所有人的联系方式还有其各做附加信息。通讯录系统能方便用户的需求,满足用户迅速、准确的查找修改或者删除联系人信息,把各个联系人信息以文件保存。本文介绍了c++编写简易通讯录管理:系统的分析,功能模块的设计,系统的流程图及运行界面。此系统的主要管理的信息由:联系人的姓名、性别、电话号码,加深对c++语言程序设计的理解,提高算法设计的能力,锻炼编程的能力。用c 语言编程一个通讯录管理系统软件,要求能实现通讯录管理系统中的增加信息,删除信息,显示通讯里的所有信息,按名字查询信息,保存通讯录,退出系统。。 2.需求分析 用例图 通讯录管理系统的用例图如下图所示:

数据结构课程设计哈希表设计问题复习过程

数据结构课程设计哈希表设计问题

目录 1 前言 (1) 2 需求分析 (1) 2.1 任务和要求 (1) 2.2 运行环境 (1) 2.3 开发工具 (1) 3 分析和设计 (2) 3.1 系统分析及设计思路 (2) 3.2 主要数据结构及算法 (2) 3.3 函数流程图 (2) (1)哈希表的创建及初始化流程图 (2) 5 课程设计总结 (13) 5.1 程序运行结果或预期运行结果 (13) 说明:输入的数为30个姓的拼音,查找的为“pan”,输出的如上图所示。 (14) 5.2 设计结论 (15) 参考文献 (15) 致谢 (15)

1 前言 从C语言产生到现在,它已经成为最重要和最流行的编程语言之一。在各种流行编程语言中,都能看到C语言的影子,如Java的语法与C语言基本相同。学习、掌握C语言是每一个计算机技术人员的基本功之一。 根据本次课程设计的要求,我设计小组将编写一个C语言程序来处理哈希表问题,通过这个程序,将针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。 2 需求分析 2.1 任务和要求 针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。 要求:假设人名为中国姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造,用链表法处理冲突。 2.2 运行环境 (1)WINDOWS2000/XP系统 (2)Visual C++ 6.0编译环境或TC编译环境 2.3 开发工具 C语言

3 分析和设计 3.1 系统分析及设计思路 (1)创建哈希表 (2)姓名(结构体数组)初始化 (1)用除留余数法构建哈希函数 (2)用链表法处理冲突 (3)查找哈希表 在哈希表中进行查找,输出查找的结果和关键字,并计算和输出查找成功的平均查找长度 (4) 显示哈希表 显示哈希表的的格式: 3.2 主要数据结构及算法 定义结构体typedef struct hashtable创建哈希表 定义函数Hash_Init(HashTable ht)来对哈希表初始化 定义函数Hash_Insert(HashTable ht, Node *node)来为哈希表分配地址 定义函数Hash_Init(ht)输入30个名字 定义函数Hash_Create(HashTable ht)来求哈希表长度 定义函数hash_output(HashTable h)来输出哈希表 定义函数Hash_Link()构造链表函数 定义函数int hash_search(int h[],int key)查找输入的名字 3.3 函数流程图 (1)哈希表的创建及初始化流程图

该程序实现的哈希表构造哈希函数的方法为除留余数法(

一、该程序实现的哈希表:构造哈希函数的方法为除留余数法(函数modhash),处理哈希冲突的方法为链地址法。 二、对哈希表的操作:插入(函数hash_table_insert)、移除(函数hash_table_remove)、 查找(函数hash_table_lookup)、整个哈希表的释放(函数hash_table_delete)、 整个哈希表的输出(函数hash_table_print)。 三、哈希表的最大长度可以由HASHMAXLEN设置(我设为1000)。 四、输入哈希表的名称拼音字符是长度为10—20(长度可由STR_MAX_LEN和STR_MIN_LEN)的小写字母组成。这些名字字符串是我用函数rand_str随机产生的。 五、名称拼音字符(关键字)到关键字值的转换方法:先把名称的拼音字符转换对应的ASCII,累加后作为关键字值。我是用函数str_to_key实现的。 六、异常情况包括: 1、在对哈希表进行插入操作时,若哈希表的实际长度超过了哈希表的最大长度,我就输出“out of hash table memory!”,然后直接跳出插入子函数,不进行插入操作。 2、在对哈希表进行插入操作时,若插入的元素在哈希表中已经存在,我就输出“******already exists !”,然后直接跳出插入子函数,不进行插入操作。 3、在对哈希表进行查找操作时,若查到则返回其地址,若没查到则返回空地址。 4、在对哈希表进行移除操作时,对同义词元素的删除,分为表头和表中两种情况处理。 七、开发平台:DEV-C++,用c语言实现。 在哈希表程序中我比较注重整个代码风格,希望能形成很好的代码风格!如果有什么可以改进的,希望老师能跟我说说!

数据结构课设-通讯录系统的设计与实现——哈希表

课程设计(论文)任务书 软件学院学院软件工程专业班 一、课程设计(论文)题目:通讯录管理系统的设计与实现——哈希表 二、课程设计(论文)工作自2016 年 1 月 4 日起至 2016 年 1 月 10 日止 三、课程设计(论文) 地点: 软件测试中心(北区测试二室) 四、课程设计(论文)内容要求: 1.本课程设计的目的 ⑴训练学生灵活应用所学数据结构知识,独立完成问题分析,结合课程的理论知识,编写程序求解指定问题; ⑵初步掌握软件开发过程的问题分析、系统设计、编码、测试等基本方法和技能; ⑶提高综合运用所学的理论知识和方法独立分析和解决问题的能力,巩固、深化学生的理论知识,提升编程水平。 2.课程设计的任务及要求 1)基本要求: ⑴要求从分析题目的需求入手,按设计抽象数据类型、构思算法、通过设计实现抽象数据类型、编写上机程序和上机调试等若干步骤完成题目,最终写出完整的报告; ⑵在程序设计阶段应尽量利用已有的标准函数,加大代码的重用率; ⑶程序设计语言推荐使用C/C++,程序书写规范,源程序需加必要的注释; ⑷每位同学需提交可独立运行的程序和规范的课程设计报告。 2)课程设计论文编写要求 ⑴理论设计部分以课程设计论文的形式提交,格式必须按照课程设计论文标准格式进行书写和装订; ⑵课程设计报告包括中文目录、设计任务、需求分析、概要设计、详细设计、编码实现、调试分析、课设总结、谢辞、参考文献、附录等; ⑶设计部分应包含系统功能模块图,调试分析应包括运行截图等。 3)课程设计评分标准: ⑴学习态度:10分; ⑵系统设计:20分; ⑶编程调试:20分; ⑷回答问题:20分; ⑸论文撰写:30分。

散列表(哈希表)

1. 引言 哈希表(Hash Table)的应用近两年才在NOI(全国青少年信息学奥林匹克竞赛)中出现,作为一种高效的数据结构,它正在竞赛中发挥着越来越重要的作用。 哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。然而在当前可利用内存越来越多的情况下,用空间换时间的做法是值得的。另外,编码比较容易也是它的特点之一。 哈希表又叫做散列表,分为“开散列” 和“闭散列”。考虑到竞赛时多数人通常避免使用动态存储结构,本文中的“哈希表”仅指“闭散列”,关于其他方面读者可参阅其他书籍。 2. 基础操作 2.1 基本原理 我们使用一个下标范围比较大的数组来存储元素。可以设计一个函数(哈希函数,也叫做散列函数),使得每个元素的关键字都与一个函数值(即数组下标)相对应,于是用这个数组单元来存储这个元素;也可以简单的理解为,按照关键字为每一个元素“分类”,然后将这个元素存储在相应“类”所对应的地方。 但是,不能够保证每个元素的关键字与函数值是一一对应的,因此极有可能出现对于不同的元素,却计算出了相同的函数值,这样就产生了“冲突”,换句话说,就是把不同的元素分在了相同的“类”之中。后面我们将看到一种解决“冲突”的简便做法。 总的来说,“直接定址”与“解决冲突”是哈希表的两大特点。 2.2 函数构造 构造函数的常用方法(下面为了叙述简洁,设h(k) 表示关键字为k 的元素所对应的函数值): a) 除余法: 选择一个适当的正整数p ,令h(k ) = k mod p ,这里,p 如果选取的是比较大

的素数,效果比较好。而且此法非常容易实现,因此是最常用的方法。 b) 数字选择法: 如果关键字的位数比较多,超过长整型范围而无法直接运算,可以选择其中数字分布比较均匀的若干位,所组成的新的值作为关键字或者直接作为函数值。 2.3 冲突处理 线性重新散列技术易于实现且可以较好的达到目的。令数组元素个数为S ,则当h(k)已经存储了元素的时候,依次探查(h(k)+i) mod S , i=1,2,3…… ,直到找到空的存储单元为止(或者从头到尾扫描一圈仍未发现空单元,这就是哈希表已经满了,发生了错误。当然这是可以通过扩大数组范围避免的)。 2.4 支持运算 哈希表支持的运算主要有:初始化(makenull)、哈希函数值的运算(h(x))、插入元素(i nsert)、查找元素(member)。设插入的元素的关键字为x ,A 为存储的数组。初始化比较容易,例如: const empty=maxlongint; // 用非常大的整数代表这个位置没有存储元素 p=9997; // 表的大小 procedure makenull; var i:integer; begin for i:=0 to p-1 do A[i]:=empty; End; 哈希函数值的运算根据函数的不同而变化,例如除余法的一个例子:

哈希表查询设计及实现

/* (1)设计哈希表,该表应能够容纳50个英文单词。 (2)对该哈希表进行查询,实现对特定单词的快速查询,并显示经过的节点内容 已经发到你邮箱里了enochwills@https://www.wendangku.net/doc/7618862659.html, */ #include #include #include #include #include #define szNAME 80 #define HASH_ROOT 47 /*用于计算哈希地址的随机数*/ #define szHASH 50 /*哈希表总长度*/ #define POPULATION 30 /*学生总数*/ /*哈希表结构体*/ struct THash { int key; /*钥匙码*/ char name[10]; /*姓名*/ int depth; /*检索深度*/ }; /*根据钥匙码和哈希根计算哈希地址*/ int GetHashAddress(int key, int root) { return key % root; }/*end GetHashAddress*/ /*冲突地址计算,如果发现地址冲突,则用当前地址和钥匙码、哈希根重新生成一个新地址*/ int GetConflictAddress(int key, int address, int root) { int addr = address + key % 5 + 1; return addr % root; }/*end GetConflictAddress*/ /*根据字符串生成哈希钥匙码,这里的方法是将串内所有字符以数值形式求累加和*/ int CreateKey(char * name) { int key = 0; unsigned char * n = (unsigned char *)name; while(*n) key += *n++; return key; }/*end CreateKey*/ /*输入一个名字,并返回哈希钥匙码*/ int GetName(char * name) { scanf("%s", name); return CreateKey(name); }/*end CreateKey*/ /*根据学生人数、长度和哈希根构造哈希表*/ struct THash * CreateNames(int size, int root, int population) { int i =0, key = 0, addr = 0, depth = 0; char name[10]; struct THash * h = 0, *hash = 0; /*哈希根和长度不能太小*/ if(size < root || root < 2) return 0; /*根据哈希表长度构造一个空的哈希表*/ hash = (struct THash *)malloc(sizeof(struct THash) * size); /*将整个表清空*/ memset(hash, 0, sizeof(struct THash) * size); for(i = 0; i < population; i++) { /*首先产生一个随机的学生姓名,并根据姓名计算哈希钥匙码,再根据钥匙码计算地址*/ key = GetName(name); addr = GetHashAddress(key, root); h = hash + addr; if (h->depth == 0) { /*如果当前哈希地址没有被占用,则存入数据*/ h->key = key; strcpy(h->name , name); h->depth ++; continue; }/*end if*/ /*如果哈希地址已经被占用了,就是说有冲突,则寻找一个新地址,直到没有被占用*/ depth = 0; while(h->depth ) { addr = GetConflictAddress(key, addr, root); h = hash + addr; depth ++; }/*end while*/ /*按照新地址存放数据,同时记录检索深度*/ h->key = key; strcpy(h->name , name); h->depth = depth + 1; }/*next*/ return hash; }/*end CreateNames*/ /*在哈希表中以特定哈希根查找一个学生的记录*/ struct THash * Lookup(struct THash * hash, char * name, int root) { int key = 0, addr = 0; struct THash * h = 0; /*不接受空表和空名称*/ if(!name || !hash) return 0; key = CreateKey(name); addr = GetHashAddress(key, root); h = hash + addr; /*如果结果不正确表示按照冲突规则继续寻找*/ while(strcmp(h->name , name)) { addr = GetConflictAddress(key, addr, root); h = hash + addr; if(h->key == 0) return 0; }/*end while*/ return hash + addr; }/*end Lookup*/ /*根据一条哈希表记录打印该记录的学生信息*/ void Print(struct THash * record) { if (!record) { printf("【查无此人】\n"); return ; }/*end if*/ if(record->depth) printf("【钥匙码】%04d\t【姓名】%s\t【检索深度】%d\n", record->key, record->name, record->depth ); else printf("【空记录】\n"); /*end if*/ }/*end Print*/ /*打印学生花名册*/ void Display(struct THash * hash, int size) { struct THash * h = 0; if (!hash || size < 1) return ; printf("学生花名册:\n"); printf("--------------------\n"); for(h = hash; h < hash + size; h++) { printf("【地址】%d\t", h - hash); Print(h); }/*next*/ printf("--------------------\n"); }/*end Display*/ /*主函数,程序入口*/ int main(void) { /*哈希表变量声明*/ struct THash * hash = 0, * h = 0; int cmd = 0; /*命令*/ char name[10]; /*学生姓名*/ /*生成30个学生用的哈希表*/ hash =

哈希表基本操作

一,哈希表(Hashtable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似key/value的键值对,其中key通常可用来快速查找,同时key是区分大小写;value用于存储对应于key的值。Hashtable中key/value键值对均为object 类型,所以Hashtable可以支持任何类型的key/value键值对. 二,哈希表的简单操作 在哈希表中添加一个key/value键值对:HashtableObject.Add(key,value); 在哈希表中去除某个key/value键值对:HashtableObject.Remove(key); 从哈希表中移除所有元素:HashtableObject.Clear(); 判断哈希表是否包含特定键key:HashtableObject.Contains(key); 下面控制台程序将包含以上所有操作: using System; using System.Collections; //使用Hashtable时,必须引入这个命名空间 class hashtable { public static void Main() { Hashtable ht=new Hashtable(); //创建一个Hashtable实例 ht.Add("E","e");//添加key/value键值对 ht.Add("A","a"); ht.Add("C","c"); ht.Add("B","b"); string s=(string)ht["A"]; if(ht.Contains("E")) //判断哈希表是否包含特定键,其返回值为true或false Console.WriteLine("the E key:exist"); ht.Remove("C");//移除一个key/value键值对 Console.WriteLine(ht["A"]);//此处输出a ht.Clear();//移除所有元素 Console.WriteLine(ht["A"]); //此处将不会有任何输出 } } 三,遍历哈希表 遍历哈希表需要用到DictionaryEntry Object,代码如下: for(DictionaryEntry de in ht) //ht为一个Hashtable实例 { Console.WriteLine(de.Key);//de.Key对应于key/value键值对key Console.WriteLine(de.Value);//de.Key对应于key/value键值对value

哈希表实现通讯录-数据结构与算法课程设计报告

合肥学院 计算机科学与技术系 课程设计报告 2009~2010学年第二学期 课程数据结构与算法 课程设计名称哈希表实现通讯录

题目:(哈希表的设计与实现的问题) 设计哈希表实现电话号码查询系统。设计程序完成以下要求:(1)设每个记录有下列数据项:电话号码、用户名、地址;(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;(3)采用再哈希法解决冲突;(4)查找并显示给定电话号码的记录;(5)查找并显示给定用户的记录。 一、问题分析和任务定义 此程序需要完成如下要求:设计哈希表实现电话号码查询系统。 实现本程序需要解决以下几个问题: (1)设计结点使该结点包括电话号码、用户名、地址。 (2)利用再哈希法解决冲突。 (3)分别以电话号码和用户名为关键字建立哈希表。 (4)实现查找并显示给定电话号码的记录。 (5)查找并显示给定用户的记录。 本问题的关键和难点在于如何解决散列的问题。由于结点的个数无法的知,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。所以采用链地址法散列算法。采用拉链法,当出现同义词冲突时,使用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。 首先,解决的是定义链表结点,在拉链法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成.name[8] 、num[11]和address[20]都是char浮点型,输入输出都只能是浮点型的。 采用拉链法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。这些表头结点组成一个一维数组,即哈希表。数组元素的下标对应由散列函数求出的散列地址。 其次,设计散列函数,本程序需要设计两个散列函数才能解决问题,程序需要分别为以电话号码和用户名为关键字建立哈希表。所以要分别以用户名、号码为关键字建立两个散列函数, 对于以号码为关键字的散列函数,是将十一个数字全部相加,然后对20求余。得到的数作为地址。对于以用户名为关键字的散列函数,是将所有字母的ASCLL码值相加,然后对20求余。 再次,需要实现添加结点的功能,则其中必须包括一个输入结点信息、添加结点的函数;需要实现查找函数,则必须包括一个查找结点的函数;需要对文件进行保存,则必需要包括保存文件函数。还需要包括一个主菜单和一个主函数。 最后,当程序设计出来后的测试数据为:

哈希表查找的设计

哈希表查找的设计 一.问题描述: 哈希表查找的设计:设哈希表长为20,用除留余数法构造一个哈希函数,以开放定址法中的线性探测再散列法作为解决冲突的方法,编程实现哈希表查找、插入和建立算法。二.需求分析: 程序可实现用户与计算机的交互过程。在计算机显示提示信息后,可由用户键入运算命令以实现对应的功能,包含数据的录入、查找、删除、显示等功能。 本程序旨在实现哈希函数的构造与处理存储冲突,因而指定哈希表存储的数据类型为简单的整型数字,在实用性上还有所欠缺。但根据用户需求的变化,可以对程序的基本数据类型进行改造,以实现更为丰富的功能,进而体现哈希表在查找数据时的优越性。 三.算法思想: 在设定哈希表的抽象数据类型时,要有查找数据元素的操作。另外,插入操作和删除操作也要用到查找数据元素操作,以查看该数据元素是否存在,因此可以设计查找元素操作包括插入和删除操作的查找。 因此,查找操作就有两种情况:一种情况是插入操作时寻找空闲单元的查找;另一种情况是在查找和删除操作时寻找该元素是否在哈希表中已存在的查找。插入操作时寻找空闲单元查找的特征是哈希表中不存在该对象,设计此时查找函数返回该空闲单元位置的“正”值;查找和删除操作时寻找该元素是否在哈希表中已存在的特征是哈希表中已存在该数据元素,设计此时查找函数返回该数据单元位置的“负”值。进而执行后续操作。 为了区分哈希表中每一个表元素的当前状态,为每一个表元素设置一个“标志”定为tag。tag=0表示该元素为空;tag=1表示该元素以存放有数据元素;tag=-1表示该元素中存放的数据元素已被删除。判断当tag为0或-1时都可以进行插入操作。

通讯录管理系统的设计与实现

大连民族大学 计算机科学与工程学院实验报告 实验题目: 1. 学生信息管理系统的设计与实现 2. 暴力算法在旅行商问题中的应用 课程名称:信息系统开发案例 实验类型:□演示性□验证性□操作性□设计性 综合性 专业:软件工程班级:144 学生姓名:赵耀学号:2014082430 实验日期:2017年3月6日—4月27日 实验地点:金石滩校区I303机房 实验学时:24学时实验成绩: 指导教师:赵戈

通讯录管理系统的设计与实现 摘要 本项目用C++语言开发了一个简单的通讯录管理系统,该系统能对联系人信 息进行“增删改查”。系统的UI设计基于Windows系统自带的控制台。测试结 果表明该通讯录管理系统可以稳定正确运行,具有较高的可靠性。 关键词:通讯录管理系统;C++语言;Windows 控制台 目录 1.选题的背景和意义 (3) 2.需求分析 (3) 2.1 用例图 (3) 2.2 用例文本 (4) 3.总体设计 (5) 3.1 通讯录管理系统功能模块图 (5) 3.2 主控main函数执行流程图 (6) 3.3 执行流程图的解释说明 (6) 3.4 存储结构设计 (7) 4.详细设计 (8) 5程序运行结果 (9) 6总结和展望 (9) 7附录 (10) 程序源代码: (10)

1.选题的背景和意义 当今时代,计算机已经成为人们生活中不可或缺的一部分,它打破了地域时间限制,改变了人们的工作和生活方式。人们之间的联系越来越便捷,这就使得要经常与很多人保持着联系,而单纯依靠人脑已经很难记住所有人的联系方式还有其各做附加信息。通讯录系统能方便用户的需求,满足用户迅速、准确的查找修改或者删除联系人信息,把各个联系人信息以文件保存。本文介绍了c++编写简易通讯录管理:系统的分析,功能模块的设计,系统的流程图及运行界面。此系统的主要管理的信息由:联系人的姓名、性别、电话号码,加深对c++语言程序设计的理解,提高算法设计的能力,锻炼编程的能力。用c语言编程一个通讯录管理系统软件,要求能实现通讯录管理系统中的增加信息,删除信息,显示通讯里的所有信息,按名字查询信息,保存通讯录,退出系统。。 2.需求分析 2.1 用例图 通讯录管理系统的用例图如下图所示: 图2.1 用例图

哈希表设计数据结构课程设计

哈希表设计数据结构课程设计

实习6、哈希表设计 一、需求分析 1. 问题描述 针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度均不超过R,完成相应的建表和查表顺序。 2. 基本要求 假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突。 3. 测试数据 取读者周围较熟悉的30个人的姓名。 4. 实现提示 如果随机数自行构造,则应首先调整好随机函数,使其分布均匀。人名的长度均不超过19个字符(最长的人名如:庄双双(Zhuang Shuangshuang))。字符的取码方法可直接利用C语言中的toascii函数,并可先对过长的人名先作折叠处理。 二、概要设计 ADT Hash { 数据对象D:D是具有相同特征的数据元素的集合。各数据元素均含有类型相同,可唯一标识数据元素的关键

字。 数据关系R:数据元素同属一个集合。 InitNameTable() 操作结果:初始化姓名表。 CreateHashTable() 操作结果:建立哈希表。 DisplayNameTable() 操作结果:显示姓名表。 DisplayHashTable() 操作结果:显示哈希表。 FindName() 操作结果:查找姓名。 }ADT Hash 三、详细设计(源代码) (使用C语言) #include #include//time用到的头文件 #include//随机数用到的头文件 #include//toascii()用到的头文件 #include//查找姓名时比较用的头文件#define HASH_LEN 50//哈希表的长度

哈希表设计-数据结构课程设计

实习6、哈希表设计 一、需求分析 1. 问题描述 针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度均不超过R,完成相应的建表和查表顺序。 2. 基本要求 假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突。 3. 测试数据 取读者周围较熟悉的30个人的姓名。 4. 实现提示 如果随机数自行构造,则应首先调整好随机函数,使其分布均匀。人名的长度均不超过19个字符(最长的人名如:庄双双(Zhuang Shuangshuang))。字符的取码方法可直接利用C 语言中的toascii函数,并可先对过长的人名先作折叠处理。 二、概要设计 ADT Hash { 数据对象D:D是具有相同特征的数据元素的集合。各数据元素均含有类型相同,可唯一标识数据元素的关键字。 数据关系R:数据元素同属一个集合。 InitNameTable() 操作结果:初始化姓名表。 CreateHashTable() 操作结果:建立哈希表。 DisplayNameTable() 操作结果:显示姓名表。 DisplayHashTable() 操作结果:显示哈希表。 FindName() 操作结果:查找姓名。 }ADT Hash 三、详细设计(源代码) (使用C语言) #include #include//time用到的头文件 #include//随机数用到的头文件 #include//toascii()用到的头文件 #include//查找姓名时比较用的头文件 #define HASH_LEN 50//哈希表的长度 #define P 47//小于哈希表长度的P #define NAME_LEN 30//姓名表的长度 typedef struct {//姓名表 char *py; //名字的拼音 int m; //拼音所对应的 }NAME; NAME NameTable[HASH_LEN]; //全局定义姓名表 typedef struct {//哈希表 char *py; //名字的拼音

Delphi 使用哈希表 (键值对 key)

Delphi 使用哈希表(键值对key) 以往在软件开发中经常需要用哈希表保存一些数据结构,C#下的哈希表可以快速检索数据,其实Delphi也提供了对哈希表的支持,下面我就将我在用Delphi开发中使用Hash表的方法写出来,希望对大家有一定的帮助! 在Borland Delphi中有一个THashedStringlist类,使用这个类可以实现Hash表的操作.使用这个类需要引用IniFiles单元. 例如:我们定义的数据结构是: 以下是引用片段: MyHashTest = record Key:Integer; Name:String[20]; Sex:Boolean; Age:Integer; end; PTest = ^MyHashTest ; 1:创建Hash表. ScHash:=THashedStringlist.Create; 2:将数据结构加入Hash表中. var

Index:Integer; p_Test:PTest; Index:=ScHash.IndexOf(IntToStr(p_Test.Key)); if Index=-1 then begin ScHash.AddObject(IntToStr(p_Test.Key),TObject(Integer( p_Test))); end; 在加入Hash表的时候,首先我们检查看这个Key是否在Hash表中,如果Index=-1则说明此Key不在Hash表中,则我们将这个结构指针加入到Hash表中. 3:将数据结构从Hash表中删除. 以下是引用片段: var Index:Integer; t_Object: TObject; Index:=ScHash.IndexOf(IntToStr(p_Test.Key)); if Index -1 then begin t_Object:=ScHash.Objects[Index]; ScHash.Delete(Index);

哈希表及其应用-课程设计

课程设计题目哈希表及其应用 教学院计算机学院 专业 班级 姓名 指导教师 年月日

课程设计任务书 2010 ~2010 学年第 1 学期 一、课程设计题目哈希表及其应用 二、课程设计内容 建立一个小型信息管理系统(可以是图书、人事、学生、物资、商品等任何信息管理系统)。要求: 1.使用哈希查找表存储信息; 2.实现查找、插入、删除、统计、输出等功能; 三、进度安排 1.初步完成总体设计,搭好框架; 2.完成最低要求:尝试使用多种哈希函数和冲突解决方法,并通过实际运行测试给出自己的评价 四、基本要求 1.界面友好,函数功能要划分好 2.程序要加必要的注释 3.要提供程序测试方案 教研室主任签名: 年月日

1 概述 (4) 2 设计目的 (4) 3 设计功能说明 (4) 4 详细设计说明 (5) 5 流程图 (5) 6 程序代码 (6) 7 程序运行结果 (15) 8 总结 (19) 参考文献 (19) 成绩评定表 (20)

数据结构是一门理论性强、思维抽象、难度较大的课程,是基础课和专业课之间的桥梁,只有进行实际操作,将理论应用于实际中,才能确实掌握书中的知识点。通过课程设计,不仅可以加深学生对数据结构基本概念的了解,巩固学习成果,还能够提高实际动手能力。为学生后继课程的学习打下良好的基础。 2 设计目的 《数据结构》课程设计是在教学实践基础上进行的一次大型实验,也是对该课程所学理论知识的深化和提高。因此,要求学生能综合应用所学知识,设计与制造出具有较复杂功能的应用系统,并且在实验的基本技能方面上进行一次全面的训练。通过程序的编译掌握对程序的调试方法及思想,并且让学生学会使用一些编程技巧。促使学生养成良好的编程习惯。 1.使学生能够较全面地巩固和应用课堂中所学的的基本理论和程序设计方法,能够较熟练地完成程序的设计和调试。 2.培养学生综合运用所学知识独立完成程序课题的能力。 3.培养学生勇于探索、严谨推理、实事求是、有错必改,用实践来检验理论,全方位考虑问题等科学技术人员应具有的素质。 4.提高学生对工作认真负责、一丝不苟,对同学团结友爱,协作攻关的基本素质。 5.培养学生从资料文献、科学实验中获得知识的能力,提高学生从别人经验中找到解决问题的新途径的悟性,初步培养工程意识和创新能力。 6.对学生掌握知识的深度、运用理论去处理问题的能力、实验能力、课程设计能力、书面及口头表达能力进行考核。 3 设计功能分析 本设计的功能如下: 1、利用哈希函数来实现一个小型信息管理系统,其中信息包含用户名,地址,电话等。 2、能添加用户信息,并能保存该信息。 3、查询管理系统中的信息:可通过姓名查找,也可通过电话查找等两种方式。

数据结构课程设计--哈希表实验报告

福建工程学院 课程设计 课程:算法与数据结构 题目:哈希表 专业:网络工程 班级:xxxxxx班 座号:xxxxxxxxxxxx 姓名:xxxxxxx 2011年12 月31 日 实验题目:哈希表 一、要解决的问题 针对同班同学信息设计一个通讯录,学生信息有姓名,学号,电话号码等。以学生姓名为关键字设计哈希表,并完成相应的建表和查表程序。 基本要求:姓名以汉语拼音形式,待填入哈希表的人名约30个,自行设计哈希函数,用线性探测再散列法或链地址法处理冲突;在查找的过程中给出比较的次数。完成按姓名查询的操作。 运行的环境:Microsoft Visual C++ 6.0 二、算法基本思想描述 设计一个哈希表(哈希表内的元素为自定义的结构体)用来存放待填入的30个人名,人名为中国姓名的汉语拼音形式,用除留余数法构造哈希函数,用线性探查法解决哈希冲突。建立哈希表并且将其显示出来。通过要查找的关键字用哈希函数计算出相应的地址来查找人名。通过循环语句调用数组中保存的数据来显示哈希表。 三、设计 1、数据结构的设计和说明 (1)结构体的定义 typedef struct //记录 { NA name; NA xuehao; NA tel; }Record;

{ Record *elem[HASHSIZE]; //数据元素存储基址 int count; //当前数据元素个数 int size; //当前容量 }HashTable; 哈希表元素的定义,包含数据元素存储基址、数据元素个数、当前容量。 2、关键算法的设计 (1)姓名的折叠处理 long fold(NA s) //人名的折叠处理 { char *p; long sum=0; NA ss; strcpy(ss,s); //复制字符串,不改变原字符串的大小写 strupr(ss); //将字符串ss转换为大写形式 p=ss; while(*p!='\0') sum+=*p++; printf("\nsum====================%d",sum); return sum; } (2)建立哈希表 1、用除留余数法构建哈希函数 2、用线性探测再散列法处理冲突 int Hash1(NA str) //哈希函数 { long n; int m; n=fold(str); //先将用户名进行折叠处理 m=n%HASHSIZE; //折叠处理后的数,用除留余数法构造哈希函数 return m; //并返回模值 }Status collision(int p,int c) //冲突处理函数,采用二次探测再散列法解决冲突{ int i,q; i=c/2+1; while(i=0) return q; else i=c/2+1; } else{ q=(p-i*i)%HASHSIZE; c++;

相关文档