哈希表基本知识简介

文章目录

  • 一、哈希表简介
  • 二、哈希函数
    • 2.1直接定址法
    • 2.2 除留余数法
    • 2.3平方取中法
    • 2.4 基数转换法
  • 三、哈希冲突
    • 3.1 开放地址法
    • 3.2 链地址法


一、哈希表简介

哈希表:也叫做散列表,是根据关键字和值(Key Value)直接进行访问的数据结构,即通过一个关键字Key和一个映射函数Hash计算出对应的值Value,然后把键值对映射到表中一个位置来访问记录,以加快查找的速度,这个映射函数叫做哈希函数,用于存放记录的数组叫做哈希表

关键在于如何使用哈希函数:

  • 向哈希表中插入一个关键字:哈希函数决定该关键字的对应值应存放到表中的哪个区块,并将对应值存放到该区块中。
  • 在哈希表中搜索一个关键字:使用相同的哈希表中查找对应的区块,并在特定的区块搜索该关键字对应的值。

二、哈希函数

哈希表中元素的关键键值映射为元素存储位置的函数。一般满足一下条件:

  • 易于计算,尽量使计算出来的索引值均匀分布;
  • 哈希函数计算得到的哈希值是一个固定长度的输出值;
  • 哈希函数是多对一函数;

2.1直接定址法

直接定址法:取关键字活着关键字的某个线性函数值为哈希地址。Hash(key)=a*key+b

适合用于关键字分布基本连续的情况,当关键字不连续活着空位较多时,则会造成存储空间的浪费。

2.2 除留余数法

除留余数法:假设哈希表的表长为m,取一个不大于m但接近或等于m的质数p,利用取模运算将关键字转换为哈希地址,即Hash(Key)=key%p,其中p为不大于m的质数。

关键点在于p的选择,一般p取素数或者m,能够尽可能减少冲突。

2.3平方取中法

先通过求关键字平方值的方式扩大相近数之间的差别,然后根据表长度取关键字平方值的中间几位数为哈希地址。例如:Hash(key)=(key*key)//100%1000,先计算平方,去除末尾的2位数,再去中间3位数作为哈希地址。

这种方法因为关键字平凡值的中间几位数和原关键字的每一位数都相关,所以产生的哈希地址也比较均匀,有利于减少冲突的发生。

2.4 基数转换法

将关键字看成另一种进制的数再转换成原来进制的数,然后选其宗几位作为哈希地址。

三、哈希冲突

哈希冲突:不同关键字通过同一个哈希函数可能得到同一哈希地址。常用的哈希冲突解决方法主要是两类:【开放地址法】和【链地址法】。

3.1 开放地址法

指的是将哈希表中的【空地址】向冲突地址开放。当哈希表未满时,处理冲突时需要尝试另外的单元,直到找到空的单元为止。

当发生冲突时,开放地址法按照下面的方法求得后继哈希地址:H(i)=(Hash(key)+F(i))%m

  • H(i)是在处理冲突中得到的地址序列,即在第1次(i=1)时经过处理得到一个新地址H(1),直到求得的H(n)不再发生冲突;
  • F(i)是冲突解决方法,取法一般有:线性探测法、二次探测法、伪随机数序列

3.2 链地址法

值得是将具有相同哈希地址的元素(或记录)存储在同一个线性链表中。相比起开放地址法,链地址法更简单。

假设哈希函数陈生地址区间为[0,m-1],哈希表的表长为m。则可以将哈希表定义为有m个头结点组成的链表指针数组T。

  • 在插入关键字时,通过Hash(key)计算出对应的哈希地址i,然后将其以链表节点的形式插入到T(i)为头节点的单链表中。
  • 在查询关键字时,通过Hash(key)计算出对应的哈希地址i,比较表中每个链节点的键值与查询的键值是否一致。查询操作的时间复杂度为O(n//m),其中n时关键字个数,m是哈希表的表长。

链地址法处理冲突要多占用一些存储空间,但是可以减少在进行插入和查找具有相同哈希地址的关键字的操作过程的平均查找长度。

你可能感兴趣的:(Leetcode刷题,散列表,数据结构,哈希算法)