为什么 shift 比 pop 慢?JS 中队列的实现

发布时间:2022-11-21 19:00

我们知道在 JS 中,删除数组元素有两个方法:popshift,分别可以删除末尾与开头的元素。

然而同样是删除元素,它们的执行时间确实不同的。

当数组项目较多时,shift 的执行时间明显长于 pop

const test = (arrLength) => {
  let arr1 = []
  console.time(`${arrLength}-arr1`)
  for (let i = 0; i < arrLength; i++) {
    arr1.push(i)
  }
  for (let i = 0; i < arrLength; i++) {
    arr1.pop()
  }
  console.timeEnd(`${arrLength}-arr1`)

  let arr2 = []
  console.time(`${arrLength}-arr2`)
  for (let i = 0; i < arrLength; i++) {
    arr2.push(i)
  }
  for (let i = 0; i < arrLength; i++) {
    arr2.shift()
  }
  console.timeEnd(`${arrLength}-arr2`)
}

test(10 ** 5)
test(10 ** 6)

结果如下:

为什么 shift 比 pop 慢?JS 中队列的实现_第1张图片

这是因为 pop 删除元素后不需要改变其他元素的索引,时间复杂度为 O(1);而调用 shift 方法删除开头元素后,需要维护数组的索引,相当于对数组中的所有元素都进行了一次赋值操作,其时间复杂度为 O(n)

栈与队列

栈与队列是我们常用的两种数据结构。

栈的元素先进后出,比如函数栈,函数递归调用时,后调用的函数先执行完。

队列的元素先进先出,比如任务队列,任务按照派发的顺序依次执行。

在 JS 中,栈可以看成只调用 pushpop 方法的数组,队列可以看成是只调用 shiftpush 方法的数组。

然而在之前的例子中也看到了,当处理大量数据时,把数组直接当成队列使用性能非常差。

所以,我们要设法实现队列这一数据结构。

如何实现?

开始之前我们要明确实现的目标,我们实现的队列要提供以下几个功能:

  • 存储数据:队列要能够按序存储数据
  • push:添加元素的唯一方法,将元素添加进队列尾部的方法,并返回队列长度
  • shift:删除元素的唯一方法,将队首元素删除的方法,并返回删除的元素
  • length:可以通过 length 属性访问队列的长度
  • 访问元素:一般队列会允许访问队头与队尾的元素

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号