数据结构-哈希表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、查找:哈希表,⼜称为散列,是⼀种更加快捷的查找技术。
我们之前的查找,都是这样⼀种思路:集合中拿出来⼀个元素,看看是否与我们要找的相等,如果不等,缩⼩范围,继续查找。
- 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