哈希表和冲突解决

1.散列表

  散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。这个映射函数称做散列函数,存放记录的数组称做散列表。

2.散列函数

散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快定位。

(1). 直接定址法:取关键字或关键字的某个线性函数值为散列地址。即{ hash(k)=k} 或{ hash(k)=a*k+b} ,其中a,b为常数(这种散列函数叫做自身函数)

(2). 数字分析法:假设关键字是以r为基的数,并且哈希表中可能出现的关键字都是事先知道的,则可取关键字的若干数位组成哈希地址。

(3). 平方取中法:取关键字平方后的中间几位为哈希地址。通常在选定哈希函数时不一定能知道关键字的全部情况,取其中的哪几位也不一定合适,而一个数平方后的中间几位数和数的每一位都相关,由此使随机分布的关键字得到的哈希地址也是随机的。取的位数由表长决定。

(4).  折叠法:将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址。

(5).  随机数法

(6).  除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。不仅可以对关键字直接取模,也可在折叠法、平方取中法等运算之后取模。对p的选择很重要,一般取素数或m,若p选择不好,容易产生冲突。

3.冲突解决

为了知道冲突产生的相同散列函数地址所对应的关键字,必须选用另外的散列函数,或者对冲突结果进行处理。而不发生冲突的可能性是非常之小的,所以通常对冲突进行处理。常用方法有以下几种:

(1).开放定址法

增量序列可有下列取法:{ di=1,2,3...(m-1)}或者为其他线性函数称为线性探测。相当于逐个探测存放地址的表,直到查找到一个空单元,把散列地址存放在该空单元。当称为平方探测、二次探测。伪随机数序列,称为伪随机探测。

(2).单独链表法(链地址法)

将散列到同一个存储位置的所有元素保存在一个链表中。实现时,一种策略是散列表同一位置的所有冲突结果都是用栈存放的,新元素被插入到表的前端还是后端完全取决于怎样方便。

(3).双散列、再散列

根据不同的散列函数,即在同义词产生地址冲突时计算另一个散列函数地址,直到冲突不再发生,这种方法不易产生“聚集”,但增加了计算时间。

(4).建立一个公共的溢出区

4.查询效率

散列表的查找过程基本上和造表过程相同。一些关键码可通过散列函数转换的地址直接找到,另一些关键码在散列函数得到的地址上产生了冲突,需要按处理冲突的方法进行查找。在介绍的三种处理冲突的方法中,产生冲突后的查找仍然是给定值与关键码进行比较的过程。所以,对散列表查找效率的量度,依然用平均查找长度来衡量。查找过程中,关键码的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就低。因此,影响产生冲突多少的因素,也就是影响查找效率的因素。影响产生冲突多少有以下三个因素:

1. 散列函数是否均匀;

2. 处理冲突的方法;

3. 散列表的装填因子。

散列表的装填因子定义为:α= 填入表中的元素个数 / 散列表的长度

α是散列表装满程度的标志因子。由于表长是定值,α与“填入表中的元素个数”成正比,所以,α越大,填入表中的元素较多,产生冲突的可能性就越大;α越小,填入表中的元素较少,产生冲突的可能性就越小。

时间: 2024-10-13 10:57:49

哈希表和冲突解决的相关文章

哈希表之三冲突解决

前的部分分析了,哈希表中的冲突时难以避免的,冲突是很正常的,所以就要知道如何解决冲突. 我觉得冲突是有两种解决的方法: 1.横向的解决 2.纵向的解决 所谓横向解决:指的是对冲突的键,会在哈希表上另外找一个位置来安放它: 纵向解决是指:在冲突的键上会有一个线性链表,来存储冲突的元素. "处理冲突"就是为该关键字的记录找到一个"空"的哈希地址. 在处理冲突时,可能得到一个地址序列: 在处理冲突的时候,如果得到另一个哈希地址H1让然发生冲突,则会继续计算下一个地址H2,

开地址哈希表(Hash Table)的原理描述与冲突解决

