1
0
Fork 0
computer-science-in-javascript/src/structures/doubly-linked-list.js

117 lines
2.6 KiB
JavaScript

const head = Symbol("head");
const tail = Symbol("tail");
class DoublyLinkedListNode {
constructor (data) {
this.data = data;
this.next = null;
this.previous = null;
}
}
export class DoublyLinkedList {
constructor () {
this[head] = null;
this[tail] = null;
}
add (data) {
const newNode = new DoublyLinkedListNode(data);
// special case: no nodes
if (this[head] === null) {
this[head] = newNode;
} else {
// link the current tail and new tail
this[tail].next = newNode;
newNode.previous = this[tail];
}
// re-assign the tail
this[tail] = newNode;
}
get (index) {
if ( ! Number(index) < 0) {
return undefined;
}
let current = this[head];
let i = 0;
while ((current !== null) && (i < index)) {
current = current.next;
i++;
}
return current !== null
? current.data
: undefined;
}
remove (index) {
if ((this[head] === null) || (index < 0)) {
throw new RangeError(`Index ${index} does not exist in the list.`);
}
// special case: removing the first node
if (index === 0) {
const data = this[head].data;
this[head] = this[head].next;
// Only one node
if (this[head] === null) {
this[tail] = null;
} else {
this[head].previous = null;
}
return data;
}
let current = this[head];
let i = 0;
while ((current !== null) && (i < index)) {
current = current.next;
i++;
}
// If node was found remove it
if (current !== null) {
current.previous.next = current.next;
// last node
if (this[tail] === current) {
this[tail] = current.previous;
} else {
current.next.previous = current.previous;
}
return current.data;
}
throw new RangeError(`Index ${index} does not exist in the list.`);
}
*values () {
let current = this[head];
while (current !== null) {
yield current.data;
current = current.next;
}
}
*reverse () {
let current = this[tail];
while (current !== null) {
yield current.data;
current = current.previous;
}
}
[Symbol.iterator] () {
return this.values();
}
}