Исходя из ответа @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()
, как указывает предложение Тима.
Использование карты на удивление на ~ 10% быстрее, чем POJSO, возможно, только потому, что с POJSOцелые числа должны быть преобразованы в строки для поиска.
Реализация Map примерно на 20% быстрее, чем двусвязный список, поэтому двусвязный список не намного медленнее.Вероятно, это медленнее в основном потому, что мы должны создать контейнерный объект с указателями next / prev для каждого элемента в очереди, тогда как при реализации несвязанного списка мы можем вставлять примитивы в очередь и т. Д.
Двусвязный список позволяет нам удалять / вставлять элементы из середины очереди в постоянное время;мы не можем сделать то же самое с реализацией несвязанного списка, как есть.
Все вышеперечисленное на несколько порядков более производительно, чем обычный массив при работе с массивом с более чем 10 000элементов или около того.
У меня есть несколько реализаций очереди с постоянным временем здесь: https://github.com/ORESoftware/linked-queue
У Тима было хорошее предложение, чтобы сделать 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);