05_第五章 散列表

本章内容:

  • 学习散列表——最有用的基本数据结构之一,用途广泛
  • 学习散列表的内部机制:实现、冲突、散列函数。理解如何分析散列表的性能

在学习的复杂数据结构中,散列表可能是最有用的,也被称为散列函数、映射、字典(python提供的散列表实现为字典)和关联数组

 

目录

散列函数

应用案例

将散列表用于查找

防止重复

将散列表用作缓存

冲突和性能

冲突

性能

 

 


 

散列函数

  散列表是学习的第一种包含额外逻辑的数据结构。数组和链表都直接被映射到内存,但散列表更加复杂,它使用散列函数来确定元素的存储位置。散列表的速度很快!

任意一门优秀的语言都提供了散列表的实现。python提供的散列表实现为字典,你可以用函数dict来创建散列表。

book['apple'] = 0.67
book['banana'] = 0.3
book['milk'] = 1.49
print(book)
print(book['apple'])

#输出结果:

{'apple': 0.67, 'banana': 0.3, 'milk': 1.49}
0.67

散列表由键和值组成

 

应用案例

将散列表用于查找

散列表可以轻松的模拟映射关系

比如你在访问一个网站的时候,无论是什么网站,计算机必须将网址转化为ip地址,这个过程称为DNS解析(DNS resolution),散列表就是提供这种功能的方式之一。

比如上面的那个代码片段就是用来查找。

 

防止重复

比如你负责一个投票站。显然每个人都只能投一票,但是如何来避免重复投票呢,有个好方法,就是使用散列表。

#创建一个散列表,用于记录已经投过票的人
voted = {}
def check_votor(name):
    if voted.get(name):
        #if Ture,那么就执行
        print('has voted!')
    else:
        voted[name] = True
        #把这个新的名字加进去
        print('let ta vote!')
check_votor('Tom')
check_votor('Mike')
print(voted)
check_votor('Mike')

#输出
let ta vote!
let ta vote!
{'Tom': True, 'Mike': True}
has voted!

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

 

将散列表用作缓存

缓存的原理:网站将数据记住,而不是重新计算

ta不让服务器去生成网页,而是将网页存储起来,并在需要的时候将其直接发送给用户。缓存是一种加速方式,所有大型网站都使用缓存,二缓存的数据则存储在散列表当中!

cache = {}
#缓存的散列表
def get_page(url):
    if cache.get(url):
        #从缓存里面找,要是找的到的话就是直接输出该网页存储的信息
        return cache[url]
    else:
        data = get_data_from_server(url)
        #找不打的话就从服务器里面去找
        cache[url] = data
        #同时将这个网页的数据存储下来
        return data
        #返回这个网页的数据

 

小结一下散列表的用途:

  1. 模拟映射关系
  2. 防止重复
  3. 缓存数据,以免服务器再处理生成ta们

 

 

冲突和性能

虽然散列表查找的速度很快,但是依然要明白散列表的性能,在了解这个之前,需要明白什么是冲突。

冲突

冲突(collision):给两个键分配的位置相同

什么意思呢,就是python的字典里面一般不都是键值对的嘛,这个时候一个键会对应多个值

处理冲突的办法很多,最简单的方法就是:如果两个键映射到一个位置,那么就在这个位置存储一个链表。

其实吧,在里面再放一个散列表也没的关系。

book = dict()
book['a'] = [("apple",0.67),('avocado',0.54)]
book['banana'] = 0.3
book['milk'] = 1.49
print(book)
print(book['a'][0][1])


#输出
{'a': [('apple', 0.67), ('avocado', 0.54)], 'banana': 0.3, 'milk': 1.49}
0.67

但是这个有缺点,加入数组后,数据的查找速度会慢下来。因此最理想的情况是,散列表将键均匀地映射到散列表的不同位置

 

性能

散列表/数组/链表     大O运行时间
operation

散列表

(平均情况)

散列表

(最糟情况)

数组链表
查找O(1)

O(n)

O(1)O(n)
插入O(1)O(n)O(n)O(1)
删除O(1)O(n)O(n)O(1)

为了避免冲突,需要有:

  1. 较低的填充因子(填充因子=列表包含的元素数/位置总数,一旦超过0.7那就应该调整散列表的长度)
  2. 良好的散列函数(不用担心)

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值