matlabeig函数根据什么原理_探索python字典底层实现原理

python字典原理

python中的字典,是python中常见的数据类型之一。由键(key)值(value)组成的元素集合,根据键就可以取到对应的值,它的使用方式在这里我们不做过多的讨论。我们要讨论的是python字典的底层到底是怎么实现的,它跟其它编程语言的字典一样,底层就是一个哈希表。

哈希表

为什么是哈希表呢?这里先从哈希表的原理出发。先来了解什么是哈希表以及它的原理。哈希表也称为散列表,它通过把关键码值映射到表中一个位置来访问记录,查找的速度非常快, 理论上它的时间复杂度是 O(1),这个在后面会讲到 。哈希表的本质是一个数组,也就是在内存里面地址是连贯的,数组中的每一个元素称为一个箱子(bin),箱子中存放的是键值对,如arr1箱子中就存放key-value。

b233b2debb73e2f41848b66b87cb2210.png

这里用一个简单的编号来进行编排。从1到13,总共占13格,假设它就是整个哈希表的长度

d1320672655c4b44118dbb62135440c9.png

哈希表有啦!开始准备存值。

a7075ef6d5432b313de112e1104e9bdb.gif

存值取值

把括号里面这9个拼音存进去(Zhao,Qian,Sun,Li,Wu,Chen,Han,Ye,Dai),它在存值的时候不是一次性存的,而是根据某种算法来存进去。比如,Zhang中的Z在26个英文字母表中是26,但是哈希表长度只有13,就直接把Z对应到26除以2,于是放到哈希表13的位置。以此类推把9个拼音中的首字母取出来,除以2之后。可以得到下面的表格。

ba773714f0670d304c06b9a2d89ddc02.png

可以看到上面的公式其实很简单:13 = 26/2.  我们把这样存值的计算方式称为散列算法,散列算法就是哈希函数。哈希函数f(Key) = Ord(Key的第一个字母)/2。哈希里面常见哈希的算法有三种:哈希算法,MD4,MD5,SHA1(安全散列算法)。存了值之后,它的取值方式,也会根据对应的key,经过哈希函数之后,直接可以取出来,这也就是为什么它的时间复杂度可以是1的原因了。

但是还有一种情况,因为哈希函数是一个压缩的映像,它将刚刚的9个关键字的集合映射到某个地址集合上,也就是顺序表中,所以有时候也会产生冲突,这个冲突是怎么来的呢?比如现在有第10个拼音Hua, 本身Han在4的位置上,这时候就存不进去,于是就给它一个增量,假如这个增量是1,有这个增量后发现5是空的,就可以存到里面。

8a0eabf1968204bca93ff5299daf0b89.png

这种解决的方式就是最简单的,开放定址法。它的公式中d就是个增量,MODm表示对表长m取余,i的取值是i = 1,2, .......,s,这种对增量di的取法是三种中的一种,叫线性探测再散列。

b54b52d99bdf243fa5f2e84901085936.png

其次第二种增量的取法是:平方探测再散列

1274fc9624195e029ef87318a044e662.png

比如,有一个值Huang, 要存到当前的哈希表中。用第二种怎么来解决呢,从结果来看如果计算第一遍,是1的平方,会发现5的位置已经有Hua这个值了,但是取-1的平方时,就可以把Huang放到3的位置。

54034bca134857be495590b7a2321641.png

第三种是:随机探测再散列,di是一组伪随机数列。

除了使用开放定址法之外,哈希表还有链地址法,再哈希法, 折叠法等。从以上的情况来推断,在存值的时候,很难找到一个不产生冲突的哈希函数,所以只能选择恰当的哈希函数,使冲突尽可能少的产生。

链地址法

链地址法也称为拉链法,将产生冲突的值以链表的形式连起来,采用它的优势是,处理冲突很简单,没有堆积现象。其次拉链法中的链表节点,是动态申请的。所以很适合表长不确定的情况。比如有一个哈希函数H(key)=key MOD 13,把刚刚拼音用拉链法处理也是很方便的,这里就画出前面6个,其它的原理是一样的。

589fb5a31036b4af9fd591139c1eed9e.png

其它解决冲突的方式,就没有做过多的概括了,解决冲突方式是有些不一样的。从字典这块深入到它的实现原理,也就是哈希表,对哈希表也进行解释,如果感兴趣的小伙伴,还想深入去了解,可以对哈希表这块去参阅更多的资料,加深对python中字典的实现原理的了解。

8203a55227b61134ec469cca5d193fd6.gif

NO.1

 May

20.2020

end

69bc90eb76497459c47d6ee836e20e04.gif

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值