博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
5、散列表
阅读量:5050 次
发布时间:2019-06-12

本文共 2611 字,大约阅读时间需要 8 分钟。

5、散列表

    散列表——最有用的基本数据结构之一。

    散列表的内部机制:实现、冲突和散列函数。

  5.1 散列函数

    散列函数是这样的函数,即无论你给它神秘数据,它都还你一个数字。(散列函数“将输入映射到数字”)。

    散列函数必须满足:

    (1)它必须是一致的。

    (2)它应将不同的输入映射到不同的数字。最理想的情况是,将不同的输入映射到不同的数字。例如,如果一个散列函数不管输入是神秘都返回1,它就不是好的散列函数。

    散列函数总是将同样的输入映射到相同的索引。

    散列函数将不同的输入映射到不同的索引。

    散列函数知道数组由多大,只返回有效的索引。如果数组包含五个元素,散列函数就不会返回无效索引100。

    结合使用散列函数和数组创建了一种被称为散列表(hash table)的数据结构。数组和链表都被直接映射到内存,但散列表更复杂,它使用散列函数来确定元素的存储位置。

    散列表也被称为散列映射、映射、字典和关联数组。

    散列表的速度很快!

    散列表使用数组来存储数据,因此其获取元素的速度与数组一样快。

    Python 提供的散列表实现为字典,你可使用函数 dict 来创建散列表。

    散列表适合用于:

    (1)仿真映射关系;

    (2)防止重复;

    (3)缓存/记住数据,以免服务器再通过处理来生成它们。

 

    代码清单5-1 散列表    

# -*- coding:UTF-8 -*-# 创建一个空的散列表book = dict()# 在其中添加一些商品的价格# 一个苹果的价格为67美分book["apple"] = 0.67# 牛奶的价格为1.49美元book["milk"] = 1.49book["avocado"] = 1.49print book# result: {'avocado': 1.49, 'apple': 0.67, 'milk': 1.49}# 鳄梨的价格print book["avocado"]# result: 1.49

    散列表由键和值组成。在前面的散列表 book 中,键为商品名,值为商品价格。散列表将键映射到值。

  5.2 将散列表用于查找

    手机都内置了方便的电话簿,其中每个姓名都有对应的电话号码。假设你要创建一个类似这样的电话簿,将姓名映射到电话号码。该电话簿提供如下功能:

    (1)添加联系人及其电话号码;

    (2)通过输入联系人来获取其电话号码。

    代码清单5-2 使用散列表用于查找电话号码 

# -*- coding:UTF-8 -*-# 新建一个散列表# phone_book = {} 与 phone_book = dict()等效phone_book = dict()# 在这个电话簿中添加一些联系人的电话号码phone_book["jenny"] = 8675309phone_book["emergency"] =911# 查找Jenny的电话号码print phone_book["jenny"]

    将网址映射到 IP 地址,这个过程被称为 DNS 解析(DNS resolution),散列表是提供这种功能的方式之一。

    5.3 防止重复

    如果你将已投票的姓名存储在列表中,这个函数的速度终将变得非常慢,因为它必须使用简单查找搜索整个列表。但这里将它们存储在散列表中,而散列表让你能够迅速知道来投票的人是否投过票。使用散列表来检查是否重复,速度非常快。

    代码清单5-3 使用散列表防止重复

# -*- coding:UTF-8 -*-# 创建一个散列表,用于记录已投票的人voted = {}def check_voter(name):    # 有人来投票时,检查他是否在散列表中    if voted.get(name):        print "kick them out!"    else:        voted[name] = True        print "let them vote!"check_voter("tom")# result: let them vote!check_voter("mike")# result: let them vote!check_voter("mike")# result: kick them out!

 

    5.4 将散列表用作缓存

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

    缓存是一种常用的加速方式,所有大型网站都使用缓存,而缓存的数据则存储在散列表中。

    代码清单5-4 请求Facebook的一个URL伪代码

cache = {}if cache.get{url}:    # 返回缓存的数据    return cache[url]else:    data = get_data_from_server(url)    # 先将数据保存到缓存中    cache[url] = data    return data

    仅当URL不在缓存中时,你才让服务器做些处理,并将处理生成的数据存储到缓存中,再返回它。这样,当下次有人请求该URL时,你就可以直接发送缓存中的数据,而不用再让服务器进行处理了。

     5.5 冲突

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

    最理想的情况是,散列函数将键均匀地映射到散列表的不同位置。

    如果散列表存储的链表很长,散列表的速度将急剧下降。然而,如果使用的散列函数很好,这些链表就不会很长。

    5.6 性能

    散列表的性能:

    

    在平均情况下,散列表执行各种操作的时间都为被称为常量时间。它并不意味着马上,而是说不管散列表多大,所需的时间都相同。

     在使用散列表时,避开最糟糕情况至关重要。为此,需要避免冲突,而要避免冲突,需要有:

    (1)较低的填装因子;

    (2)良好的散列函数。

 

转载于:https://www.cnblogs.com/Lamfai/p/10767499.html

你可能感兴趣的文章
django创建项目流程
查看>>
UIActionSheet 修改字体颜色
查看>>
Vue 框架-01- 入门篇 图文教程
查看>>
Spring注解之@Lazy注解,源码分析和总结
查看>>
多变量微积分笔记24——空间线积分
查看>>
Magento CE使用Redis的配置过程
查看>>
poi操作oracle数据库导出excel文件
查看>>
(转)Intent的基本使用方法总结
查看>>
Mac 下的Chrome 按什么快捷键调出页面调试工具
查看>>
Windows Phone开发(24):启动器与选择器之发送短信
查看>>
JS截取字符串常用方法
查看>>
Google非官方的Text To Speech和Speech Recognition的API
查看>>
stdext - A C++ STL Extensions Libary
查看>>
Django 内建 中间件组件
查看>>
bootstrap-Table服务端分页,获取到的数据怎么再页面的表格里显示
查看>>
进程间通信系列 之 socket套接字及其实例
查看>>
天气预报插件
查看>>
Unity 游戏框架搭建 (十三) 无需继承的单例的模板
查看>>
模块与包
查看>>
mysql忘记root密码
查看>>