算法学习笔记_散列表

学习编程知识的同时,梳理知识,也便于以后查找
tags: 图解算法、B站视频

散列表

最有用的基本数据结构之一。第一种学到的包含额外逻辑的数据结构。
查找时间O(1)!!!

加密散列函数如彩虹表

散列函数

散列函数的要求

  1. 必须一致。一个输入对应的输出是固定的
  2. 不同的输入映射到不同的数字。

第一种学到的包含额外逻辑的数据结构。散列表使用散列函数来确定元素的存储位置。

散列表也被称为散列映射、映射、字典和关联数组。
散列表也使用数组来存储数据,因此其获取元素的速度和数组一样快。

创建散列表

散列表由键和值组成。
对于同样的输入,散列表必须返回同样的输出。这一点很重要。

"""散列表"""

# 创建散列表
book = dict()

# 添加数据
book["张三0"] = 99
book["张三1"] = 9
book["张三2"] = 44

print(book)
print(book['张三1'])
一些散列函数示例
# 无论输入什么都返回1
f(x) = 1
# 无论输入什么都返回一个随机数
f(x) = rand()
# 返回散列表中下一个空位置的索引
f(x) = next)empty_solt()
# 将字符串长度作为索引
f(x) = len(x)

散列表应用案例

散列表用途广泛。

  • 电话簿
  • 网址转换为IP地址(DNS解析)

防止重复

# 投票案例
voted = {}
# 检查在不在散列表中
value = voted.get("Tom")
if value:
    print("已经投过票!")
else:
    voted("Tom") = True

将散列表用作缓存

为提高网站访问速度,往往使用缓存技术。
缓存是一种常用的加速技术,所有大型网站都使用缓存。

缓存的优点

  • 用户能更快的看到网页
  • 网站需要做的工作更少

缓存的数据存储在散列表中。

代码实现

cache = {}

def get_page(url):
    if cache.get(url):
        return cache[url]

    else:
        data = get_data_from_server(url)
        #将数据保存到缓存中
        cache[url] = data
        return data

冲突

大多数语言都提供了散列表实现。基础时可以先不考虑散列表的内部原理,只需考虑散列表的性能问题。

冲突:给两个键分配的位置相同(即计算得出的hash值相同)

解决冲突

最简单的办法
如果两个键映射到了同一个位置,就在这个位置存储一个链表。

这里的经验教训有两个

  • 散列函数很重要。最理想的情况是,散列函数将键均匀地映射到散列表的不同位置
  • 如果散列表存储的链表很长,散列表的速度会急剧下降。如果使用的散列函数很好,这些链表就不会很长!
常用的三种方法 链表法、再哈希法、
  • 链表法 在传统位置,添加链表,通过链表存储元素。缺点是链表查找效率低。也是java中HashMap在基本情况下的使用方法
  • 开放定址法 若是发生哈希冲突,就以当前地址为基准,根据再寻址的方法(探查序列),去寻找下一个地址,若再冲突再去寻找,直至找到为止
  • 再哈希法 换用其它的哈希函数

性能

在平均情况下,散列表执行各种操作的时间都为O(1).(常量时间)
在最糟情况下,散列表所有操作的运行时间都为O(n)–线性时间。

在这里插入图片描述
在使用散列表时,避开最糟情况至关重要。为此,需要避免冲突,避免冲突,需要有

  • 较低的装填因子
  • 良好的散列函数

装填因子

散列表的装填因子很容易计算

散列表包含的元素数 / 位置总数

散列表使用数组来存储数据,因此需要计算数组中被占用的位置数。
装填因子的度量是散列表中有多少位置是空的

装填因子大于1,意味着元素数量超过了数组的位置数。
一旦装填因子开始增大,就需要在散列表中添加位置,这被称为调整长度

装填因子越低,散列表的性能越高。
一个不错的经验规则是:一旦装填因子大于0.7,就调整散列表的长度。

调整长度的开销很大,要避免频繁地调整长度。但平均而言,即便考虑到调整长度所需的时间,散列表操作所需的时间也为O(1).

散列函数

良好的散列函数让数组中的值呈均匀分布。

可以使用SHA函数,作为散列函数。

–END–

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值