Class DoublyLinkedList<E, R>

Doubly linked list with O(1) push/pop/unshift/shift and linear scans.

Time O(1), Space O(1)

// basic DoublyLinkedList creation and push operation
// Create a simple DoublyLinkedList with initial values
const list = new DoublyLinkedList([1, 2, 3, 4, 5]);

// Verify the list maintains insertion order
console.log([...list]); // [1, 2, 3, 4, 5];

// Check length
console.log(list.length); // 5;

// Push a new element to the end
list.push(6);
console.log(list.length); // 6;
console.log([...list]); // [1, 2, 3, 4, 5, 6];
// DoublyLinkedList pop and shift operations
const list = new DoublyLinkedList<number>([10, 20, 30, 40, 50]);

// Pop removes from the end
const last = list.pop();
console.log(last); // 50;

// Shift removes from the beginning
const first = list.shift();
console.log(first); // 10;

// Verify remaining elements
console.log([...list]); // [20, 30, 40];
console.log(list.length); // 3;
// DoublyLinkedList for...of iteration and map operation
const list = new DoublyLinkedList<number>([1, 2, 3, 4, 5]);

// Iterate through list
const doubled = list.map(value => value * 2);
console.log(doubled.length); // 5;

// Use for...of loop
const result: number[] = [];
for (const item of list) {
result.push(item);
}
console.log(result); // [1, 2, 3, 4, 5];
// Browser history
const browserHistory = new DoublyLinkedList<string>();

browserHistory.push('home page');
browserHistory.push('search page');
browserHistory.push('details page');

console.log(browserHistory.last); // 'details page';
console.log(browserHistory.pop()); // 'details page';
console.log(browserHistory.last); // 'search page';
// DoublyLinkedList for LRU cache implementation
interface CacheEntry {
key: string;
value: string;
}

// Simulate LRU cache using DoublyLinkedList
// DoublyLinkedList is perfect because:
// - O(1) delete from any position
// - O(1) push to end
// - Bidirectional traversal for LRU policy

const cacheList = new DoublyLinkedList<CacheEntry>();
const maxSize = 3;

// Add cache entries
cacheList.push({ key: 'user:1', value: 'Alice' });
cacheList.push({ key: 'user:2', value: 'Bob' });
cacheList.push({ key: 'user:3', value: 'Charlie' });

// Try to add a new entry when cache is full
if (cacheList.length >= maxSize) {
// Remove the oldest (first) entry
const evicted = cacheList.shift();
console.log(evicted?.key); // 'user:1';
}

// Add new entry
cacheList.push({ key: 'user:4', value: 'Diana' });

// Verify current cache state
console.log(cacheList.length); // 3;
const cachedKeys = [...cacheList].map(entry => entry.key);
console.log(cachedKeys); // ['user:2', 'user:3', 'user:4'];

// Access entry (in real LRU, this would move it to end)
const foundEntry = [...cacheList].find(entry => entry.key === 'user:2');
console.log(foundEntry?.value); // 'Bob';

Type Parameters

  • E = any
  • R = any
    1. Node Structure: Each node contains three parts: a data field, a pointer (or reference) to the previous node, and a pointer to the next node. This structure allows traversal of the linked list in both directions.
    2. Bidirectional Traversal: Unlike singly linked lists, doubly linked lists can be easily traversed forwards or backwards. This makes insertions and deletions in the list more flexible and efficient.
    3. No Centralized Index: Unlike arrays, elements in a linked list are not stored contiguously, so there is no centralized index. Accessing elements in a linked list typically requires traversing from the head or tail node.
    4. High Efficiency in Insertion and Deletion: Adding or removing elements in a linked list does not require moving other elements, making these operations more efficient than in arrays. Caution: Although our linked list classes provide methods such as at, setAt, addAt, and indexOf that are based on array indices, their time complexity, like that of the native Array.lastIndexOf, is 𝑂(𝑛). If you need to use these methods frequently, you might want to consider other data structures, such as Deque or Queue (designed for random access). Similarly, since the native Array.shift method has a time complexity of 𝑂(𝑛), using an array to simulate a queue can be inefficient. In such cases, you should use Queue or Deque, as these data structures leverage deferred array rearrangement, effectively reducing the average time complexity to 𝑂(1).

Hierarchy

Constructors

  • Create a DoublyLinkedList and optionally bulk-insert elements.

    Type Parameters

    • E = any
    • R = any

    Parameters

    • Optionalelements: Iterable<E, any, any> | Iterable<R, any, any> | Iterable<DoublyLinkedListNode<E>, any, any> = []

      Iterable of elements or nodes (or raw records if toElementFn is provided).

    • Optionaloptions: DoublyLinkedListOptions<E, R>

      Options such as maxLen and toElementFn.

    Returns DoublyLinkedList<E, R>

    New DoublyLinkedList instance.

    Time O(N), Space O(N)

