python 哈希表_数据结构-7 哈希表
python内部查找表非常快,就是用的哈希表(hash-table)实现的。
后续实现字典集合。
怎么解决冲突?
其实一种直观的想法是如果冲突了我能不能让数组中 对应的槽变成一个链式结构呢?这就是其中一种解决方法,叫做链接法(chaining)。如果我们用链接法来处理冲突:
这样就用链表解决了冲突问题,但是如果哈希函数选不好的话,可能就导致冲突太多一个链变得太长,这样查找就不再是 O(1) 的了。
还有一种叫做开放寻址法(open addressing),它的基本思想是当一个槽被占用的时候,采用一种方式来寻找下一个可用的槽。 (这里槽指的是数组中的一个位置),根据找下一个槽的方式不同,分为:
线性探查(linear probing): 当一个槽被占用,找下一个可用的槽。
- h(k, i) =
% m, (i = 0,1,...,m-1 )
双重散列(double hashing): 重新计算 hash 结果。
- h(k,i) =
% m
二次探查(quadratic probing): 当一个槽被占用,以二次方作为偏移量。就是二次哈希。 (python使用的就是二次探查。)
- % m , i=0,1,...,m-1
- #注意:是在第一次得到的index上(+i*i) , 不是每次都累加。
inserted_index_set = set()#建立一个无重复集
M = 13 #键位13def h(key,M = 13):return key % Mto_insert = [765, 431, 96, 142, 579, 226, 903, 388]
#——————————————————————————————————————————————————————————————
for number in to_insert:index = h(number)first_index = index #得到first-index,如果发现这个键位被占用则计算下一个可用的键位。i = 1while index in inserted_index_set: #计算得到下一个可用的槽print('th({number}) = {number} % M = {index} collision' . format(number = number,index = index))index = (first_index + i*i) % M # 根据二次方探查的公式重新计算下一个需要插入的位置i += 1else: #没有被占用就直接输出print('h({number}) = {number} % M = {index}'.format(number = number,index = index))inserted_index_set.add(index)
output:
h(765) = 765 % M = 11
h(431) = 431 % M = 2
h(96) = 96 % M = 5
h(142) = 142 % M = 12
h(579) = 579 % M = 7h(226) = 226 % M = 5 collision
h(226) = 226 % M = 6h(903) = 903 % M = 6 collisionh(903) = 903 % M = 7 collision
h(903) = 903 % M = 10h(388) = 388 % M = 11 collisionh(388) = 388 % M = 12 collisionh(388) = 388 % M = 2 collisionh(388) = 388 % M = 7 collision
h(388) = 388 % M = 1
最终:
装载因子(load factor)
如果继续往我们的哈希表里塞东西会发生什么?空间不够用。这里我们定义一个负载因子的概念(load factor),其实很简单,就是已经使用的槽数比哈希表大小。 比如我们上边的例子插入了 8 个元素,哈希表总大小是 13, 它的 load factor 就是 8/13≈0.628/13≈0.62。当我们继续往哈希表插入数据的时候,很快就不够用了。 通常当负载因子开始超过 0.8 的时候,就要新开辟空间并且重新进行散列了。
重哈希(Rehashing)
当负载因子超过 0.8 的时候,需要进行 rehashing 操作了。
步骤就是重新开辟一块新的空间,开多大呢?感兴趣的话可以看下 cpython 的 dictobject.c 文件然后搜索 GROWTH_RATE 这个关键字,你会发现不同版本的 cpython 使用了不同的策略。python3.3 的策略是扩大为已经使用的槽数目的两倍。开辟了新空间以后,会把原来哈希表里 不为空槽的数据重新插入到新的哈希表里,插入方式和之前一样。这就是 rehashing 操作。
HashTable ADT
实践是检验真理的唯一标准,这里我们来实现一个简化版的哈希表 ADT,主要是为了让你更好地了解它的工作原理,有了它,后边实现起 dict 和 set 来就小菜一碟了。 这里我们使用到了定长数组,还记得我们在数组和列表章节里实现的 Array 吧,这里要用上了。
解决冲突我们使用二次探查法,模拟 cpython 二次探查函数的实现。我们来实现三个哈希表最常用的基本操作,这实际上也是使用字典的时候最常用的操作。
- add(key, value)
- get(key, default)
- remove(key)
python 哈希表_数据结构-7 哈希表相关推荐
- 不同表结构数据迁移_数据结构:哈希 哈希函数 哈希表
写在前面 希望你们看了能够有所收获,同时觉得不错的朋友可以点赞和关注下我,以后还会有更多精选文章分享给大家!大家可以关注一下java提升专栏 java提升zhuanlan.zhihu.com 什么是 ...
- 人们通常先在线性表尾部临时添加一个_数据结构学习笔记-线性表
我们经常会处理一系列类型相同的数据, 创建这种元素组, 读取和修改 当我们处理一个具有有穷或者无穷的元素数据集的时候, 我们需要将其作为一个整体来管理和使用, 用变量去表示它们, 传入和传出函数等等. ...
- python基础刷题_数据结构与算法LeetCode刷题(Python)
参考资料: 一.链表 1. 链表的必备知识要点(包括基础知识.刷题中使用的STL等知识) 2. 链表逆序(LeetCode 92 ,206. Reverse Linked List 1,2) 3. ...
- mysql 线性表_数据结构之线性表
概要 参考<大话数据结构>,把常用的基本数据结构梳理一下. 线性表 定义 线性表(List):零个或多个数据元素的有限序列. 若将线性表记为 \((a_1, \cdots, a_{i-1} ...
- java 实现内存数据表_数据结构 Java中的内存
根据线性表的实际存储方式,分为两种实现模型: 顺序表 ,将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示. 链表 ,将元素存放在通过链接构造起来的一系列存储块中. 一.顺 ...
- python开源报表系统_流程设计器、表单设计器和简单报表管理开源OA系统smart-web...
smart-web2是一套相对简单的OA系统:包含了流程设计器,表单设计器,权限管理,简单报表管理等功能: 系统后端基于SpringMVC+Spring+Hibernate框架,前端页面采用JQuer ...
- 线性表算法题库_数据结构与算法(线性表)练习题
.word 资料 . 三.写一个算法合并两个已排序的线性表. (用两种方法:数组表示的线性表(顺序表)和 指针表示的线性表(链表) ) 要求: 1 .定义线性表节点的结构,并定义节点的型和位置的型. ...
- 哈希值 哈希码_什么是哈希? 哈希码如何工作-带有示例
哈希值 哈希码 哈希简介 (Introduction to hashing) Hashing is designed to solve the problem of needing to effici ...
- excel链接隐藏工作表_自动隐藏Excel工作表
excel链接隐藏工作表 When you build a workbook for other people to use, there might be worksheets that can s ...
最新文章
- Swift数组扩容原理
- 如何消费WCF Data Services定义的服务操作
- 给JDK报了一个P4的Bug,结果居然……
- 背后的故事之 - 快乐的Lambda表达式(二)
- springmvc知识点
- LeetCode 1116. 打印零与奇偶数
- arduino和python对接_Python:与Arduino进行交互-后续
- 无聊特意去拍月亮。呵呵
- 路径规划-人工势场法(Artificial Potential Field)
- SXF终端检测平台 EDR漏洞复现
- Outlook的服务器设置中POP3协议,在outlook的服务器设置中POP3协议是指
- 英文字体识别在线识别_如何查找和识别字体
- KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结【转】
- 【一起学Rust】Rust的Hello Rust详细解析
- 实习6(持续更新)--数据分析
- 华为设备配置IS-IS命令
- Linux下的vim如何保存并退出
- 关于operator bool () 和bool operator ==()
- 大数据、云计算、物联网、数据仓库、OLAP、OLTP、等大数据你必须知道并且了解的概念及相关关系,我的一些总结
- element-ui时间组件使用
热门文章
- PostgreSQL与MySQL的日期类型DATE/date的格式区别
- jquery生成一个li_如何使用jQuery从字符串数组生成UL Li列表?
- 现代科技概论_现代科技概论课程:力与运动1
- Kotlin 接口(三)
- 这也许是Android一句话权限适配的更优解决方案
- python2.7更新pip_CentOS升级Python2.6到Python2.7并安装pip
- python sphinx_Python Sphinx使用实例及问题解决
- linux7本地yum安装,RHEL7安装本地离线yum源仓库
- 命令行开启一个unity实例和执行其中的脚本方法的使用和注意
- 在Web应用程序中执行常见搜索场景的服务器端方法