在开地址哈希表中,元素存放在表本身中.这对于某些依赖固定大小表的应用来说非常有用.因为不像链式哈希表在每个槽位上有一个"桶"来存储冲突的元素,所以开地址哈希表需要通过另一种方法来解决冲突. 解决冲突的方法 在开地址哈希表中,解决冲突的方法就是探查这个表,直到找到一个可以放置元素的槽. 例如,插入一个元素时,我们探查槽位直到找到一个空槽,然后将元素插入此槽中.删除或查找一个元素时,我们探查槽位直到定位到该元素或找到一个空槽.如果在找到元素之前找到一个空槽或遍历完所有槽位,那么说明此元素在

第七章 哈希表

上章回顾 常见的排序算法有哪些 其中那种算法的效率最高 对大量的数据进行排序的化最好使用那种排 序算法 [email protected]:Kevin-Dfg/[email protected]:Kevin-Dfg/Data-Structures-and-Algorithm-Analysis-in-C.git 第七章 第七章 哈希表 哈希表 [email protected]:Kevin-Dfg/[email protected]:Kevin-Dfg/Data-Structures-and-Al

哈希表算法的编写

哈希算法的编写 hash表,有时候也被称为散列表.个人认为,hash表是介于链表和二叉树之间的一种中间结构.链表使用十分方便,但是数据查找十分麻烦:二叉树中的数据严格有序,但是这是以多一个指针作为代价的结果.hash表既满足了数据的查找方便,同时不占用太多的内容空间,使用也十分方便. 打个比方来说,所有的数据就好像许许多多的书本.如果这些书本是一本一本堆起来的,就好像链表或者线性表一样,整个数据会显得非常的无序和凌乱,在你找到自己需要的书之前,你要经历许多的查询过程:而如果你对所有的书本进行编号

memcached源码分析-----哈希表基本操作以及扩容过程

        转载请注明出处:http://blog.csdn.net/luotuo44/article/details/42773231 温馨提示:本文用到了一些可以在启动memcached设置的全局变量.关于这些全局变量的含义可以参考<memcached启动参数详解>.对于这些全局变量,处理方式就像<如何阅读memcached源代码>所说的那样直接取其默认值. assoc.c文件里面的代码是构造一个哈希表.memcached快的一个原因是使用了哈希表.现在就来看一下memca

C++链地址法实现哈希表

哈希表,也叫散列表,是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做哈希函数,存放记录的数组叫做哈希表. 哈希函数最主要的设计在于哈希函数和冲突处理的解决,其中哈希函数的设计方法主要有直接定址法和除留余数法:冲突处理的方法主要有开放定址法和链地址法.本文主要实现了一个基本存放字符串的哈希表,冲突处理采用链地址法. 代码如下: #include <iostream> #include<c

Java数据结构和算法之哈希表

五.哈希表 一般的线性表.树中,记录在结构中的相对位置是随机的即和记录的关键字之间不存在确定的关系,在结构中查找记录时需进行一系列和关键字的比较.这一类查找方法建立在"比较"的基础上,查找的效率与比较次数密切相关.理想的情况是能直接找到需要的记录,因此必须在记录的存储位置和它的关键字之间建立一确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应.因而查找时,只需根据这个对应关系f找到给定值K的像f(K).若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上,由此不需

哈希表之开地址法解决冲突

在上一篇博文中,我们讲述了使用链地址法解决冲突的方法.这里我们介绍另一种方式:开地址法解决冲突. 基本思想:当关键码key的哈希地址H0 = hash(key)出现冲突时,以H0为基础,产生另一个哈希地址H1 ,如果H1仍然冲突,再以H0 为基础,产生另一个哈希地址H2 ,-,直到找出一个不冲突的哈希地址Hi ,将相应元素存入其中.根据增量序列的取值方式不同,相应的再散列方式也不同.主要有以下四种: 线性探测再散列 二次探测再散列 伪随机探测再散列 双散列法 (一)线性探测再散列 理解起来很简单

[数据结构] Hash表、Hash函数及冲突解决

1.Hash表 哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构.也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. 以数据中每个元素的关键字K为自变量,通过散列函数H(k)计算出函数值,以该函数值作为一块连续存储空间的的单元地址,将该元素存储到函数值对应的单元中. 哈希表存储的是键值对,其查找的时间复杂度与元素数量多少无关,哈希表在查找元素时是通过计算哈希码值来定位元素的位置从而直接访问元