Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.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
数组函数的JavaScript运行时复杂性_Javascript_Arrays_Time Complexity - Fatal编程技术网

数组函数的JavaScript运行时复杂性

数组函数的JavaScript运行时复杂性,javascript,arrays,time-complexity,Javascript,Arrays,Time Complexity,JS标准是否定义了常见的数组函数(如推送、弹出、移位、切片或拼接)的运行时复杂性?特别是,我对在随机位置删除和插入条目感兴趣。如果未定义复杂性,我可以期望什么,例如在V8中 (这个问题的灵感来源于。另外,发帖也让我好奇,但也许这是一些不相关的现象。) (一个非常相关的问题是。然而,对公认答案的一个评论说,它现在是错误的。而且,公认答案没有任何参考,说明标准确实是这样定义的。)。但是,ECMA规范没有规定边界复杂性,您可以从规范的算法中派生一个 push是O(1),但实际上,由于需要重新分配插槽阵

JS标准是否定义了常见的
数组
函数(如
推送
弹出
移位
切片
拼接
)的运行时复杂性?特别是,我对在随机位置删除和插入条目感兴趣。如果未定义复杂性,我可以期望什么,例如在V8中

(这个问题的灵感来源于。另外,发帖也让我好奇,但也许这是一些不相关的现象。)


(一个非常相关的问题是。然而,对公认答案的一个评论说,它现在是错误的。而且,公认答案没有任何参考,说明标准确实是这样定义的。)。

但是,ECMA规范没有规定边界复杂性,您可以从规范的算法中派生一个

push
是O(1),但实际上,由于需要重新分配插槽阵列,它将在引擎定义的边界处遇到O(N)拷贝成本。这些边界通常是对数的

pop
是O(1),具有与
push
类似的警告,但是很少遇到O(N)拷贝,因为它经常被折叠到垃圾收集中(例如,复制收集器只能复制阵列的已使用部分)

shift
最差为O(N),但在特殊情况下,它可以作为O(1)实现,代价是降低索引速度,因此您的里程数可能会有所不同

slice
是O(N),其中N是
end-start
。如果不显著降低对两个阵列的写入速度,这里就没有大量的优化机会

拼接
是最坏情况下的O(N)。有一些数组存储技术将N除以一个常数,但它们会显著降低索引速度。如果引擎使用这些技术,您可能会注意到在访问模式更改触发的存储技术之间切换时操作异常缓慢


您没有提到的一个是
sort
。在一般情况下,它是O(N logn)。但是,根据引擎选择的算法,在某些情况下可以得到O(N^2)。例如,如果引擎使用快速排序(即使插入排序有延迟),它也有众所周知的N^2个案例。这可能是应用程序的DoS源。如果这是一个问题,要么限制您排序的数组的大小(可能合并子数组),要么将其释放到HeapSort。

如果取数未知,则切片仅为线性。如果切片数为常量,则切片为常量,而不是线性

只是一个旁注,可以使用RingBuffer(i.O.w CircularQueue/CircularBuffer)数据结构在O(1)中实现
移位
/
取消移位
推送
方法。当循环缓冲区不需要增长时,最坏的情况是O(1)。有人真正衡量过这些行动的表现吗?用非常简单的话来说,知道总比猜测好。

按下->O(1)

弹出->O(1)

换档->O(N)

切片->O(N)

拼接->O(N)


是对JavaScript中数组的时间复杂性的完整解释。

这可能很好,但如果没有JavaScript的特定源代码,则很难验证。例如,我知道排序可以是O(NlogN),但在每种语言中都是这样吗?不。(还有,过滤、反向等等呢?)这些很难验证,但你可以相信它们的复杂性并不比规范中的算法差。至于
过滤
反向
它们是O(N)。那么
concat
呢?请提及
取消移位()
,我假设是O(N)同样,值得一提的是,即使是对你来说,这也是正确的。N中包含空元素。任何算法都可以这样说。如果数组中的元素数是常量,那么可以说对数组进行排序是一个常量时间操作。由于明显的原因,这不是非常有用的信息,因此所有的反对票都被否决了。是的,我在几个月前在一个jsperf上试用过它-shift和unshift确实执行得比O(1)更接近O(n),并且在使用大n时慢得多。执行此队列实现是为了避免移位和取消移位是的,没错
Array.prototype.splice
是一种通用的多功能工具,其复杂性取决于如何使用它。例如,它可以删除和/或添加最后一个元素(如push或pop),那么复杂性将是O(1);如果其执行与移位/取消移位相同,则其复杂性将为O(n)。还有其他的“中间”情况是可能的。是的,所以我们可以说,在最坏的情况下,仍然是O(n)。