算法——散列表(最有用的基本数据结构之一)
你作为一个老板,一个卖东西要不断找价格表的销售员和一个一眼看到商品就能知道价格的销售员 你会要哪一个?
可以使用这样形式的数组来记录商品价格
[(eggs,2,49)(milk,1.49)(pear,0.79)],
将这些数组按商品名排序,再执行二分查找商品的价格。 这样查找价格的时间就是O(log n)
什么是散列函数? 输入能够映射到数字的函数。
散列函数需要满足的要求:
①必须是一致的。比如输入apple得到4,那么每次输入apple都是4
②将不同的输入映射到不同的数字。【最理想】
如果输入后都返回1,那这个散列函数就很烂 要有一个一一对应的关系,这样才非常容易分辨找到自己要找的数字
散列函数准确指出了价格的存储位置。 原因是:
①相同的输入总得到相同的索引。
②不同的输入映射到不同的索引。
③散列函数能够知道数组有多大,并且只会返回有效的索引。不会超出数组的索引范围。
散列表就像是python里的字典。包含键值对
如果像字典一样存储 如果开头都是A 就会有一个冲突问题
可以像这样子再加个链表,但速度又会慢上许多。
书上的扩展内容:如何避免散列表的最糟情况
①较低的填充因子 ②良好的散列函数
散列表的填装因子 = 散列表包含的元素数 / 位置总数
填充因子就是1/3 最佳情况为1 一一对应 位置越少填充因子越大
可以将数组增长一倍
hash()函数能将
所有元素插入这个新的散列表中。 这时候 填充因子就降低了,填充因子越低,发生冲突的可能性越大
如何设计散列表(举例)
散列函数设计: 例:将每个字符都映射到一个素数,a = 2,b = 3,c = 5,d = 7 ,e =11,g=17等等,
对于给定字符串,散列函数将每个字符对应的素数相加,再计算结果除以散列表长度的余数。
比如,散列表长度10,字符串bag,则索引就是(3+2+17)% 10 = 2
小结:
①一旦填装因子超过0.7,就应该调整列表长度
②散列表非常适合用于防止重复