从哈希结构去理解PHP数组
php的数组实际上就是hash_table,无论是 数字索引数组array(1, 2, 3) 还是关联数组array(1 => 2, 2=> 4)等等。
一,这里的hash_table有几个特殊的地方:
1. 遍历的时候的顺序和插入的顺序一致,也就是如果你插入的时候顺序是:
$a = array();
$a[3] = 3;
$a[2] = 2;
$a[1] = 1;
那么它foreach的遍历顺序还是3, 2, 1。我们可以利用这个特殊的性质,如果开始的时候,插入的顺序是有序的,那么foreach也是有序的,这个是很方便的。
2. 插入和删除都是O(1)的复杂度,特别是删除,比较方便。
3. 遍历的效率低于一般的数组,因为数据不是连续的。
二,PHP采用了DJBX33A(time33)哈希函数,哈希函数将两个不同的key映射到同一个索引的情况,出现哈希冲突。解决哈希冲突的方法有链接法和开放寻址法,PHP采用链接法。
链接法:链接法通过使用一个链表来保存slot值的方式来解决冲突,也就是当不同的key映射到一个槽中的时候使用链表来保存这些值。 所以使用链接法是在最坏的情况下,也就是所有的key都映射到同一个槽中了,操作链表的时间复杂度为O(n)。 所以选择一个合适的哈希函数是最为关键的。目前PHP中HashTable的实现就是采用这种方式来解决冲突的。
开放寻址法:通常还有另外一种解决冲突的方法:开放寻址法。使用开放寻址法是槽本身直接存放数据, 在插入数据时如果key所映射到的索引已经有数据了,这说明发生了冲突,这是会寻找下一个槽, 如果该槽也被占用了则继续寻找下一个槽,直到寻找到没有被占用的槽,在查找时也使用同样的策律来进行。
三,PHP中哈希表结构
假定向PHP数组中插入三个元素分别为Bucket1,Bucket2,Bucket3,其中Bucket1和Bucket2的key具有相同的哈希值。其在哈希表中存储如图所示:

从上图可知,(1)哈希表中同一个哈希值对应元素存储在双向链表中。(2)PHP数组<key,value>,将key代入哈希函数,很快获得哈希值。然后遍历此哈希值对应链表,获取链表中某个属性是key的节点,此节点的值是value。PHP数组中获取key的速率高于value,可以利用此优势。
从哈希结构去理解PHP数组的更多相关文章
- 深入理解Js数组
深入理解Js数组 在Js中数组存在两种形式,一种是与C/C++等相同的在连续内存中存放数据的快数组,另一种是HashTable结构的慢数组,是一种典型的字典形式. 描述 在本文中所有的测试都是基于V8 ...
- Redis源代码分析(三)---dict哈希结构
昨天分析完adlist的Redis代码.今天立即马不停蹄的继续学习Redis代码中的哈希部分的结构学习,只是在这里他不叫什么hashMap,而是叫dict.并且是一种全新设计的一种哈希结构,他仅仅是通 ...
- 从有限状态机的角度去理解Knuth-Morris-Pratt Algorithm(又叫KMP算法)
转载请加上:http://www.cnblogs.com/courtier/p/4273193.html 在开始讲这个文章前的唠叨话: 1:首先,在阅读此篇文章之前,你至少要了解过,什么是有限状态机, ...
- 从需求的角度去理解Linux系列:总线、设备和驱动
笔者成为博客专家后整理以前原创的嵌入式Linux系列博文,现推出以让更多的读者受益. <从需求的角度去理解linux系列:总线.设备和驱动>是一篇有关如何学习嵌入式Linux系统的方法论文 ...
- 从逆向的角度去理解C++虚函数表
很久没有写过文章了,自己一直是做C/C++开发的,我一直认为,作为一个C/C++程序员,如果能够好好学一下汇编和逆向分析,那么对于我们去理解C/C++将会有很大的帮助,因为程序中所有的奥秘都藏在汇编中 ...
- 按自己的想法去理解事件和泛型(C#)
上一篇那些年困扰我们的委托(C#)讲了委托,这一篇自然就轮到事件了. 不喜欢官方的表达方式,喜欢按照自己的想法去理解一些抽象的东西. 事件 考虑到委托使用的一些缺陷,就有了事件.委托是不安全的,打个比 ...
- JAVA中的数据结构 - 真正的去理解红黑树
一, 红黑树所处数据结构的位置: 在JDK源码中, 有treeMap和JDK8的HashMap都用到了红黑树去存储 红黑树可以看成B树的一种: 从二叉树看,红黑树是一颗相对平衡的二叉树 二叉树--&g ...
- Perl 引用:引用就是指针,Perl 引用是一个标量类型可以指向变量、数组、哈希表(也叫关联数组)甚至子程序。
Perl 引用引用就是指针,Perl 引用是一个标量类型可以指向变量.数组.哈希表(也叫关联数组)甚至子程序,可以应用在程序的任何地方. 1.创建引用1.使用斜线\定义变量的时候,在变量名前面加个\, ...
- c#中关于结构体和字节数组转化
最近在使用结构体与字节数组转化来实现socket间数据传输.现在开始整理一下.对于Marshal可以查阅msdn,关于字节数组与结构体转代码如下: using System; using System ...
随机推荐
- FreeSWITCH 客户端fs_cli连接设置(acl)
FreeSWITCH 默认配置只能 在本机连接, 要从 外面连接, 就要配置: acl.conf.xml::network-lists/list event_socket.conf.xml::appl ...
- NodeJS - npm WARN package.json : No repository field:can not open package.json
最近在研究node.js,在安装npm的时候发现了几个报错,瞬间蒙圈,查找文献基本解决(文献好少呀~ -.-) 一.报错:“can not open path/path/package.jso ...
- 清北学堂 day6 花
1.花( flower.cpp/c/pas)[ 问题描述]商店里出售 n 种不同品种的花.为了装饰桌面,你打算买 m 支花回家.你觉得放两支一样的花很难看,因此每种品种的花最多买 1 支.求总共有几种 ...
- SceneBuilder 打不开 .fxml文件,只在任务栏显示
mark一下,今天下载官网的SceneBuilder 2.X 最近在使用JavaFX,感觉还是很酷的,可是在正常的编辑关闭SceneBuilder 之后,再次打开却打不开了 可是奇怪的是有些 .fxm ...
- RAW编程接口
LWIP移植好之后,就要使用它提供的API接口来编写程序.
- Excel数据透视表
Excel中每列是一个字段,每行是一条记录. 值字段设置,双击更改统计方法. 双击透视表中的数据可以看具体是哪些记录贡献的这些数据. 显示报表筛选页,生成多个工作簿.
- ConfigureAwait(false)避免上下文延续
之前MVC利用MvcHtmlString封装通用下拉菜单,菜单数据需要从webapi获取,自然用到了 await Http Client.GetAsync(Url)方法,前端 @Html.Select ...
- 编写高质量代码改善C#程序的157个建议——建议65:总是处理未捕获的异常
建议65:总是处理未捕获的异常 处理为捕获的异常是每个应用程序具备的基本功能,C#在APPDomain提供了UnhandledException事件来接收未捕获到的异常的通知.常见的应用如下: sta ...
- 【小梅哥SOPC学习笔记】NIOS II工程目录改变时project无法编译问题
解决NIOS II工程移动在磁盘上位置后project无法编译问题 说明:本文档于2017年3月4日由小梅哥更新部分内容,主要是增加了讲解以Quartus II13.0为代表的经典版本和以15.1为代 ...
- Gym - 100989H (贪心)
After the data structures exam, students lined up in the cafeteria to have a drink and chat about ho ...