@node-dlc/core
Version:
104 lines • 3.06 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LinkedList = void 0;
const LinkedListNode_1 = require("./LinkedListNode");
/**
* Implementation of a doubly linked-list that maintains both head and tail.
* Tail maintenance allows for O(1) insertions at tail
*/
class LinkedList {
constructor() {
this.length = 0;
this.head = null;
this.tail = null;
}
/**
* Adds a node to the end of a linked List
* @param T value
* @returns {LinkedListNode}
*/
add(value) {
const node = new LinkedListNode_1.LinkedListNode(value);
// when empty list
if (!this.head) {
this.head = node;
this.tail = node;
this.length++;
return node;
}
// non-empty, append to tail
node.prev = this.tail;
this.tail.next = node;
this.tail = node;
this.length++;
return node;
}
/**
* Finds the node at a specific position
*/
valueAt(index) {
const node = this.nodeAt(index);
if (node)
return node.value;
}
/**
* Finds the node for the index or throws an out of range exception
*/
nodeAt(index) {
// error when index out of range
if (index < 0 || index > this.length) {
throw new RangeError('Index out of range');
}
// seek until index is found
let currentNode = this.head;
let count = 0;
while (count < index) {
currentNode = currentNode.next;
count++;
}
return currentNode;
}
/**
* Removes the node at the index and returns its value.
* Head or tail removal is an O(1) operation. For removal of other indexes
* is at worst O(N).
*/
remove(index) {
// error when index out of range
if (index < 0 || index > this.length) {
throw new RangeError('Index out of range');
}
let removeNode;
let prevNode = null;
let nextNode = null;
// first node simply removes the node at the tip
if (index === 0) {
removeNode = this.head;
nextNode = this.head.next;
// adjust head
this.head = nextNode;
}
// last node, update the tail and mark next as null
if (index === this.length - 1) {
removeNode = this.tail;
prevNode = this.tail.prev;
// adjust tail
this.tail = prevNode;
}
// middle node
if (!removeNode) {
removeNode = this.nodeAt(index);
prevNode = removeNode.prev;
nextNode = removeNode.next;
}
// splice out the node afer null checking
if (prevNode)
prevNode.next = nextNode;
if (nextNode)
nextNode.prev = prevNode;
this.length--;
return removeNode.value;
}
}
exports.LinkedList = LinkedList;
//# sourceMappingURL=LinkedList.js.map