这是一个非常笼统的基于计算机科学的问题,但是根据有关其工作原理的文献来看,这似乎并不直观。这是一个与语言无关的问题,但与Set数据类型在内部如何工作有关。
我已经多次使用它们,建议使用它们来存储唯一值并快速访问它们。用Big-O表示,每次访问Set时,其时间和复杂度为O(1)。如果Set包含数千个项目,怎么可能?即使项目是唯一的。
为了在Set中找到一个项目,它仍然必须扫描每个唯一的项目,在Big-O中,时间和复杂度均为O(n)。我在这里想念什么吗?
预先感谢您的帮助!最彻底的答案会得到投票!
答案 0 :(得分:1)
Set
是一种更通用的对象示例,统称为HashedCollections
。它们使用某种HashTable
来实际存储和检索其元素。
给定任何element
,这些表为其计算一个整数值,称为hash
。有几种众所周知的技术来定义元素及其hash
值之间的映射。有些是本征,在某种意义上说hash
不依赖于element
的属性,该属性可能会改变,因此hash
保持不变沿element
的生命。其他的是外部,因为它们可能取决于属性。但是,在后一种情况下,假设从HashedCollection
引用特定元素时将不会对其进行修改(否则HashedCollection
必须为rehashed
)。
存储element
的过程如下:
hash
计算element
。index
被计算为表中hash
的{{1}}的余数。length
处的插槽,则将应用某些策略来解决冲突。第1步应该非常快(例如index
的强度没有hash
)。
步骤2假设(在大多数情况下)表的长度是素数的数字(也使用cryptographic
的幂)
第3步基本上可以通过两种方式解决:
2
次,直到j
上的插槽可用,或者index + j
(存储桶)上发生冲突的元素集合中此外,如果没有足够的空插槽(这会增加发生冲突的可能性),则会放大表格并index
(因为rehashed
已更改)。
有了足够的可用时隙和索引机制的相当随机的分布,在modulo
中找到所需时隙的可能性非常高。当然,如果有太多的元素冲突,则平均复杂度不再O(1)
,但是可以通过不断增长的策略(+ O(1)
)来减轻。
检索类似。为了检查rehash
是否属于集合,需要计算其element
和hash
,并将modulo
与目标槽的内容进行比较。如果比较失败,搜索将在存储桶中线性进行。
在没有element
且增加bucket
的情况下,删除元素会有些困难,但是您会明白的。
如果您真的想了解所有这些工作,请继续进行调试,并调试任何Smalltalk方言中indexes
的基本操作。保证有很多乐趣。