standard-data-structures
Version:
A collection of standard data-structures for node and browser
181 lines (180 loc) • 4.45 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const option_1 = require("../immutable/option");
/* tslint:disable strict-comparisons */
/**
* A node for the linked list
*/
class LinkedListNode {
constructor(value) {
this.value = value;
this.right = undefined;
this.left = undefined;
}
}
exports.LinkedListNode = LinkedListNode;
/**
* A doubly linked list
*/
class DoublyLinkedList {
constructor(values) {
/**
* Returns the size of the linked list
*/
this.length = 0;
this.headN = undefined;
this.tailN = undefined;
for (const i of values) {
this.add(i);
}
}
/**
* Converts the doubly linked list into an array
*/
get asArray() {
return this.fold(new Array(), (a, b) => {
b.push(a);
return b;
});
}
/**
* Returns the first element of the list
*/
get head() {
return this.headN === undefined ? undefined : this.headN.value;
}
/**
* Returns true if the list is empty
*/
get isEmpty() {
return this.length === 0;
}
/**
* Returns the last element in the list
*/
get tail() {
return this.tailN === undefined ? undefined : this.tailN.value;
}
/**
* Creates a new DoublyLinkedList with the provided values.
*/
static of(...t) {
return new DoublyLinkedList(t);
}
/**
* Adds a new value to the list
*/
add(val) {
const node = new LinkedListNode(val);
if (this.length === 0) {
this.headN = node;
}
if (this.tailN === undefined) {
this.tailN = node;
}
else {
this.tailN.right = node;
node.left = this.tailN;
this.tailN = node;
}
this.length += 1;
return node;
}
/**
* Cleans removes all the elements from the list
*/
empty() {
this.length = 0;
this.headN = this.tailN = undefined;
}
/**
* Refer [[ICollection.filter]]
*/
filter(F) {
const elm = DoublyLinkedList.of();
this.fold(true, A => {
elm.add(A);
return false;
});
return elm;
}
/**
* Converts the linked list into a value
*/
fold(seed, f) {
let node = this.headN;
let result = seed;
while (node !== undefined) {
result = f(node.value, result);
node = node.right;
}
return result;
}
/**
* Tests if the provided node is a part of the list or not in O(n) time complexity.
*/
isConnected(n) {
return (n === this.headN ||
((n.left !== undefined && n.left.right === n) ||
(n.right !== undefined && n.right.left === n)));
}
/**
* Transforms the values inside the list using the transformer function, creating a new list.
*/
map(ab) {
return this.fold(DoublyLinkedList.of(), (a, l) => {
l.add(ab(a));
return l;
});
}
/**
* Removes the last inserted element
*/
pop() {
const h = this.tailN;
if (h !== undefined) {
this.remove(h);
return option_1.Option.some(h.value);
}
return option_1.Option.none();
}
/**
* Removes the provided node from the list.
*/
remove(n) {
if (!this.isConnected(n)) {
return;
}
if (n.left !== undefined && n.right !== undefined) {
n.left.right = n.right;
n.right.left = n.left;
}
else if (n.left !== undefined) {
this.tailN = n.left;
n.left.right = undefined;
}
else if (n.right !== undefined) {
this.headN = n.right;
n.right.left = undefined;
}
else {
this.tailN = undefined;
this.headN = undefined;
}
if (this.length > 0) {
this.length -= 1;
}
}
/**
* Remove the first element from the list
*/
shift() {
const h = this.headN;
if (h !== undefined) {
this.remove(h);
return option_1.Option.some(h.value);
}
return option_1.Option.none();
}
}
exports.DoublyLinkedList = DoublyLinkedList;