散列表

散列表的英文名叫"HASH TABLE",也叫哈希表或者HASH表。算法

散列表用的是数组支持按照下标随机访问的特色,其实就是一种数组的扩展,没有数据就没有散列表数组

例子:函数

好比说学校里面的每一个学生都有编号,而后有89名学生去参加运动会,咱们如今要作一个经过编号迅速找到学生信息,编号是这样的061101,06是年级,11是班级,01就是编号,这样咱们就能够经过取每一个编号的后两位数做为数组的下标把学生的信息存储下来。blog

这里的编号061101就是键或者关键字,这里的取每一个编号的后两位数的过程叫做散列函数,这里的获取到的01也就是数组的下标,叫做散列值string

下面是伪代码实现的散列函数(取编号的后两位)hash

int hash(String key) {
// 获取后两位字符
string lastTwoChars = key.substr(length-2, length);
// 将后两位字符转换为整数
int hashValue = convert lastTwoChas to int-type;
return hashValue;
}

散列表特色:ast

1.获得的散列值必须是非负数class

2.若是key1=key2,那么func(key1)=func(key2)扩展

3.若是key1≠key2,那么func(key1)≠func(key2)方法

第一点很好理解,由于数组下标是从0开始的,第二点也好理解,相同的值通过散列函数计算出来的值相同,第三点看起来也很好理解,可是其实大多数的散列函数都不能实现这个要求,就连业界有名的MD5,SHA等哈希算法,也没法避免散列冲突。

散列冲突是什么意思呢?

就是不一样的值经过散列函数计算出来的散列值相同,也就是存储的数组的下标相同,那么就会带来冲突

那么解决散列冲突的方法通常有这么两种

1.开放寻址法

开放寻址法的核心思想是,若是出现了散列冲突,咱们就从新探测一个空闲位置,将其插入, 那如何探测空闲位置呢?咱们先来看这种线性探测的方法。

当咱们往数组中插入数据时,发现该数组下标已经被占用,那么咱们就依次日后面继续查找下标,直到找到空闲的数组下标而后将其插入。

能够看到上图中x通过散列函数获得数组下标为7的位置,可是7已经被占用了,那么咱们就继续日后查找,一直查到下标为2的位置是空闲的,那么咱们就将其插入到这个位置。

这个时候当咱们须要查找的时候就不能单纯的经过散列函数查找到对应的散列值来查找数据了,而是要在比对一下存储在该数组下标中的元素的值是否和须要查找的值同样

2.链表法

这个很好理解,就是把得出来相同散列值存在一个链表中

当插入的时候咱们只须要经过散列函数插入到对应的链表中便可。

相关文章
相关标签/搜索