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