散列表

散列表是什么:

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

简单来说就是我们要存一组数据,我们可以拿他的关键值(key)通过散列函数的到散列值,以散列值为下标存入数组。

但是随着数据量的增加会出现哈希冲突这种情况

何为哈希冲突?

用散列函数得到的散列值在数据量大的情况下是会重复的,这种情况无法避免,那么我要存的数据的位置给之前的数据占了,尴尬了,到底要存哪呢?这就是所谓的哈希冲突。

解决途径:

介绍两种方法:

1、开放寻址法
如果发生了哈希冲突,需要找个新的位置存进去,这个位置要探测出来,探测的方法有许多种,举一个简单的办法,线性探测

这种方法就是,从冲突的地方继续往下找空闲的位置,找到就插进去,遍历到数组末尾没找到,就从头找,如果回到冲突位置就满了,考虑动态扩容问题(有点类似数组动态扩容,但是要解决数据量过大数据搬迁的时效问题)

查找的方法也一样,通过散列值找,然后比较下标为散列值的元素与要查找的元素,相等说明找到了,没找到就继续顺序往后找,直到找到空闲位置,那就是该元素压根就不在这散列表里。

删除操作则需在删除的位置打上标记,免的查的时候出错了。

2、链表法

把哈希表中的每一位置看做是桶或者槽(实际上是一条条链表),哈希冲突时只需将数据插入到该散列值对应的链表中即可,查找的时候就遍历这条链表,对比是否有相同的元素,插入时间复杂度为O(1)。

散列表的核心就是散列函数的设计,还有哈希冲突。

补充:
当装载因子(存的元素数/散列表大小)过大时,出现冲突的可能性就越大,那么此时散列表可能会退化链表,遍历起来耗时长。
关于动态扩容问题,动态扩容的话会导致散列函数出现变化,从而导致散列值出现变化,所有的数据要重新计算并且迁移都是十分耗费时间的,比方说几G的数据需要重新算又要移动位置,需要耗费相当的时间,解决这个问题的方法是搞个新的散列表,这个新的散列表的大小是原先的2倍或者几倍,然后把新的值插入新的散列表里,每插一个新值,就把旧的值搬一个到新的表,慢慢地实现更替,然后查询的时候先查新的再查旧的。

你可能感兴趣的:(散列表)