UNPKG

standard-data-structures

Version:

A collection of standard data-structures for node and browser

181 lines (180 loc) 4.45 kB
"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;