Properties

_toElementFn?: ((rawElement: R) => E)

The converter used to transform a raw element (R) into a public element (E).

Time O(1), Space O(1).

Accessors

  • get maxLen(): number
  • Upper bound for length (if positive), or -1 when unbounded.

    Returns number

    Maximum allowed length.

    Time O(1), Space O(1)

  • get toElementFn(): undefined | ((rawElement: R) => E)
  • Exposes the current toElementFn, if configured.

    Returns undefined | ((rawElement: R) => E)

    The converter function or undefined when not set.

    Time O(1), Space O(1).

Methods

  • (Protected) Create an empty instance of the same concrete class.

    Parameters

    • Optionaloptions: LinearBaseOptions<E, R>

      Options forwarded to the constructor.

    Returns this

    An empty like-kind list instance.

    Time O(1), Space O(1)

  • Internal iterator factory used by the default iterator.

    Returns IterableIterator<E, any, any>

    An iterator over elements.

    Implementations should yield in O(1) per element with O(1) extra space when possible.

  • Reverse-direction iterator over elements.

    Returns IterableIterator<E, any, any>

    Iterator of elements from tail to head.

    Time O(n), Space O(1)

  • Returns an iterator over the structure's elements.

    Parameters

    • Rest...args: unknown[]

      Optional iterator arguments forwarded to the internal iterator.

    Returns IterableIterator<E, any, any>

    An IterableIterator<E> that yields the elements in traversal order.

    Producing the iterator is O(1); consuming the entire iterator is Time O(n) with O(1) extra space.

  • Insert a new element/node at an index, shifting following nodes.

    Parameters

    Returns boolean

    True if inserted.

    Time O(N), Space O(1)

  • Concatenate lists/elements preserving order.

    Parameters

    • Rest...items: LinearBase<E, R, LinkedListNode<E>>[]

      Elements or LinearBase instances.

    Returns this

    New list with combined elements (this type).

    Time O(sum(length)), Space O(sum(length))

  • Delete the element at an index.

    Parameters

    • index: number

      Zero-based index.

    Returns undefined | E

    Removed element or undefined.

    Time O(N), Space O(1)

  • Tests whether all elements satisfy the predicate.

    Parameters

    • predicate: ElementCallback<E, R, boolean>

      Function invoked for each element with signature (value, index, self).

    • OptionalthisArg: unknown

      Optional this binding for the predicate.

    Returns boolean

    true if every element passes; otherwise false.

    Time O(n) in the worst case; may exit early when the first failure is found. Space O(1).

  • Fill a range with a value.

    Parameters

    • value: E

      Value to set.

    • start: number = 0

      Inclusive start.

    • end: number = ...

      Exclusive end.

    Returns this

    This list.

    Time O(n), Space O(1)

  • Filter values into a new list of the same class.

    Parameters

    • callback: ElementCallback<E, R, boolean>

      Predicate (value, index, list) → boolean to keep value.

    • OptionalthisArg: any

      Value for this inside the callback.

    Returns this

    A new list with kept values.

    Time O(N), Space O(N)

  • Finds the first element that satisfies the predicate and returns it.

    Finds the first element of type S (a subtype of E) that satisfies the predicate and returns it.

    Type Parameters

    • S

    Parameters

    • predicate: ElementCallback<E, R, S>

      Type-guard predicate: (value, index, self) => value is S.

    • OptionalthisArg: unknown

      Optional this binding for the predicate.

    Returns undefined | S

    The matched element typed as S, or undefined if not found.

    Time O(n) in the worst case; may exit early on the first match. Space O(1).

  • Find the first index matching a predicate.

    Parameters

    • predicate: ElementCallback<E, R, boolean>

      (element, index, self) => boolean.

    • OptionalthisArg: any

      Optional this for callback.

    Returns number

    Index or -1.

    Time O(n), Space O(1)

  • Invokes a callback for each element in iteration order.

    Parameters

    • callbackfn: ElementCallback<E, R, void>

      Function invoked per element with signature (value, index, self).

    • OptionalthisArg: unknown

      Optional this binding for the callback.

    Returns void

    void.

    Time O(n), Space O(1).

  • Checks whether a strictly-equal element exists in the structure.

    Parameters

    • element: E

      The element to test with === equality.

    Returns boolean

    true if an equal element is found; otherwise false.

    Time O(n) in the worst case. Space O(1).

  • Linked-list optimized indexOf (forwards scan).

    Parameters

    • searchElement: E

      Value to match.

    • fromIndex: number = 0

      Start position.

    Returns number

    Index or -1.

    Time O(n), Space O(1)

  • Join all elements into a string.

    Parameters

    • separator: string = ','

      Separator string.

    Returns string

    Concatenated string.

    Time O(n), Space O(n)

  • Linked-list optimized lastIndexOf (reverse scan).

    Parameters

    • searchElement: E

      Value to match.

    • fromIndex: number = ...

      Start position.

    Returns number

    Index or -1.

    Time O(n), Space O(1)

  • Map values into a new list (possibly different element type).

    Type Parameters

    • EM
    • RM

    Parameters

    • callback: ElementCallback<E, R, EM>

      Mapping function (value, index, list) → newElement.

    • Optionaloptions: DoublyLinkedListOptions<EM, RM>

      Options for the output list (e.g., maxLen, toElementFn).

    • OptionalthisArg: any

      Value for this inside the callback.

    Returns DoublyLinkedList<EM, RM>

    A new DoublyLinkedList with mapped values.

    Time O(N), Space O(N)

  • Map values into a new list of the same class.

    Parameters

    • callback: ElementCallback<E, R, E>

      Mapping function (value, index, list) → newValue.

    • OptionalthisArg: any

      Value for this inside the callback.

    Returns this

    A new list with mapped values.

    Time O(N), Space O(N)

  • Prints toVisual() to the console. Intended for quick debugging.

    Returns void

    void.

    Time O(n) due to materialization, Space O(n) for the intermediate representation.

  • Append a sequence of elements/nodes.

    Parameters

    • elements: Iterable<E, any, any> | Iterable<R, any, any> | Iterable<DoublyLinkedListNode<E>, any, any>

      Iterable of elements or nodes (or raw records if toElementFn is provided).

    Returns boolean[]

    Array of per-element success flags.

    Time O(N), Space O(1)

  • Right-to-left reduction using reverse iterator.

    Type Parameters

    • U

    Parameters

    • callbackfn: ReduceLinearCallback<E, U>

      (acc, element, index, self) => acc.

    • initialValue: U

      Initial accumulator.

    Returns U

    Final accumulator.

    Time O(n), Space O(1)

  • Set the element value at an index.

    Parameters

    • index: number

      Zero-based index.

    • value: E

      New value.

    Returns boolean

    True if updated.

    Time O(N), Space O(1)

  • Set the equality comparator used to compare values.

    Parameters

    • equals: ((a: E, b: E) => boolean)

      Equality predicate (a, b) → boolean.

        • (a, b): boolean
        • Parameters

          Returns boolean

    Returns this

    This list.

    Time O(1), Space O(1)

  • Slice via forward iteration (no random access required).

    Parameters

    • start: number = 0

      Inclusive start (supports negative index).

    • end: number = ...

      Exclusive end (supports negative index).

    Returns this

    New list (this type).

    Time O(n), Space O(n)

  • Tests whether at least one element satisfies the predicate.

    Parameters

    • predicate: ElementCallback<E, R, boolean>

      Function invoked for each element with signature (value, index, self).

    • OptionalthisArg: unknown

      Optional this binding for the predicate.

    Returns boolean

    true if any element passes; otherwise false.

    Time O(n) in the worst case; may exit early on first success. Space O(1).

  • In-place stable order via array sort semantics.

    Parameters

    • OptionalcompareFn: ((a: E, b: E) => number)

      Comparator (a, b) => number.

        • (a, b): number
        • Parameters

          Returns number

    Returns this

    This container.

    Time O(n log n), Space O(n) (materializes to array temporarily)

  • Splice by walking node iterators from the start index.

    Parameters

    • start: number

      Start index.

    • deleteCount: number = 0

      How many elements to remove.

    • Rest...items: E[]

      Elements to insert after the splice point.

    Returns this

    Removed elements as a new list (this type).

    Time O(n + m), Space O(min(n, m)) where m = items.length

  • Snapshot elements into a reversed array.

    Returns E[]

    New reversed array.

    Time O(n), Space O(n)

  • Returns a representation of the structure suitable for quick visualization. Defaults to an array of elements; subclasses may override to provide richer visuals.

    Returns E[]

    A visual representation (array by default).

    Time O(n), Space O(n).

  • Prepend a sequence of elements/nodes.

    Parameters

    • elements: Iterable<E, any, any> | Iterable<R, any, any> | Iterable<DoublyLinkedListNode<E>, any, any>

      Iterable of elements or nodes (or raw records if toElementFn is provided).

    Returns boolean[]

    Array of per-element success flags.

    Time O(N), Space O(1)

  • Returns an iterator over the values (alias of the default iterator).

    Returns IterableIterator<E, any, any>

    An IterableIterator<E> over all elements.

    Creating the iterator is O(1); full iteration is Time O(n), Space O(1).

  • Create a new list from an array of elements.

    Type Parameters

    • E
    • R = any

    Parameters

    • this: Object

      The constructor (subclass) to instantiate.

    • data: E[]

      Array of elements to insert.

    Returns any

    A new list populated with the array's elements.

    Time O(N), Space O(N)