数据结构-哈希表ppt课件
数据结构之哈希表
实验目的:1.训练与培养解决实际问题的能力2.学会面对一个问题时应该如何分析问题,设计解决方法,实际编码及结果测试。
3.熟悉哈希表的使用4.设计哈希表实现电话号码查询系统。
5.设计程序完成以下要求:(1)设每个记录有下列数据项:电话号码、用户名、地址;(2)从键盘输入各记录,以电话号码为关键字建立哈希表(至少要有12个以上的记录,哈希表的长度为8);(3)采用链地址法解决冲突;(4)显示建立好的哈希表,对于学有余力的同学可以实现哈希表的查找。
实验仪器与设备:计算机实验内容:(1)采用除留余数法进行哈希表的散列,即以电话号码作为主关键字,将电话号码的11位相加,按照模7取余;(2)解决冲突用链地址法。
、(3)实现哈希表的显示与号码的查询实验方法与步骤:1.根据问题进行分析,明确要解决的问题是什么,怎样解决2.根据分析设计问题求解算法3.用特定语言对设计进行编码4.对程序进行测试实验原理:1.对于哈希电话本问题的分析:哈希表问题实际上和图问题一样,先创建一个数组。
在号码存入时,如果数组中哈希关键字位置没有写入号码,则在该处写入,并把该处设置为已写入。
如果该处已写入号码,则在该处建立新的结点,并写入号码。
2.号码显示用for和while两个循环,具体实现过程可看附录代码。
3.号码查询按号码显示的函数书写,只是实现函数不同。
实验心得:通过这次的实验,我更加熟练了分析问题的方法。
深刻题解算法的重要性。
本次的算法实现中,对算法的时间空间复杂度进行了优化处理。
这是一个以前没做过的地方。
在哈希表的显示与查询中,出了一个错误,在纸上模拟了很久也没看出问题。
后来睡觉时才突然想到写少了一个函数,这提示我,写程序要细心,不能大意。
实验具体代码如下:// 哈希表问题.cpp : 定义控制台应用程序的入口点。
#include"stdafx.h"#include<iostream>usingnamespace std;class PNQS{private:char num[11];char name[8],address[18];int numwrited;PNQS *p;public :void setname(char cname[8],int n){int i;for (i=0;i<n;i++)name[i]=cname[i];name[i] = 0;}void setnum(char cnum[11],int n){int j;numwrited=1;for (j=0;j<n;j++)num[j]=cnum[j];num[n] = 0;}void setaddress(char cadd[18]){int i;for ( i=0;i<18;i++)address[i]=cadd[i];address[i] = 0;}void displaynpa(){cout<<"姓名:";cout<<name<<endl;cout<<"号码:";cout<<num<<endl;cout<<"地址:";cout<<address<<endl;}void displaynum(){cout<<num<<" ";}bool Isnumwrited(){if (numwrited==0)return 0;elsereturn 1;}bool Ispemp(){if (p==NULL)return 1;elsereturn 0;}void find(char Fnum[11],int n,int& ftrue){int b=0;for (int i=0;i<n;i++)if (num[i]!=Fnum[i])b++;if (b==0 && strlen(num)==strlen(Fnum)){displaynpa();ftrue=1;}}void movenext(PNQS *&mp){mp=p;}PNQS(){for(int i=0;i<16;i++)num[i]='0';num[16]=0;p=NULL;numwrited=0;}PNQS(char num2[4],int n){numwrited=0;p=NULL;for(int i=0;i<n;i++)num[i]=num2[i];num[n]=0;cout<<"请输入姓名:"<<endl;cin>>name;cout<<"请输入地址:"<<endl;cin>>address;}void CreatNewP(char num3[4],int n){p=new PNQS(num3,n);}};int keyword(char nums[16],int n){int count=0;for(int i=0;i<n;i++){count=count+nums[i]-48;}nums[n]=0;return count%7;}void main(){PNQS *p=new PNQS[8];bool exit=1;do{cout<<"输入存储,输入显示表,输入查找电话,输入退出"<<endl;int slect;cin>>slect;if (slect==1){staticint counts=0;counts++;cout<<"输入你要存入的号码:"<<counts<<endl;char num[16];cin>>num;if ( (p+keyword(num,strlen(num)))->Isnumwrited()==0){(p+keyword(num,strlen(num)))->setnum(num,strlen(num));cout<<"输入此主号码的姓名:"<<endl;char name[8];cin>>name;(p+keyword(num,strlen(num)))->setname (name,strlen(name));cout<<"输入此主号码的地址:"<<endl;char add[18];cin>>add;(p+keyword(num,strlen(num)))->setaddress (add);}else{PNQS *nextp=(p+keyword(num,strlen(num)));while(!nextp->Ispemp ()){nextp->movenext(nextp);}nextp->CreatNewP(num,strlen(num));}}PNQS *q;if(slect==2){cout<<"存入的表为:"<<endl;for(int ii=0;ii<8;ii++){cout<<endl;cout<<"第"<<ii<<"个位置:";if((p+ii)->Isnumwrited()==1 &&(p+ii)->Ispemp ()==1)(p+ii)->displaynum ();if ((p+ii)->Isnumwrited()==1 &&(p+ii)->Ispemp ()==0){q=(p+ii);q->displaynum ();do{q->movenext (q);q->displaynum ();}while(!q->Ispemp());}}}int findrigt;if(slect==3){findrigt=0;cout<<"输入要查的号码:"<<endl;char f[16];cin>>f;if((p+keyword(f,strlen(f)))->Isnumwrited()==1 &&(p+keyword(f,strlen(f)))->Ispemp ()==1){(p+keyword(f,strlen(f)))->find (f,strlen(f), findrigt);}if ((p+keyword(f,strlen(f)))->Isnumwrited()==1 &&(p+keyword(f,strlen(f)))->Ispemp ()==0){q=(p+keyword(f,strlen(f)));q->find (f,strlen(f), findrigt);do{q->movenext (q);q->find (f,strlen(f), findrigt);}while(!q->Ispemp());}if ( findrigt==0)cout<<"无此号码"<<endl;}if(slect==4)exit=0;}while(exit);system("pause"); }结果图附表:。
哈希表
123456789101112131415161718123456789101112131415161718 // HashTableInitializeTable(int TableSize) {HashTable H;int i;// 為散列表分配空間// 有些编譯器不支持為struct HashTable 分配空間,聲稱這是一個不完全的結構,// 可使用一个指向HashTable的指針為之分配空間。
// 如:sizeof(Probe),Probe作为HashTable在typedef定義的指針。
H = malloc(sizeof(struct HashTable));// 散列表大小为一个質数H->TableSize = Prime;// 分配表所有地址的空間H->Cells = malloc(sizeof(Cell) * H->TableSize);// 地址初始為空for (i =0; i < H->TableSize; i++)H->Cells[i].info = Empty;return H;}查找空单元并插入:// PositionFind(ElementType Key, HashTable H) {Position Current;int CollisionNum;// 冲突次数初始为0// 通過表的大小對關鍵字進行處理CollisionNum =0;Current = Hash( Key, H->TableSize );// 不為空時進行查詢while (H->Cells[Current].info != Empty &&H->Cells[Current].Element != Key) {Current =++CollosionNum *++CollisionNum;// 向下查找超過表範圍時回到表的開頭if (Current >= H->TableSize)Current -= H->TableSize;}return Current;}分離連接法散列表的查找过程基本上和造表过程相同。
数据结构 第九章 查找-哈希表
冲突是很难避免的, 冲突是很难避免的,其不可避免性具有它一 定的内因。 定的内因。因为关键字的值域往往比哈希表的个 数大的多,所以哈希函数是一种压缩映射, 数大的多,所以哈希函数是一种压缩映射,碰撞 是难免的。 是难免的。 例如,存储100个学生记录,尽管安排 个学生记录, 例如,存储 个学生记录 尽管安排120 个地址空间,要找到一个哈希函数把100个任意 个地址空间,要找到一个哈希函数把100个任意 的学生名映射成[0…119]内的不同整数,实际上 内的不同整数, 的学生名映射成 内的不同整数 是不可能的。 是不可能的。 问题在于一旦发生了冲突应如何处理? 问题在于一旦发生了冲突应如何处理?
解决冲突的主要方法 :
(1)开放地址法 (1)开放地址法 为了便于发现冲突和溢出, 为了便于发现冲突和溢出,首先要对哈希表 HT[0…m-1]进行初始化,置表中每个位置为 进行初始化, 进行初始化 置表中每个位置为NULL。就 。 关键字而言, 关键字而言,它表示不属于关键字值域的一种特定的特 殊符号。 殊符号。 假定记录Ri和 的关键字分别为 的关键字分别为Ki和 , 假定记录 和Rj的关键字分别为 和Kj,而有 H[Ki]=H[Kj]=t时,则说发生了冲突。如果 已装入 时 则说发生了冲突。如果Ri已装入 HT[t]中,那么 就不能再装入 那么Rj就不能再装入 中 那么 就不能再装入HT[t]中,但只要 中还 中 但只要HT中还 有空位,总可以把Ri存入 存入HT[t]的“下一个”空位上。 有空位,总可以把 存入 的 下一个”空位上。 寻找“下一个”空位的过程称为探测 探测。 寻找“下一个”空位的过程称为探测。下面介绍两种探 测方法。 测方法。
哈希函数的构造方法回顾
(1)直接定址法 (1)直接定址法 (2)平方取中法 (2)平方取中法 (3)数字分析法 (3)数字分析法 (4)除留余数法 (4)除留余数法
数据结构.第9章.查找.4.哈希表
§9.3 哈希表
开放地址法
例:关键码集为 {47,7,29,11,16,92,22,8,3}, 设:哈希表表长为m=11; 哈希函数为Hash(key)=key mod 11; 拟用线性探测法处理冲突。建哈希表: 0 1
11 22
2
3
4
5
6
3
7
7
8
29
9
8
10
47 92 16
§9.3 哈希表
开放地址法
选用关键字的某几位组合成哈希地址。
选用原则应当是:各种符号在该位上出现的频率大致
相同。
适于关键字位数比哈希地址位数大,且可能出现的关 键字事先知道的情况。
§9.3 哈希表
数字分析法
例:有一组(例如80个)关键码,其样式如下: 讨论: 3 4 7 0 5 2 4 ① 第1、2位均是“3和4”,第3位也只有 3 4 9 1 4 8 7 3 4 8 2 6 9 6 “ 7、8、9”,因此,这几位不能用,余 3 4 8 5 2 7 0 下四位分布较均匀,可作为哈希地址选用。 3 4 8 6 3 0 5 ② 若哈希地址取两位(因元素仅80个), 3 4 9 8 0 5 8 则可取这四位中的任意两位组合成哈希地 3 4 7 9 6 7 1 址,也可以取其中两位与其它两位叠加求 3 4 7 3 9 1 9 和后,取低两位作哈希地址。 位号:① ② ③ ④ ⑤ ⑥ ⑦
拟用二次探测法处理冲突。建哈希表如下: Hi = ( H(K)+di ) mod m 其中di =12, -12, 22,-22,…, j2, -j2 ( j≤m/2)。
0 1
11 22
2
3
3
4
5
6
7
数据结构 第4章
例子
假设要建立一个地址区间长度为13的哈希表,哈希函数为 H(key) = Ord(关键字第一个字母)-1)/2 其中函数Ord求字母在字母表中的序号。例如,字母A在 字母表中的序号为1, Ord(‘A’)=1。 现将关键字依次为Zhao, Qian, Sun, Li, Wu, Chen, Han的 7 个记录插入该哈希表。
例子
例如构造一个数据元素个数n = 60,哈希地址空间长度m = 100 的哈希表。 对关键字分析发现,关键字的第 1、2、3、6位取值比较集中,不 宜作为哈希地址,
…… 8 8 8 8 8 8 8 8 1 1 2 1 2 2 1 1 3 3 7 3 7 7 3 3 1 2 3 4 0 7 8 7 6 9 3 6 4 1 6 8 6 6 8 6 2 0 7 2 3 1 3 6 2 5 8 4 5 8 2
数据结构
广东工业大学 计算机学院
第4章 哈希表
第4章 哈希表
4.1 哈希表的概念 4.2 哈希函数的构造方法
4.2.1 直接定址法 4.2.2 除留余数法 4.2.3 数字分析法 4.2.4 折叠法 4.2.5 平方取中法 4.3.1 开放定址法 4.3.2 链地址法 链地址哈希表的实现 开放定址哈希表的实现
移位叠加 0040 1108 1053 0216 + 9891 (1)2308
Z形叠加 0040 8011 1053 6120 + 9891 (2)5115
4.2.5 平方取中法
平方取中法先取关键字的平方,然后根据哈希表地址区 间长度m的大小,选取平方数的中间若干位作为哈希地 址。通过取平方扩大关键字之间的差别,而平方值的中 间若干位和这个数的每一位都相关,使得不同关键字的 哈希函数值分布较为均匀,不易产生冲突。 设哈希表地址区间长度为1000,可取关键字平方值的中 间三位。
hash表及其应用 ppt课件
ppt课件
12
• in.txt • 4 ----- 5个字符串 • cat • banana • apple • dog • 3 ----- 询问3次 • banana • fruit • pet
• out.txt • YES • NO • NO
ppt课件
13
二、字符串的Hash函数 构造方法
• 字符串本身就可以看成一个256进制(ANSI字符 串为128进制)的大整数,因此我们可以利用直接 取余法,在线性时间内直接算出Hash函数值。
• 影响冲突的因素 冲突的频繁程度除了与h相关外,还与表的填满程度
相关。 设m和n分别表示表长和表中填人的结点数,则将
α=n/m定义为散列表的装填因子(Load Factor)。α越大, 表越满,冲突的机会也越大。通常取α≤1。
ppt课件
16
解决冲突的方法
• 开散列方法( open hashing,也称为拉链法, separate chaining )
• 为了保证效果,仍然不能选择太接近2n的数;尤 其是当我们把字符串看成一个2p进制数的时候, 选择m= 2p -1会使得该字符串的任意一个排列的 Hash函数值都相同。
ppt课件
14
排列的Hash函数
• 让排列与数1--A(m,n)之间建立一一对应的关系。
•
引理
n N
n1
n! 1 k k!
ppt课件
8
回到问题一
n最多为100000 flag数组不开到109,但可以开flag[1..300000]
ppt课件
9
可用取余法
ppt课件
10
解决冲突
• 将数组改为链表
ppt课件
第六章哈希表
(19,14,23,01,68,20,84,27,55,11,10,79) H(84)=84%13=6 H(20)=20%13=7 H(19)=19%13=6 H(14)=14%13=1 H(55)=55%13=3 H(23)=23%13=10 H(01)=01%13=1 H(68)=68%13=3 H(11)=11%13=11 H(10)=10%13=10 H(79)=79%13=1 H(27)=27%13=1 =(6+1)%15=7 =(10+1)%15=11 H1=(1+1)%15=2 =(3+1)%15=4 =(3+2)%15=5 =(6+2)%15=8 H2=(10+2)%15=12 =(1+2)%15=3 H3=(1+3)%15=4 H4=(1+4)%15=5
i 1 n
1 15
(1 13 12 11 10 9 8 7 6 5 4 3 2 1 1)
Hi = RHi(k) i = 1, 2, …, k
RHi均是不同的哈希函数,当产生冲突时就计算 另一个哈希函数,直到冲突不再发生。 优点:不易产生聚集; 缺点:增加了计算时间。
(4)建立一个公共溢出区
除设立哈希基本表外,另设立一个溢出向 量表。所有关键字和基本表中关键字为同义词 的记录,不管它们由哈希函数得到的地址是什 么,一旦发生冲突,都填入溢出表。
6.5 哈希表(Hash table)
基本思想
以结点的关键字k为自变量,通过一个确定的 哈希函数H,计算出对应的函数值H(k),作为 结点的存储位置并将结点存入。 顺序查找、折半查找、树的查找是建立在比较 基础上的查找,而哈希查找是直接查找。
哈希表(hash)详解
哈希表(hash)详解哈希表结构讲解:哈希表(Hash table,也叫散列表),是根据关键码值(Key value)⽽直接进⾏访问的数据结构。
也就是说,它通过把关键码值映射到表中⼀个位置来访问记录,以加快查找的速度。
这个映射函数叫做散列函数,存放记录的数组叫做散列表。
记录的存储位置 = function(关键字)这⾥的对应关系function称为散列函数,⼜称为哈希(Hash函数),采⽤散列技术将记录存储在⼀块连续的存储空间中,这块连续存储空间称为散列表或哈希表(Hash table)。
哈希表hashtable(key,value) 就是把Key通过⼀个固定的算法函数function既所谓的哈希函数转换成⼀个整型数字,然后就将该数字对数组长度进⾏取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间⾥。
(或者:把任意长度的输⼊(⼜叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。
这种转换是⼀种压缩映射,也就是,散列值的空间通常远⼩于输⼊的空间,不同的输⼊可能会散列成相同的输出,⽽不可能从散列值来唯⼀的确定输⼊值。
简单的说就是⼀种将任意长度的消息压缩到某⼀固定长度的消息摘要的函数。
)⽽当使⽤哈希表进⾏查询的时候,就是再次使⽤哈希函数将key转换为对应的数组下标【仍通过映射哈希函数function】,并定位到该空间获取value,如此⼀来,就可以充分利⽤到数组的定位性能进⾏数据定位。
Hash的应⽤:1、Hash主要⽤于信息安全领域中加密算法,它把⼀些不同长度的信息转化成杂乱的128位的编码,这些编码值叫做Hash值. 也可以说,Hash 就是找到⼀种数据内容和数据存放地址之间的映射关系。
2、查找:哈希表,⼜称为散列,是⼀种更加快捷的查找技术。
我们之前的查找,都是这样⼀种思路:集合中拿出来⼀个元素,看看是否与我们要找的相等,如果不等,缩⼩范围,继续查找。
严蔚敏数据结构课件10:哈希表
1. 直接定址法
此类函数直接取关键字或关键字的某个线性函数 线性函数值 线性函数 作为散列地址: Hash ( key ) = a * key + b { a, b为常数 } 这类散列函数是一对一的映射,一般不会产生冲突。 但是,它要求散列地址空间的大小与关键字集合的 大小相同。
2. 数字分析法 设有n个d位数,每一位可能有r种不同的符号。这 r 种不同的符号在各位上出现的频率不一定相同,可能 在某些位上分布均匀些;在某些位上分布不均匀,只 有某几种符号经常出现。可根据散列表的大小,选取 其中各种符号分布均匀的若干位作为散列地址。
查找关键字时所需对桶的平均访问次数
从图中可以看出,链地址法优于开放定址法;在散列函 数中,用除留余数法作散列函数优于其它类型的散列函 数,最差的是折叠法。
用不同的方法溢出处理冲突时散列表的平均查找长度 如图所示
处 理 溢 出 的 方 法 开 放 定 址 法 伪随机探查法 二次探查法 双散列法 链 地 址 法 (同义词子表法)
1 + α 2
平 均 搜 索 长 度 ASL 搜索成功 Sn
1 1 1 + 2 1 − α
搜索不成功(登入新记录) Un
1 2 1 1 + 2 (1 − α )
线性探查法
1 − log α
e (1 − α )
1 1− α
α + e −α ≈ α
散列 (Hashing)
在线性表、树结构中查找纪录是通过与关键 字的“比较”完成的。
• 顺序查找,比较的结果为“=”或“≠” • 非顺序查找,比较的结果为“<”,“=”,“>”
散列的思想: 根据纪录的关键字直接找到记录的存储位置, 即为关键字和记录的存储位置建立一个对应 关系f,使每个关键字和结构中一个唯一的 存储位置相对应。 对应关系f为散列函数,按该思想建立的表 为散列表。
哈希表演示
• 数字分析法:假设关键字是以r为基的数(如:以10为基 的十进制数)并且哈希表中可能出现的关键字都是事先知 道的,则可取关键字的若干数位组成哈希地址。 •平方取中法:取关键字平方后的中间几位作为哈希地址。 得到的哈希地址是随机的,取得位数由表长来决定。 •折叠法:将关键字分割成位数相同的几部分(最后一部分的位数可以不 同),然后取这几部分的叠加和(舍去进位)作为哈希地址。 •除留余数法:取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希 地址。即H(key)=key MOD p,p<=m 这是一种最简单,也是最常用的方法。它不仅可以对关键字直接取模,也可以 在折叠平方等运算之后取模。P应该取小于表长的最大素数。 •随机数法:选择一个随机函数,取关键字的随机函数值为它的哈希 地址,即H(key)=random(key),其中random为随机函数。通常当 关键字长度不等于时采用此法构造哈希函数比较恰当。
…
例如有80个记录,其关键字为8位十进制数。假设哈希表的表长为 10010则可取两位十进制数组成哈希地址。原则是使得到的哈希地址 尽量避免产生冲突,则需从分析这80个关键字着手,假设这80个关键 字中的一部分如下所列:
…
8 8 8 8 8 8 8 8 8 1
1 1 1 1 1 1 1 1 1 2
3 3 3 3 3 3 3 3 4 3
哈希表的查找及分析
哈希表的查找:在哈希表上进行查找的过程和哈希造 表的过程基本一致。给定k值,根据造表时设定的哈希 函数求的哈希地址,若表中此位置上没有记录,则查 找不成功;否则比较关键字若和给定值相等,则查找 成功;否则根据造表时设定的处理冲突的方法找下一 个定址,直至哈希表中某个位置为空或者表中所填记 录的关键字等于给定值时为止。 哈希表的性能分析:从哈希表的查找过程来看,虽然哈希表在 关键字与记录的存储位置之间建立了直接映像,但由于冲突的 产生,使得哈希表的查找过程仍然是一个给定值和关键字进行 比较的过程,因此,仍需以平均查找长度作为衡量哈希表的查 找效率的量度。但是对于均匀的哈希函数可以假定:不同的哈 希函数对同一组随机的关键字,产生冲突的可能性相同,因为 一般情况下设定的哈希函数时均匀的,则可不考虑它对平均查 找长度的影响。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
…..
81346532 81372242 81387422 81301367 81322817 81338967 81368537 81419355
分析: 只取8 只取1 只取3、4 只取2、7、5 数字分布近乎随机
所以:取任意两位或两位 与另两位的叠加作哈希地址
…..
哈希函数的构造方法
3. 平方取中法
什么是哈希表
例5:对于如下9个关键字 {Zhao, Qian, Sun, Li, Wu, Chen, Han, Ye, Dei}
设 哈希函数 f(key) = (Ord(第一个字母) - Ord('A') + 1)/2
什么是哈希表
字 ABCDE F GHI J KL M 母
序
1
2
3
4
5
6
7
8
9
10 11 12 13
什么是哈希表
例2: Ord(Char)=asc(char) –asc(‘a’) + 1
8(H)
0 1(A) 3 4 5(E) 9(I)
… … 26
4(D) 19(S) 22(V) 0
18(R)
7(G) 19
HAD HAS HAV HE 0
5(E) HIG HIS
HER HERE
什么是哈希表
什么是哈希表
由此可见,
1) 哈希(Hash)函数是一个映象,即:将关键字的 集合映射到某个地址集合上,它的设置很灵活, 只要这个地址集合的大小不超出允许范围即可;
2) 对不同的关键字可能得到同一哈希地址,即: key1≠ key2,而 f(key1) = f(key2),因此,很容易 产生“冲突”现象;
例3:为每年招收的1000名新生建立一张查找表,其 关键字为学号,其值的范围为xx000 ~ xx999 (前 两位为年份)。 将1000个学生的信息存放在数组A[0]—A[999]中
number(substring(学号, 3,3))
什么是哈希表
查找表: 使用数组存放n个关键字,数组的下标0n-1
什么是哈希表
3) 很难找到一个不产生冲突的哈希函数。一般 情况下,只能选择恰当的哈希函数,使冲突尽可 能少地产生。
因此,在构造这种特殊的“查找表” 时,除 了需要选择一个“好”(尽可能少产生冲突)的哈 希函数之外;还需要找到一种“处理冲突” 的方 法。
哈希表的定义
根据设定的哈希函数 H(key) 和所选中的处理冲突的 方法,将一组关键字映象到一个有限的、地址连续的 地址集 (区间) 上,并以关键字在地址集中的“象” 作为相应记录在表中的存储位置,如此构造所得的查 找表称之为“哈希表”。 这一过程称为哈希造表或者散列,所得的存储位置成 为哈希地址或者散列地址。
哈希函数的构造方法
对数字的关键字可有下列构造方法:
1. 直接定址法 2. 数字分析法
4. 折叠法 5. 除留余数法
3. 平方取中法
6. 随机数法
若是非数字关键字,则需先对其进行数字 化处理。
哈希函数的构造方法
1. 直接定址法
哈希函数为关键字的线性函数 H(key) = key 或者 H(key) = a key + b
建立查找表: 给定关键字key计算f(key)数组下标
查找时: 给定关键字key计算f(key)数组下标
什么是哈希表
例4:统计学生成绩各分数段的人数
Hash函数:f(grade) = grade/10
建立查找表: 给定grade计算f(grade)数组下标
查找时: 给定grade计算f(grade)数组下标
哈希函数的构造方法
2. 数字分析法
假设关键字集合中的每个关键字都是由 s 位数字组 成 (u1, u2, …, us),分析关键字集中的全体, 并从 中提取分布均匀的若干位或它们的组合作为地址。
此方法仅适合于:
能预先估计出全体关键字的每一关键字为8位十进制数,哈希地址为 2位十进制数
号
字 N O P Q R S T U V WX Y Z 母
序
14 15 16 17 18 19 20 21 22 23 24 25 26
号
序号
0 1 2 3 4 5 6 7 8 9 10 11 12 13
Chen Dei
Han
Li
Qian Sun
Wu Ye Zhao
问题: 若添加关键字Zhou , 怎么办?
哈希表
什么是哈希表 哈希函数的构造方法 处理冲突的方法 课堂练习 哈希表的查找 哈希表的查找分析 小结和作业
什么是哈希表
例1:有一批考试成绩,统计各分数段的人数。 A[0]A[1]A[2]A[3]A[4]A[5]A[6]A[7]A[8]A[9]A[10]
对成绩Grade,执行:A[grade/10]++
以关键字的平方值的中间几位作为存储地址。求“关 键字的平方值”的目的是“扩大差别”,同时平方值 的中间各位又能受到整个关键字中各位的影响。
此方法适合于: 关键字中的每一位都有某些数字重复出现频度
很高的现象。
哈希函数的构造方法
4. 折叠法
将关键字分割成若干部分,然后取它们的叠加和为哈希 地址。有两种叠加处理的方法:移位叠加和间界叠加。
可见,若p中含质因子3, 则所有含质因子3的关 键字均映射到“3的倍数”的地址上,从而增加 了“冲突”的可能。
哈希函数的构造方法
6. 随机数法
设定哈希函数为: H(key) = Random(key)
其中Random 为随机函数
此方法通常用于对长度不等的关键字构造哈 希函数。
哈希函数的构造方法
实际构造哈希表时 1.采用哪种构造哈希函数的方法取决于建表的关键字 集合的情况(包括关键字的范围和形态) 2.总的原则是使产生冲突的可能性尽可能的小。 3.如果哈希造表过程中产生冲突,应当如何处理这些 冲突呢?
此方法适合于:
关键字的数字位数特别多,而且关键字在每一位上 的数字分布大致均匀的情况。
哈希函数的构造方法
4. 折叠法
例 关键字为 :0442205864,哈希地址位数为4
5864
4220 04
移位叠加
10088
H(key)=0088
5864
0224 04
间界叠加
6092
H(key)=6092
哈希函数的构造方法
5. 除留余数法
设定哈希函数为: H(key) = key MOD p
其中, p≤m (表长) 并且 p 应为不大于 m 的素数 或是 不含 20 以下的质因子
哈希函数的构造方法
为什么要对p加限制?
给定一组关键字为: 12, 39, 18, 24, 33, 21 若取 p=9, 则它们对应的哈希函数值将为: 3, 3, 0, 6, 6, 3