Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Search 什么';O(1)怎么了?_Search_Collections_Complexity Theory_Data Access - Fatal编程技术网

Search 什么';O(1)怎么了?

Search 什么';O(1)怎么了?,search,collections,complexity-theory,data-access,Search,Collections,Complexity Theory,Data Access,在讨论涉及散列和搜索类型的算法时,我注意到O(1)的一些非常奇怪的用法,通常是在使用语言系统提供的字典类型,或者使用使用数组索引表示法的字典或散列数组类型的上下文中 基本上,O(1)表示由恒定时间和(通常)固定空间限定。一些非常基本的操作是O(1),尽管使用中间语言和特殊VM往往会扭曲人们在这里的想法(例如,如何将垃圾收集器和其他动态进程分摊到原本是O(1)活动的部分上) 但是忽略延迟的摊销、垃圾收集等,我仍然不明白,除非在非常特殊的条件下,否则假设某些涉及某种搜索的技术可以是O(1)的飞跃 虽

在讨论涉及散列和搜索类型的算法时,我注意到O(1)的一些非常奇怪的用法,通常是在使用语言系统提供的字典类型,或者使用使用数组索引表示法的字典或散列数组类型的上下文中

基本上,O(1)表示由恒定时间和(通常)固定空间限定。一些非常基本的操作是O(1),尽管使用中间语言和特殊VM往往会扭曲人们在这里的想法(例如,如何将垃圾收集器和其他动态进程分摊到原本是O(1)活动的部分上)

但是忽略延迟的摊销、垃圾收集等,我仍然不明白,除非在非常特殊的条件下,否则假设某些涉及某种搜索的技术可以是O(1)的飞跃

虽然我以前已经注意到了这一点,但在

正如我在这里所说的,我所知道的唯一一个提供O(1)访问作为保证绑定的集合是一个具有整数索引值的固定绑定数组。假设数组是通过映射到随机访问内存来实现的,该内存使用O(1)操作来定位具有该索引的单元

对于涉及某种搜索以确定不同类型索引(或具有整数索引的稀疏数组)的匹配单元格的位置的集合,生活并不那么容易。特别是,如果存在碰撞并且可能出现拥塞,则访问不完全是O(1)。如果收集是灵活的,则必须确认并分摊扩展底层结构(如树或哈希表)的成本,以缓解拥塞(例如,高冲突发生率或树不平衡)

我从未想过将这些灵活的动态结构称为O(1)。然而,我看到它们被作为O(1)解决方案提供,而没有确定必须保持的条件,以确保O(1)的实际访问(以及常数小到可以忽略不计)

问题:所有这些准备都是为了一个问题。O(1)的随意性是什么?为什么它被如此盲目地接受?是否认识到即使O(1)接近常数,也可能是不希望的大?或者O(1)只是将计算复杂性的概念用于非正式用途?我很困惑

更新:答案和评论指出了我对自己定义O(1)的随意性,我已经修复了这一点。我仍然在寻找好的答案,在一些情况下,一些评论线程比它们的答案更有趣。

哈希表查找相对于表中的项目数是O(1),因为无论您向列表中添加多少项目,对单个项目进行哈希处理的成本基本相同,创建散列将告诉您项目的地址



为了回答为什么这是相关的:OP问为什么O(1)看起来如此随意地被抛来抛去,而在他看来,它显然不适用于许多情况。这个答案解释了O(1)时间在这些情况下确实是可能的。

我认为,当许多人把“O(1)”这个词抛在脑后时,他们隐含着一个“小”常数,不管“小”在他们的上下文中是什么意思

你必须根据上下文和常识进行所有这些大O分析。它可能是一个非常有用的工具,也可能是荒谬的,这取决于你如何使用它。

我的理解是O(1)不一定是常数;相反,它并不取决于所考虑的变量。因此,就散列中的元素数量而言,散列查找可以说是O(1),但就被散列的数据的长度或散列中的元素与桶的比率而言,散列查找不是O(1)


混淆的另一个因素是大O符号描述了限制行为。因此,一个函数f(N)对于N的小值可能确实显示出很大的变化,但是如果当N接近无穷大时,极限相对于N是常数,那么你仍然可以正确地说它是O(1)。

我可以理解你的意思,但我认为有两个基本假设支持这样的说法,即哈希表中的查找具有O(1)的复杂性

  • 哈希函数的合理设计是为了避免大量冲突
  • 这组密钥几乎是随机分布的,或者至少不是故意设计来让散列函数性能不佳的

哈希表查找的最坏情况复杂性为O(n),但考虑到上述两个假设,这是极不可能的。

一般来说,我认为人们使用它们时比较不考虑准确性。例如,如果设计得好,并且有一个好的散列,则基于散列的数据结构是O(1)(平均)查找。如果所有内容都散列到一个bucket,那么它就是O(n)。一般来说,虽然使用了一个好的算法,并且密钥分布合理,所以可以方便地将其称为O(1),而不需要所有的条件。同样,对于列表、树等,我们考虑到了某些实现,在讨论一般性时,讨论它们更方便,而不需要限定条件。另一方面,如果我们讨论的是具体的实现,那么可能更精确一些是值得的。

哈希表实现实际上并没有“精确地”使用O(1),如果您测试一个,您会发现它们的平均查找次数大约为1.5次,以在一个大数据集中找到给定的键

(由于碰撞确实发生,并且在碰撞时,必须指定不同的位置)

此外,在实践中,hashmap由具有初始大小的数组支持,即当其平均满度达到70%时,“增长”到两倍大小,这提供了相对较好的寻址空间。满度达到70%后,碰撞率增长更快

大O理论指出,如果你有一个O(1)算法,甚至是一个
array[18] = ("Name", "Bob")
array[32] = ("Occupation", "Student")
array[74] = ("Location", "Earth")
array[29] = ("Pet", "Dog")