Class SinglyLinkedList<E, R>

Singly linked list with O(1) push/pop-like ends operations and linear scans.

Time O(1), Space O(1)

// implementation of a basic text editor
class TextEditor {
private content: SinglyLinkedList<string>;
private cursorIndex: number;
private undoStack: Stack<{ operation: string; data?: any }>;

constructor() {
this.content = new SinglyLinkedList<string>();
this.cursorIndex = 0; // Cursor starts at the beginning
this.undoStack = new Stack<{ operation: string; data?: any }>(); // Stack to keep track of operations for undo
}

insert(char: string) {
this.content.addAt(this.cursorIndex, char);
this.cursorIndex++;
this.undoStack.push({ operation: 'insert', data: { index: this.cursorIndex - 1 } });
}

delete() {
if (this.cursorIndex === 0) return; // Nothing to delete
const deleted = this.content.deleteAt(this.cursorIndex - 1);
this.cursorIndex--;
this.undoStack.push({ operation: 'delete', data: { index: this.cursorIndex, char: deleted } });
}

moveCursor(index: number) {
this.cursorIndex = Math.max(0, Math.min(index, this.content.length));
}

undo() {
if (this.undoStack.size === 0) return; // No operations to undo
const lastAction = this.undoStack.pop();

if (lastAction!.operation === 'insert') {
this.content.deleteAt(lastAction!.data.index);
this.cursorIndex = lastAction!.data.index;
} else if (lastAction!.operation === 'delete') {
this.content.addAt(lastAction!.data.index, lastAction!.data.char);
this.cursorIndex = lastAction!.data.index + 1;
}
}

getText(): string {
return [...this.content].join('');
}
}

// Example Usage
const editor = new TextEditor();
editor.insert('H');
editor.insert('e');
editor.insert('l');
editor.insert('l');
editor.insert('o');
console.log(editor.getText()); // 'Hello' // Output: "Hello"

editor.delete();
console.log(editor.getText()); // 'Hell' // Output: "Hell"

editor.undo();
console.log(editor.getText()); // 'Hello' // Output: "Hello"

editor.moveCursor(1);
editor.insert('a');
console.log(editor.getText()); // 'Haello'

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 doubly linked lists, singly linked lists can be easily traversed forwards but not backwards.
    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 (view full)

Constructors

  • Create a SinglyLinkedList and optionally bulk-insert elements.

    Type Parameters

    • E = any
    • R = any

    Parameters

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

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

    • Optionaloptions: SinglyLinkedListOptions<E, R>

      Options such as maxLen and toElementFn.

    Returns SinglyLinkedList<E, R>

    New SinglyLinkedList 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: SinglyLinkedListOptions<E, R>

      Options forwarded to the constructor.

    Returns this

    An empty like-kind list instance.

    Time O(1), Space O(1)

  • (Protected) Iterate values from head to tail.

    Returns IterableIterator<E, any, any>

    Iterator of values (E).

    Time O(N), Space O(1)

  • (Protected) Iterate values from tail to head.

    Returns IterableIterator<E, any, any>

    Iterator of values (E).

    Time O(N), Space O(N)

  • 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)

  • Delete the first node whose value matches a predicate.

    Parameters

    • predicate: ((value: E, index: number, list: this) => boolean)

      Predicate (value, index, list) → boolean to decide deletion.

        • (value, index, list): boolean
        • Parameters

          • value: E
          • index: number
          • list: this

          Returns boolean

    Returns boolean

    True if a node was removed.

    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 = any

    Parameters

    • callback: ElementCallback<E, R, EM>

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

    • Optionaloptions: SinglyLinkedListOptions<EM, RM>

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

    • OptionalthisArg: any

      Value for this inside the callback.

    Returns SinglyLinkedList<EM, RM>

    A new SinglyLinkedList 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<SinglyLinkedListNode<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)

  • Remove and/or insert elements at a position (array-like behavior).

    Parameters

    • start: number

      Start index (clamped to [0, length]).

    • OptionaldeleteCount: number = 0

      Number of elements to remove (default 0).

    • Optional Rest...items: E[]

      Elements to insert after start.

    Returns this

    A new list containing the removed elements (typed as this).

    Time O(N + M), Space O(M)

  • 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<SinglyLinkedListNode<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 iterable of elements.

    Type Parameters

    Parameters

    • this: Object

      The constructor (subclass) to instantiate.

    • data: Iterable<E, any, any>

      Iterable of elements to insert.

    • Optionaloptions: SinglyLinkedListOptions<E, R>

      Options forwarded to the constructor.

    Returns S

    A new list populated with the iterable's elements.

    Time O(N), Space O(N)