创建一个循环队列

274 阅读2分钟

您将创建一个循环队列。循环队列是一种队列,它先写到一个集合的末尾,然后开始在集合的开头覆盖自己。这种类型的数据结构在某些情况下很有用。例如,一个循环队列可以用于流媒体。一旦队列满了,新的媒体数据将覆盖旧的数据

用一个长度为5的数组来说明这个概念的好方法是。

[null, null, null, null, null]。
 ^读 @ 0
 写入 @ 0

这里的读和写都在0的位置。现在队列得到了3条新的记录a、b和c,我们的队列现在看起来这样

[a, b, c, null, null]。
 ^Read @ 0
          ^Write @ 3

当读头读取时,它可以删除数值或保留它们。

[null, null, null, null, null]。
                   ^Read @ 3
                   ^Write @ 3

现在我们把d、e和f的值写到队列中。一旦写到数组的末端,它就会循环回到开头。

[f, null, null, d, e] 。
                ^Read @ 3
    ^Write@1

这种方法需要恒定的内存量,但可以处理更大的文件。

我们将实现一个循环队列。循环队列应该提供enqueue和dequeue方法,允许你从队列中读取和写入。该类本身也应该接受一个整数参数,你可以用它来指定创建队列时的大小。

当你向队列排队时,写指针应该向前推进,一旦到达队列的末端,就循环回到起点。enqueue方法如果成功的话,应该返回你所排队的项目;否则它将返回null。

同样地,当你去读queue项目时,读取指针应该向前推进。当你取消一个项目的queue时,该项目应该被返回。如果你不能取消一个项目,你应该返回null。

写指针不应该被允许移过读指针(我们的类不会让你覆盖你还没有读过的数据),读指针也不应该能够移过你已经写过的数据。

class CircularQueue {
  constructor(size) {
    this.queue = [];
    this.read = 0;
    this.write = 0;
    this.max = size - 1;

    while (size > 0) {
      this.queue.push(null);
      size--;
    }
  }

  print() {
    return this.queue;
  }

  enqueue(item) {
    if (this.queue[this.write] === null) {
      this.queue[this.write++] = item;

      if (this.write > this.max) this.write = 0;
      return item;
    }
    return null;
  }

  dequeue() {
    if (this.queue[this.read] != null) {
      let item = this.queue[this.read];
      this.queue[this.read++] = null;
      if (this.read > this.max) this.read = 0;
      return item;
    }
    return null;
  }
}