散列表
也叫哈希表
数组+散列函数
类比Java中的Map
key-value键值对
应用:
DNS域名解析,你输入 www.baidu.com 就会映射到相应的IP
防止重复,key值是唯一的,投票系统,每个人只能投一次
缓存,Web服务器存一些经常使用的数据到内存中,如Redis
散列函数
特性:
1.一致性,输入apple得到4,那么再次输入apple得到的还是4
2.输入不同,映射得到的也不同,如果输入不同的数得到相同的结果,说明这个散列函数不是好的
3.散列函数返回的索引是有效的,不会超过数组长度
冲突
散列函数不可能总是将不同的键映射到数组的不同位置,几乎不可能编写出这样的散列函数
如果apple在数组第一个位置,而此时把avocados(鳄梨)也放入散列表,但函数给你分配的第一个位置
这时候就有了冲突,apple可能会被覆盖
解决办法:在数组的第一个位置存一个链表,apple -> avocados 这样存起来
问题:如果这个链表元素少,还可以,但是如果存多了,读取起来就跟链表一样慢了(O(n))
所以说散列函数很重要
糟糕的散列函数让值扎堆分布,导致大量冲突
良好的散列函数会均匀分不到不同的位置
性能
散列表(平均情况) | 散列表(糟糕情况) | 数组 | 链表 | |
---|---|---|---|---|
查找 | O(1) | O(n) | O(1) | O(n) |
插入 | O(1) | O(n) | O(n) | O(1) |
删除 | O(1) | O(n) | O(n) | O(1) |
装填因子
装填因子 = 散列表包含的元素 / 位置总数
值越小,说明空位置越多,发生冲突可能性越小,值越大,说明越饱满,没有足够位置,发生冲突可能性越大
阀值:0.7
当装填因子大于0.7 ,需要调整数组长度,通常将数组长度增长一倍