【读书笔记】《算法图解》第五章 散列表

第五章 散列表

1 散列函数

散列函数将输入映射到数字,白话是:无论你给它什么数据,它都还你一个数字。

散列函数必须满足以下要求:
  1. 他必须是一致的
  2. 它应将不同的输入映射到不同的数字
散列函数的作用:
  1. 散列函数总是将同样的输入映射到相同的索引。
  2. 散列函数将不同的输入映射到不同的索引
  3. 散列函数知道数组有多大,只返回有效的索引
散列表:

是一种包含额外逻辑的数据结构,它使用散列函数来确定元素的存储位置。也被成为散列映射,映射,字典和关联数组。Python提供的散列表实现为字典,你可以使用函数dict来创建散列表。散列表由键和值组成。散列表将键映射到值。

2 应用案例

2.1 将散列表用于查找

例如你需要创建一个电话簿,将姓名映射到电话号码

phone_book = dic()
phone_book = {} #与phone_book = dic()等效
phone_book[“jenny”] = 86766
phone_book[“emergency”] = 911
print phone_book[“jenny”]
86766

2.2 防止重复

假设你负责管理一个投票站。避免投过的人再次投票,代码如下:

Voted = {}
def check_voter(name):
if voted.get(name):
print(“kick them out!”)
else:
voted[name] = Ture
print(“let them vote!”)

使用散列表来检查是否重复,速度非常快。

2.3 将散列表用作缓存

缓存的工作原理:网站将数据记住,而不再重新计算。缓存是一种常用的加速方式,所有大型网站都使用缓存,而缓存的数据则存储在散列表中。
具体代码如下:

cache = {}
def get_page(url):
if cache.get(url):
return cache[url]
else:
data = get_data_from_server(url)
cache[url] = data
return data

2.4 小结

散列表适用于

  1. 模拟映射关系
  2. 防止重复
  3. 缓存/记住数据,以免服务器再通过处理来生成他们。

3 冲突

处理冲突最简单的办法:如果两个键映射到了同一个位置,就在这个位置存储一个链表。
散列函数很重要,好的散列函数很少导致冲突。

4 性能

在散列表中查找所花费的时间为常量时间。O(1)。这意味着不管散列表多大,所需的时间都相同。
最遭的情况下,散列表的各种操作的速度都很慢,所以为了避免最遭情况,需要避免冲突。而要避免冲突就需要1. 较低的填装因子 2. 良好的散列函数

4.1 填装因子

填装因子=散列表包含的元素数 / 位置总数
填装因子越低,发生冲突的可能性越小,散列表的性能越高。一个不错的经验规则是:一旦填装因子大于0.7,就调整散列表的长度。

4.2 良好的散列函数

良好的散列函数让数组中的值呈均匀分布,最糟糕的散列函数让值扎堆,导致大量的冲突。SHA函数是比较好的散列函数。

5 小结

  1. 你可以结合散列函数和数组来创建散列表。
  2. 冲突很糟糕,你应使用可以最大限度减少冲突的散列函数。
  3. 散列表的查找,插入和删除速度都非常快。
  4. 散列表适合用于模拟映射关系
  5. 一旦填装因子超过0.7,就该调整散列表的长度
  6. 散列表可用于缓存数据(例如,在Web服务器上)
  7. 散列表非常适合用于防止重复。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值