103 lines
2.2 KiB
JavaScript
103 lines
2.2 KiB
JavaScript
const head = Symbol("head");
|
|
|
|
class LinkedListNode {
|
|
constructor (data) {
|
|
this.data = data;
|
|
this.next = null;
|
|
}
|
|
}
|
|
|
|
export class LinkedList {
|
|
constructor () {
|
|
this[head] = null;
|
|
}
|
|
|
|
add (data) {
|
|
const newNode = new LinkedListNode(data);
|
|
|
|
if (this[head] === null) {
|
|
this[head] = newNode;
|
|
} else {
|
|
let current = this[head];
|
|
|
|
// Go to the end of the list
|
|
while (current.next !== null) {
|
|
current = current.next;
|
|
}
|
|
|
|
// On the last node, add the new node
|
|
current.next = 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) {
|
|
// Invalid index?
|
|
if ((this[head] === null) || (index < 0)) {
|
|
throw new RangeError(`Index ${index} does not exist in the list.`);
|
|
}
|
|
|
|
// Remove the first node
|
|
if (index === 0) {
|
|
const data = this[head].data;
|
|
|
|
// Replace the head with the next node
|
|
this[head] = this[head].next;
|
|
|
|
return data;
|
|
}
|
|
|
|
let current = this[head];
|
|
let previous = null;
|
|
let i = 0;
|
|
|
|
while ((current !== null) && (i < index)) {
|
|
// Save the current value
|
|
previous = current;
|
|
|
|
current = current.next;
|
|
|
|
i++;
|
|
}
|
|
|
|
// Remove the node if found
|
|
if (current !== null) {
|
|
// skip over the node to "remove" it
|
|
previous.next = current.next;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
[Symbol.iterator] () {
|
|
return this.values();
|
|
}
|
|
} |