哈希表的本质其实是个数组:
那就是哈希表就是通过将关键值也就是key通过一个散列函数加工处理之后得到一个值,这个值就是数据存放的位置,
请看这张图来理解哈希函数的作用:
虽然说哈希表就是个数组,但是他不像数组那样存储一个值,哈希表存储的是键值对,就想学号:101000,姓名:张三,简单点说就是一个值对应另外一个值。比如a对应b,那a就是key,b就是value;哈希表存放的就是这样的键值对。在焊锡表中是通过哈希函数将一个值映射到另外一个值的,所以在哈希表中a映射到b,a就是键值,而b呢叫做a的哈希值,也就是hash值。
哈希表是如何存放数据:
这里的序号是个key,我们也知道哈希表根据key值通过哈希函数计算得到一个值,这个值就是用来确定这个Entry要放在哈希表中的位置的,实际上这个值就是一个下标值,来确定放在数组的那个位置上。
现在学号101000 经过哈希函数算的Entry应该放在哈希表的下标为1的位置上,但是如果再来一个学号102000,经过哈希函数得到位置也是1怎么办呢?
关于哈希冲突的解决办法有好几个:我们这里介绍开放寻址法和拉链法》;
开放寻址法简单的来说就是:既然位置被占了,那就找另外一个位置,怎么找其他位置?假设当前1位置被占了,那就看看2的位置占了没,,2的位置也占了,那就看3的位置占了没,依次类推知道找到没有被占的位置.
拉链法:开放寻址法是如果当前位置被占了,那就找其他位置。而拉链法不一样还是找当前位置,可是当前位置被占了怎么办呢?所以这里采用的是链表?比如下图中王二占了1的位置,再来个李四也是这个位置,怎么解决呢?通过链表,所以Entry中还需要额外的保存一个next指针,这个指针指向数组的另外一个位置,将李四安排在这里,然后张三那个Entry中的next指针指向的是李四的位置,也就是保存了这个位置的内存地址,如果还有冲突,那就把又冲突的那个Entry放在一个新的位置上,然后李四的Entry中的next指向他。这样就形成了一个链表。
哈希表的扩容: