与@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()
,正如蒂姆的建议所指出的那样,您可以致电 。
使用 Map 比 POJSO 快约 10%,这可能只是因为使用 POJSO 需要将整数转换为字符串以进行查找。
Map 实现比双向链表快约 20%,因此双向链表并没有那么慢。它可能更慢,主要是因为我们必须为队列中的每个项目创建一个带有 next/prev 指针的容器对象,而使用非链表实现,我们可以在队列中插入原语等。
双向链表允许我们在恒定时间内从队列中间删除/插入项目;我们不能对非链表实现做同样的事情。
当对具有超过 10,000 个元素左右的数组进行操作时,上述所有内容的性能都比普通数组高出几个数量级。
我在这里有一些恒定时间队列实现:
https ://github.com/ORESoftware/linked-queue
Tim 有一个很好的建议,让 getByIndex() 更容易使用——我们可以这样做:
getByIndex(v: number) {
if(!Number.isInteger(v)){
throw new Error('Argument must be an integer.');
}
return this.lookup.get(v + this.first);
}
以这种方式获取队列中的第 5 个元素,我们需要做的就是:
getByIndex(4);