Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.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_Node.js_Time Complexity_Constant Time - Fatal编程技术网

在JavaScript中创建忽略索引的数组结构

在JavaScript中创建忽略索引的数组结构,javascript,arrays,node.js,time-complexity,constant-time,Javascript,Arrays,Node.js,Time Complexity,Constant Time,数组中的索引(维护索引)使array.prototype.shift和array.prototype.unshiftO(N)而不是O(1) 但是,如果我们只想使用pop()/push()/shift()和unshift(),而从不使用索引进行查找,有没有办法实现一个忽略索引的JavaScript数组 我想不出一个办法。 我能想到的唯一方法是使用数组,并且只使用pop()/push()(因为它们是O(1))。。。但即使使用多个阵列,也不确定这是否可行 如果可能的话,希望在没有链接列表的情况下完成此

数组中的索引(维护索引)使
array.prototype.shift
array.prototype.unshift
O(N)而不是O(1)

但是,如果我们只想使用pop()/push()/shift()和unshift(),而从不使用索引进行查找,有没有办法实现一个忽略索引的JavaScript数组

我想不出一个办法。 我能想到的唯一方法是使用数组,并且只使用pop()/push()(因为它们是O(1))。。。但即使使用多个阵列,也不确定这是否可行

如果可能的话,希望在没有链接列表的情况下完成此操作。我用一个双链表实现了一个解决方案,但不知道是否有可能不用链表来实现


最终目标:尝试创建一个FIFO队列,其中所有操作都在固定时间内进行,而不使用链表。

如果存储的数据是基本数据(字符串、整数、浮点或基本数据的组合),则可以使用JavaScript,将其转换为适当的类型化数组视图,加载数据,然后自己跟踪偏移量

在您的示例中,
pop
shift
unshift
都可以通过递增/递减整数索引来实现<代码>推送更难,因为TypedArray的大小是固定的:如果ArrayBuffer已满,则只有两个选项是截断数据或分配新的类型数组,因为JS无法存储指针

如果要存储同质对象(它们具有相同的属性),可以使用不同的视图和偏移量将每个值保存到TypedArray中,以模拟C结构(参见MDN示例),然后使用JS函数从TypedArray序列化/取消序列化,基本上是从二进制表示转换数据,变成一个成熟的JS对象。

用整数索引的ES2015怎么样

让我们调用map
myFIFOMap

在FIFO类中保留一个
第一个
最后一个
整数成员。从零开始

每次您想
push()
进入FIFO队列时,都要调用
myFIFOMap.set(++last,item)
。而
pop()
看起来像:

const item = myFIFOMap.get(first); 
myFIFOMap.delete(first++); 
return item;
应该是
O(1)
来推动或弹出

不要忘记检查边界条件(例如,当
first==last
时,不要让它们
pop()


鉴于JavaScript实际上使用双精度浮点,您应该能够在整数精度出现问题之前运行FIFO。因此,如果您每秒通过FIFO运行10000个项目,这对于大约28000年的运行时间应该是有益的

根据@SomeCallMeTim的答案,我认为这是正确的,我有以下几点:

export class Queue {

  lookup = new Map<number, any>();
  first = 0;
  last = 0;
  length = 0;
  elementExists = false; // when first === last, and item exists there

  peek() {
    return this.lookup.get(this.first);
  }

  getByIndex(v: number) {
    return this.lookup.get(v);
  }

  getLength() {
    return this.length;
  }

  pop() {

    const last = this.last;

    if (this.elementExists && this.first === this.last) {
      this.length--;
      this.elementExists = false;
    }
    else if (this.last > this.first) {
      this.length--;
      this.last--;
    }

    const v = this.lookup.get(last);
    this.lookup.delete(last);
    return v;
  }

  shift() {

    const first = this.first;

    if (this.elementExists && this.first === this.last) {
      this.length--;
      this.elementExists = false;
    }
    else if (this.first < this.last) {
      this.length--;
      this.first++;
    }

    const v = this.lookup.get(first);
    this.lookup.delete(first);
    return v;
  }

  push(v: any) {

    this.length++;

    if (this.elementExists && this.first === this.last) {
      this.last++;
    }
    else if (this.first === this.last) {
      this.elementExists = true;
    }
    else {
      this.last++;
    }

    return this.lookup.set(this.last, v);

  }

  enq(v: any) {
    return this.push.apply(this, arguments);
  }

  enqueue(v: any) {
    return this.push.apply(this, arguments);
  }

  deq() {
    return this.shift.apply(this, arguments);
  }

  dequeue() {
    return this.shift.apply(this, arguments);
  }

  unshift(v: any) {

    this.length++;

    if (this.elementExists && this.first === this.last) {
      this.first--;
    }
    else if (this.first === this.last) {
      this.elementExists = true;
    }
    else {
      this.first--;
    }

    return this.lookup.set(this.first, v);
  }

  addToFront(v: any){
    return this.unshift.apply(this,arguments);
  }

  removeAll() {
    return this.clear.apply(this, arguments);
  }

  clear(): void {
    this.length = 0;
    this.elementExists = false;
    this.first = 0;
    this.last = 0;
    this.lookup.clear();
  }

}
要获得队列中的第五个元素,我们需要做的就是:

getByIndex(4);

只需使用对象或映射并围绕它们构建那些方法?您可以构建一个链表,它将支持您在O(1)中提到的所有操作,仅使用对象/映射-不可能检索O(1)中的第一个/最后一个插入项。为了检索O(1)中的第一个/最后一个项目,您必须使用带有对象/映射的链表。@FelixKling但如果删除最后插入的项目会怎么样?您必须找到最后一项才能将其保存为最后一个键?听起来您需要构建另一个数据结构来支持这一点,但还不清楚您试图解决的是什么更高级别的问题。这是行不通的,因为(a)需要通用性,而不仅仅是存储原语,(b)不能固定大小,因为最有可能的用例是FIFO队列。是的,但如何取消移位/移位?我想你可以通过增加/减少两个字段来跟踪第一个和最后一个字段。我想知道负数/整数是否和keys@AlexanderMills:当然可以。键可以是任意值。@AlexanderMills是的,数字在地图中可以变成负数。因此,分别使用适当的减量/增量
first
,shift()/unshift()是有效的出于好奇,你为什么认为这比链表好?我不认为在
Map
中访问元素比从链表尾部获取元素快。根据
Map
访问时间平均小于O(n)而不是链接数据的O(1)List@FelixKling是的,我没有想过使用递增/递减整数,但这使我们有可能参考以前的研究成果items@Minderov在这种情况下,唯一能确定的方法是尝试两种不同的解决方案,然后看看哪一种更快。@AlexanderMills我同意。如果您要测试它,请在测试后返回结果。非常好奇!
getByIndex(4);