PHP的array是真正的数组吗

超级大笨狼 2012-04-24 06:53:40
我看PHP语法中,数组的下标除了是数字外同样可以有类似哈希的key。那么PHP中的数组对象是不是不是真正的数据结构中的ARRAY。同时,但我设定了KEY时是不是就是可以当作HASH去使用,读取的时间复杂度是不是O(1)的?
...全文
275 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq120848369 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 的回复:]
Hash只能保证桶内有序, 如果坚持用哈希表而不用红黑树的话, 需要维护一个按Key有序的Hash node链表.

这样就可以同时满足:

1, 哈希表按key的O(1)的随机查询
2, 按key有序的遍历Hash node链表.
3, 支持链表按key的归并(array_uniq), 按key的排序, 按val的排序, 等等.

为什么要这样做?

Hash支持O(1)按k……
[/Quote]

这个数据结构和memached里的hashtable+lru list实现是基本一致的,只不过memached又结合的slab。
qq120848369 2012-04-25
  • 打赏
  • 举报
回复
Hash只能保证桶内有序, 如果坚持用哈希表而不用红黑树的话, 需要维护一个按Key有序的Hash node链表.

这样就可以同时满足:

1, 哈希表按key的O(1)的随机查询
2, 按key有序的遍历Hash node链表.
3, 支持链表按key的归并(array_uniq), 按key的排序, 按val的排序, 等等.

为什么要这样做?

Hash支持O(1)按key查找,而因为array提供了很多额外的特性, 比如按key排序,按val排序,操作hash表很难满足这些特性, 所以需要额外的存储容器来实现灵活的改变访问顺序这个功能.

在C语言里, 哈希表的Node和链表里的Node是同一个内存, Node有链表的prev,next,也有哈希链表的hash_prev,hash_next。


Php目前使用链表维护索引, 在很多操作中都要执行链表快排, 链表不支持随机访问, 所以快排性能有所下降,但是它的内存消耗又是比较低的, 很难说用顺序内存取代链表. 而如果用红黑树等平衡二叉树做索引, 又会面临的问题就是经常重新建树, 因为只要用户的排序要求变了, 就得重新建树, 而且支持array_asort的时候会显得更加恶心.
foolbirdflyfirst 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

引用 9 楼 的回复:

那是链表的话,是不是我向一个数组中插入100W条记录。哪怕指定了KEY。但是查找起来还是O(n)的?
引用 1 楼 的回复:

不是,他是一个链表

hash

是O(1),除非你刻意制造的下标,导致hash冲突

前段时间不是java ruby php啥的都中招了吗。。hash算法开源的


要说链表,还是双向的。。。prev next……
[/Quote]
hash攻击那个?
http://www.laruence.com/2011/12/30/2435.html
amani11 2012-04-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 的回复:]

那是链表的话,是不是我向一个数组中插入100W条记录。哪怕指定了KEY。但是查找起来还是O(n)的?
引用 1 楼 的回复:

不是,他是一个链表
[/Quote]
hash

是O(1),除非你刻意制造的下标,导致hash冲突

前段时间不是java ruby php啥的都中招了吗。。hash算法开源的


要说链表,还是双向的。。。prev next
foolbirdflyfirst 2012-04-25
  • 打赏
  • 举报
回复
哈稀表+链表
参见php开发组成员laruence的文章
http://www.laruence.com/2009/08/23/1065.html
helloDongXiu 2012-04-25
  • 打赏
  • 举报
回复
详解PHP中Array结构HashTable
http://www.cnblogs.com/wgw8299/articles/2275572.html

插入A,B,C三个值之后的内存中状态即为:
HashTable.arBucket[1] = C;
HashTable.pListHead = A
HashTable.pListTail =C
HashTable.pInternalPointer = A
A.pNext=null
A.pLast = C
A.pListNext = B
A.pListLast = null

B.pNext = null
B.pLast = null
B.pListLast = A
B.pListNext = C
C.pNext = A
C.pLast = null
C.pListNext = null
C.pListLast = B

查找某key的元素值(value):
如果我们要访问A元素,则提供A的key:key_a,得到对应的hash值为1
然后找HastTable.arBucket[1]。这时HastTable.arBucket[1]其实为C不是A,但由于C的key不等于A的key,因此,要沿着pNext的指针找下去,直到NULL,而此时C.pNext就是A,即找到了key_a对应的值A。
总之由key查找一个元素时,首先要hash,然后顺着hash后的索引位置的pNext指针一直找下去,直到NULL,如果遇到了和要查找的key相同的值,则找到,否则找不到。
超级大笨狼 2012-04-25
  • 打赏
  • 举报
回复
那是链表的话,是不是我向一个数组中插入100W条记录。哪怕指定了KEY。但是查找起来还是O(n)的?
[Quote=引用 1 楼 的回复:]

不是,他是一个链表
[/Quote]
K-dash 2012-04-25
  • 打赏
  • 举报
回复
哦,原来是HashTable
zhang6236872 2012-04-24
  • 打赏
  • 举报
回复
php键的冲突 解决冲突用的是单链表
zhang6236872 2012-04-24
  • 打赏
  • 举报
回复
贴个网址: http://www.codinglabs.org/html/hash-collisions-attack-on-php.html
xuzuning 2012-04-24
  • 打赏
  • 举报
回复
如果不是链表,那你如何解释一下函数
reset、prev、next、end

又,一般说 hash 表的时间复杂度是O(1)
这是理论上的,它假定键足够长
但实际应用时,键冲突是必然存在的。 hash 表在出现键冲突时采用顺序表来弥补
zhang6236872 2012-04-24
  • 打赏
  • 举报
回复
在PHP内部Array通过一个hashtable来实现,其中使用链接法解决hash冲突的问题,这样最坏情况下,查找Array元素的复杂度为O(N),最好则为1.
梦游 2012-04-24
  • 打赏
  • 举报
回复
PHP的数组Array是列表List,散列表/关联数组/字典Hashtable的聚合体。
既然array具有hashtable的性质 那么通过key值读取,他的时间复杂度当然是O(1)的!
wulg10 2012-04-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

不是,他是一个链表
[/Quote]
array()是链表?
zhang6236872 2012-04-24
  • 打赏
  • 举报
回复
在PHP中, 数组是用一种HASH结构(HashTable)来实现的, PHP使用了一些机制, 使得可以在O(1)的时间复杂度下实现数组的增删, 并同时支持线性遍历和随机访问.
xuzuning 2012-04-24
  • 打赏
  • 举报
回复
不是,他是一个链表

21,881

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