data-structure-typed 1.52.8 → 1.52.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +13 -13
  3. package/benchmark/report.html +13 -13
  4. package/benchmark/report.json +146 -146
  5. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +4 -4
  6. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js +4 -4
  7. package/dist/cjs/data-structures/binary-tree/avl-tree-multi-map.js.map +1 -1
  8. package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +3 -3
  9. package/dist/cjs/data-structures/binary-tree/avl-tree.js +3 -3
  10. package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
  11. package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +62 -5
  12. package/dist/cjs/data-structures/binary-tree/binary-tree.js +26 -11
  13. package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
  14. package/dist/cjs/data-structures/binary-tree/bst.js +9 -14
  15. package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
  16. package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +3 -3
  17. package/dist/cjs/data-structures/binary-tree/rb-tree.js +8 -6
  18. package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
  19. package/dist/cjs/data-structures/binary-tree/tree-multi-map.d.ts +4 -5
  20. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js +9 -8
  21. package/dist/cjs/data-structures/binary-tree/tree-multi-map.js.map +1 -1
  22. package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.d.ts +4 -4
  23. package/dist/mjs/data-structures/binary-tree/avl-tree-multi-map.js +4 -4
  24. package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +3 -3
  25. package/dist/mjs/data-structures/binary-tree/avl-tree.js +3 -3
  26. package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +62 -5
  27. package/dist/mjs/data-structures/binary-tree/binary-tree.js +26 -11
  28. package/dist/mjs/data-structures/binary-tree/bst.js +9 -14
  29. package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +3 -3
  30. package/dist/mjs/data-structures/binary-tree/rb-tree.js +8 -6
  31. package/dist/mjs/data-structures/binary-tree/tree-multi-map.d.ts +4 -5
  32. package/dist/mjs/data-structures/binary-tree/tree-multi-map.js +9 -8
  33. package/dist/umd/data-structure-typed.js +58 -45
  34. package/dist/umd/data-structure-typed.min.js +5 -5
  35. package/dist/umd/data-structure-typed.min.js.map +1 -1
  36. package/package.json +6 -6
  37. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +4 -5
  38. package/src/data-structures/binary-tree/avl-tree.ts +3 -4
  39. package/src/data-structures/binary-tree/binary-tree.ts +26 -30
  40. package/src/data-structures/binary-tree/bst.ts +16 -19
  41. package/src/data-structures/binary-tree/rb-tree.ts +8 -6
  42. package/src/data-structures/binary-tree/tree-multi-map.ts +9 -8
  43. package/test/integration/bst.test.ts +2 -2
  44. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +20 -0
  45. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +37 -17
  46. package/test/unit/data-structures/binary-tree/bst.test.ts +11 -6
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/data-structures/base/iterable-entry-base.ts","../../src/data-structures/base/iterable-element-base.ts","../../src/utils/utils.ts","../../src/utils/number.ts","../../src/data-structures/hash/hash-map.ts","../../src/data-structures/linked-list/singly-linked-list.ts","../../src/data-structures/linked-list/doubly-linked-list.ts","../../src/data-structures/linked-list/skip-linked-list.ts","../../src/data-structures/stack/stack.ts","../../src/data-structures/queue/queue.ts","../../src/data-structures/queue/deque.ts","../../src/data-structures/heap/heap.ts","../../src/data-structures/heap/max-heap.ts","../../src/data-structures/heap/min-heap.ts","../../src/data-structures/graph/abstract-graph.ts","../../src/data-structures/graph/directed-graph.ts","../../src/data-structures/graph/undirected-graph.ts","../../src/data-structures/graph/map-graph.ts","../../src/constants/index.ts","../../src/data-structures/binary-tree/binary-tree.ts","../../src/data-structures/binary-tree/bst.ts","../../src/data-structures/binary-tree/binary-indexed-tree.ts","../../src/data-structures/binary-tree/segment-tree.ts","../../src/data-structures/binary-tree/avl-tree.ts","../../src/data-structures/binary-tree/rb-tree.ts","../../src/data-structures/binary-tree/avl-tree-multi-map.ts","../../src/data-structures/binary-tree/tree-multi-map.ts","../../src/data-structures/priority-queue/priority-queue.ts","../../src/data-structures/priority-queue/min-priority-queue.ts","../../src/data-structures/priority-queue/max-priority-queue.ts","../../src/data-structures/matrix/matrix.ts","../../src/data-structures/matrix/navigator.ts","../../src/data-structures/trie/trie.ts","../../src/data-structures/tree/tree.ts"],"sourcesContent":["export * from './data-structures';\nexport * from './utils';\nexport * from './interfaces';\nexport * from './types';\nexport * from './constants';\n","import { EntryCallback, ReduceEntryCallback } from '../../types';\n\nexport abstract class IterableEntryBase<K = any, V = any> {\n abstract get size(): number;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function is an implementation of the Symbol.iterator method that returns an iterable iterator.\n * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It\n * allows the function to accept any number of arguments as an array. In this case, the `args`\n * parameter is used to pass any additional arguments to the `_getIterator` method.\n */\n *[Symbol.iterator](...args: any[]): IterableIterator<[K, V]> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields key-value pairs from the object, where the value can\n * be undefined.\n */\n *entries(): IterableIterator<[K, V | undefined]> {\n for (const item of this) {\n yield item;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields the keys of a data structure.\n */\n *keys(): IterableIterator<K> {\n for (const item of this) {\n yield item[0];\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields the values of a collection.\n */\n *values(): IterableIterator<V> {\n for (const item of this) {\n yield item[1];\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `every` function checks if every element in a collection satisfies a given condition.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is\n * met for the current element in the iteration.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the first argument to the `predicate` function. If `thisArg` is not provided\n * @returns The `every` method is returning a boolean value. It returns `true` if every element in\n * the collection satisfies the provided predicate function, and `false` otherwise.\n */\n every(predicate: EntryCallback<K, V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item[1], item[0], index++, this)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The \"some\" function iterates over a collection and returns true if at least one element satisfies\n * a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is\n * met for the current element in the iteration.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided,\n * it will be passed as the first argument to the `predicate` function. If `thisArg` is\n * @returns a boolean value. It returns true if the predicate function returns true for any pair in\n * the collection, and false otherwise.\n */\n some(predicate: EntryCallback<K, V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item[1], item[0], index++, this)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `forEach` function iterates over each key-value pair in a collection and executes a callback\n * function for each pair.\n * @param callbackfn - The callback function that will be called for each element in the collection.\n * It takes four parameters: the value of the current element, the key of the current element, the\n * index of the current element, and the collection itself.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. If `thisArg` is provided, it will be\n * used as the `this` value when calling the callback function. If `thisArg` is not provided, `\n */\n forEach(callbackfn: EntryCallback<K, V, void>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n callbackfn.call(thisArg, value, key, index++, this);\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the entries of a collection and returns the first value for\n * which the callback function returns true.\n * @param callbackfn - The callback function that will be called for each entry in the collection. It\n * takes three arguments: the value of the entry, the key of the entry, and the index of the entry in\n * the collection. It should return a boolean value indicating whether the current entry matches the\n * desired condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The method `find` returns the value of the first element in the iterable that satisfies\n * the provided callback function. If no element satisfies the callback function, `undefined` is\n * returned.\n */\n find(callbackfn: EntryCallback<K, V, boolean>, thisArg?: any): [K, V] | undefined {\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n if (callbackfn.call(thisArg, value, key, index++, this)) return item;\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given key exists in a collection.\n * @param {K} key - The parameter \"key\" is of type K, which means it can be any type. It represents\n * the key that we want to check for existence in the data structure.\n * @returns a boolean value. It returns true if the key is found in the collection, and false\n * otherwise.\n */\n has(key: K): boolean {\n for (const item of this) {\n const [itemKey] = item;\n if (itemKey === key) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given value exists in a collection.\n * @param {V} value - The parameter \"value\" is the value that we want to check if it exists in the\n * collection.\n * @returns a boolean value, either true or false.\n */\n hasValue(value: V): boolean {\n for (const [, elementValue] of this) {\n if (elementValue === value) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `get` function retrieves the value associated with a given key from a collection.\n * @param {K} key - K (the type of the key) - This parameter represents the key that is being\n * searched for in the collection.\n * @returns The `get` method returns the value associated with the specified key if it exists in the\n * collection, otherwise it returns `undefined`.\n */\n get(key: K): V | undefined {\n for (const item of this) {\n const [itemKey, value] = item;\n if (itemKey === key) return value;\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reduce` function iterates over key-value pairs and applies a callback function to each pair,\n * accumulating a single value.\n * @param callbackfn - The callback function that will be called for each element in the collection.\n * It takes four arguments: the current accumulator value, the current value of the element, the key\n * of the element, and the index of the element in the collection. It should return the updated\n * accumulator value.\n * @param {U} initialValue - The `initialValue` parameter is the initial value of the accumulator. It\n * is the value that will be used as the first argument to the `callbackfn` function when reducing\n * the elements of the collection.\n * @returns The `reduce` method is returning the final value of the accumulator after iterating over\n * all the elements in the collection.\n */\n reduce<U>(callbackfn: ReduceEntryCallback<K, V, U>, initialValue: U): U {\n let accumulator = initialValue;\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n accumulator = callbackfn(accumulator, value, key, index++, this);\n }\n return accumulator;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n toVisual(): [K, V][] | string {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n abstract isEmpty(): boolean;\n\n abstract clear(): void;\n\n abstract clone(): any;\n\n abstract map(...args: any[]): any;\n\n abstract filter(...args: any[]): any;\n\n protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;\n}\n","import { ElementCallback, IterableElementBaseOptions, ReduceElementCallback } from '../../types';\n\nexport abstract class IterableElementBase<E, R, C> {\n /**\n * The protected constructor initializes the options for the IterableElementBase class, including the\n * toElementFn function.\n * @param [options] - An optional object that contains the following properties:\n */\n protected constructor(options?: IterableElementBaseOptions<E, R>) {\n if (options) {\n const { toElementFn } = options;\n if (typeof toElementFn === 'function') this._toElementFn = toElementFn;\n else if (toElementFn) throw new TypeError('toElementFn must be a function type');\n }\n }\n\n abstract get size(): number;\n\n protected _toElementFn?: (rawElement: R) => E;\n\n /**\n * The function returns the _toElementFn property, which is a function that converts a raw element to\n * a specific type.\n * @returns The function `get toElementFn()` is returning either a function that takes a raw element\n * `rawElement` of type `R` and returns an element `E`, or `undefined` if no function is assigned to\n * `_toElementFn`.\n */\n get toElementFn(): ((rawElement: R) => E) | undefined {\n return this._toElementFn;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function is an implementation of the Symbol.iterator method that returns an IterableIterator.\n * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It\n * allows the function to accept any number of arguments as an array. In this case, the `args`\n * parameter is used to pass any number of arguments to the `_getIterator` method.\n */\n *[Symbol.iterator](...args: any[]): IterableIterator<E> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields all the values in the object.\n */\n *values(): IterableIterator<E> {\n for (const item of this) {\n yield item;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `every` function checks if every element in the array satisfies a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being processed, its index, and the array it belongs to. It should return a\n * boolean value indicating whether the element satisfies a certain condition or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `every` method is returning a boolean value. It returns `true` if every element in\n * the array satisfies the provided predicate function, and `false` otherwise.\n */\n every(predicate: ElementCallback<E, R, boolean, C>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item, index++, this)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The \"some\" function checks if at least one element in a collection satisfies a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `index`, and `array`. It should return a boolean value indicating whether the current\n * element satisfies the condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided,\n * it will be passed as the `this` value to the `predicate` function. If `thisArg\n * @returns a boolean value. It returns true if the predicate function returns true for any element\n * in the collection, and false otherwise.\n */\n some(predicate: ElementCallback<E, R, boolean, C>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item, index++, this)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `forEach` function iterates over each element in an array-like object and calls a callback\n * function for each element.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes three arguments: the current element being processed, the index of the current\n * element, and the array that forEach was called upon.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n */\n forEach(callbackfn: ElementCallback<E, R, void, C>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n callbackfn.call(thisArg, item, index++, this);\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the elements of an array-like object and returns the first\n * element that satisfies the provided callback function.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes three arguments: the current element being processed, the index of the current\n * element, and the array itself. The function should return a boolean value indicating whether the\n * current element matches the desired condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The `find` method returns the first element in the array that satisfies the provided\n * callback function. If no element satisfies the callback function, `undefined` is returned.\n */\n find(callbackfn: ElementCallback<E, R, boolean, C>, thisArg?: any): E | undefined {\n let index = 0;\n for (const item of this) {\n if (callbackfn.call(thisArg, item, index++, this)) return item;\n }\n\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given element exists in a collection.\n * @param {E} element - The parameter \"element\" is of type E, which means it can be any type. It\n * represents the element that we want to check for existence in the collection.\n * @returns a boolean value. It returns true if the element is found in the collection, and false\n * otherwise.\n */\n has(element: E): boolean {\n for (const ele of this) {\n if (ele === element) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reduce` function iterates over the elements of an array-like object and applies a callback\n * function to reduce them into a single value.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes four arguments:\n * @param {U} initialValue - The initialValue parameter is the initial value of the accumulator. It\n * is the value that the accumulator starts with before the reduction operation begins.\n * @returns The `reduce` method is returning the final value of the accumulator after iterating over\n * all the elements in the array and applying the callback function to each element.\n */\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U, C>, initialValue: U): U {\n let accumulator = initialValue;\n let index = 0;\n for (const item of this) {\n accumulator = callbackfn(accumulator, item as E, index++, this);\n }\n return accumulator;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n toVisual(): E[] {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n abstract isEmpty(): boolean;\n\n abstract clear(): void;\n\n abstract clone(): C;\n\n abstract map(...args: any[]): any;\n\n abstract filter(...args: any[]): any;\n\n protected abstract _getIterator(...args: any[]): IterableIterator<E>;\n}\n","/**\n * data-structure-typed\n *\n * @author Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { Comparable, ComparablePrimitive, Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';\n\n/**\n * The function generates a random UUID (Universally Unique Identifier) in TypeScript.\n * @returns A randomly generated UUID (Universally Unique Identifier) in the format\n * 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' where each 'x' is replaced with a random hexadecimal\n * character.\n */\nexport const uuidV4 = function () {\n return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n\n/**\n * The `arrayRemove` function removes elements from an array based on a specified predicate function\n * and returns the removed elements.\n * @param {T[]} array - An array of elements that you want to filter based on the provided predicate\n * function.\n * @param predicate - The `predicate` parameter is a function that takes three arguments:\n * @returns The `arrayRemove` function returns an array containing the elements that satisfy the given\n * `predicate` function.\n */\nexport const arrayRemove = function <T>(array: T[], predicate: (item: T, index: number, array: T[]) => boolean): T[] {\n let i = -1,\n len = array ? array.length : 0;\n const result = [];\n\n while (++i < len) {\n const value = array[i];\n if (predicate(value, i, array)) {\n result.push(value);\n Array.prototype.splice.call(array, i--, 1);\n len--;\n }\n }\n\n return result;\n};\n\nexport const THUNK_SYMBOL = Symbol('thunk');\n\n/**\n * The function `isThunk` checks if a given value is a function with a specific symbol property.\n * @param {any} fnOrValue - The `fnOrValue` parameter in the `isThunk` function can be either a\n * function or a value that you want to check if it is a thunk. Thunks are functions that are wrapped\n * around a value or computation for lazy evaluation. The function checks if the `fnOrValue` is\n * @returns The function `isThunk` is checking if the input `fnOrValue` is a function and if it has a\n * property `__THUNK__` equal to `THUNK_SYMBOL`. The return value will be `true` if both conditions are\n * met, otherwise it will be `false`.\n */\nexport const isThunk = (fnOrValue: any) => {\n return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL;\n};\n\n/**\n * The `toThunk` function in TypeScript converts a function into a thunk by wrapping it in a closure.\n * @param {ToThunkFn} fn - `fn` is a function that will be converted into a thunk.\n * @returns A thunk function is being returned. Thunk functions are functions that delay the evaluation\n * of an expression or operation until it is explicitly called or invoked. In this case, the `toThunk`\n * function takes a function `fn` as an argument and returns a thunk function that, when called, will\n * execute the `fn` function provided as an argument.\n */\nexport const toThunk = (fn: ToThunkFn): Thunk => {\n const thunk = () => fn();\n thunk.__THUNK__ = THUNK_SYMBOL;\n return thunk;\n};\n\n/**\n * The `trampoline` function in TypeScript enables tail call optimization by using thunks to avoid\n * stack overflow.\n * @param {TrlFn} fn - The `fn` parameter in the `trampoline` function is a function that takes any\n * number of arguments and returns a value.\n * @returns The `trampoline` function returns an object with two properties:\n * 1. A function that executes the provided function `fn` and continues to execute any thunks returned\n * by `fn` until a non-thunk value is returned.\n * 2. A `cont` property that is a function which creates a thunk for the provided function `fn`.\n */\nexport const trampoline = (fn: TrlFn) => {\n const cont = (...args: [...Parameters<TrlFn>]): ReturnType<TrlFn> => toThunk(() => fn(...args));\n\n return Object.assign(\n (...args: [...Parameters<TrlFn>]) => {\n let result = fn(...args);\n\n while (isThunk(result) && typeof result === 'function') {\n result = result();\n }\n\n return result;\n },\n { cont }\n );\n};\n\n/**\n * The `trampolineAsync` function in TypeScript allows for asynchronous trampolining of a given\n * function.\n * @param {TrlAsyncFn} fn - The `fn` parameter in the `trampolineAsync` function is expected to be a\n * function that returns a Promise. This function will be called recursively until a non-thunk value is\n * returned.\n * @returns The `trampolineAsync` function returns an object with two properties:\n * 1. An async function that executes the provided `TrlAsyncFn` function and continues to execute any\n * thunks returned by the function until a non-thunk value is returned.\n * 2. A `cont` property that is a function which wraps the provided `TrlAsyncFn` function in a thunk\n * and returns it.\n */\nexport const trampolineAsync = (fn: TrlAsyncFn) => {\n const cont = (...args: [...Parameters<TrlAsyncFn>]): ReturnType<TrlAsyncFn> => toThunk(() => fn(...args));\n\n return Object.assign(\n async (...args: [...Parameters<TrlAsyncFn>]) => {\n let result = await fn(...args);\n\n while (isThunk(result) && typeof result === 'function') {\n result = await result();\n }\n\n return result;\n },\n { cont }\n );\n};\n\n/**\n * The function `getMSB` returns the most significant bit of a given number.\n * @param {number} value - The `value` parameter is a number for which we want to find the position of\n * the Most Significant Bit (MSB). The function `getMSB` takes this number as input and calculates the\n * position of the MSB in its binary representation.\n * @returns The function `getMSB` returns the most significant bit (MSB) of the input `value`. If the\n * input value is less than or equal to 0, it returns 0. Otherwise, it calculates the position of the\n * MSB using the `Math.clz32` function and bitwise left shifts 1 to that position.\n */\nexport const getMSB = (value: number): number => {\n if (value <= 0) {\n return 0;\n }\n return 1 << (31 - Math.clz32(value));\n};\n\n/**\n * The `rangeCheck` function in TypeScript is used to validate if an index is within a specified range\n * and throws a `RangeError` with a custom message if it is out of bounds.\n * @param {number} index - The `index` parameter represents the value that you want to check if it\n * falls within a specified range.\n * @param {number} min - The `min` parameter represents the minimum value that the `index` should be\n * compared against in the `rangeCheck` function.\n * @param {number} max - The `max` parameter in the `rangeCheck` function represents the maximum value\n * that the `index` parameter is allowed to have. If the `index` is greater than this `max` value, a\n * `RangeError` will be thrown.\n * @param [message=Index out of bounds.] - The `message` parameter is a string that represents the\n * error message to be thrown if the index is out of bounds. By default, if no message is provided when\n * calling the `rangeCheck` function, the message \"Index out of bounds.\" will be used.\n */\nexport const rangeCheck = (index: number, min: number, max: number, message = 'Index out of bounds.'): void => {\n if (index < min || index > max) throw new RangeError(message);\n};\n\n/**\n * The function `throwRangeError` throws a RangeError with a custom message if called.\n * @param [message=The value is off-limits.] - The `message` parameter is a string that represents the\n * error message to be displayed when a `RangeError` is thrown. If no message is provided, the default\n * message is 'The value is off-limits.'.\n */\nexport const throwRangeError = (message = 'The value is off-limits.'): void => {\n throw new RangeError(message);\n};\n\n/**\n * The function `isWeakKey` checks if the input is an object or a function in TypeScript.\n * @param {unknown} input - The `input` parameter in the `isWeakKey` function is of type `unknown`,\n * which means it can be any type. The function checks if the `input` is an object (excluding `null`)\n * or a function, and returns a boolean indicating whether the `input` is a weak\n * @returns The function `isWeakKey` returns a boolean value indicating whether the input is an object\n * or a function.\n */\nexport const isWeakKey = (input: unknown): input is object => {\n const inputType = typeof input;\n return (inputType === 'object' && input !== null) || inputType === 'function';\n};\n\n/**\n * The function `calcMinUnitsRequired` calculates the minimum number of units required to accommodate a\n * given total quantity based on a specified unit size.\n * @param {number} totalQuantity - The `totalQuantity` parameter represents the total quantity of items\n * that need to be processed or handled.\n * @param {number} unitSize - The `unitSize` parameter represents the size of each unit or package. It\n * is used in the `calcMinUnitsRequired` function to calculate the minimum number of units required to\n * accommodate a total quantity of items.\n */\nexport const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) =>\n Math.floor((totalQuantity + unitSize - 1) / unitSize);\n\n/**\n * The `roundFixed` function in TypeScript rounds a number to a specified number of decimal places.\n * @param {number} num - The `num` parameter is a number that you want to round to a certain number of\n * decimal places.\n * @param {number} [digit=10] - The `digit` parameter in the `roundFixed` function specifies the number\n * of decimal places to round the number to. By default, it is set to 10 if not provided explicitly.\n * @returns The function `roundFixed` returns a number that is rounded to the specified number of\n * decimal places (default is 10 decimal places).\n */\nexport const roundFixed = (num: number, digit: number = 10) => {\n const multiplier = Math.pow(10, digit);\n return Math.round(num * multiplier) / multiplier;\n};\n\n/**\n * The function `isPrimitiveComparable` checks if a value is a primitive type that can be compared.\n * @param {unknown} value - The `value` parameter in the `isPrimitiveComparable` function is of type\n * `unknown`, which means it can be any type. The function checks if the `value` is a primitive type\n * that can be compared, such as number, bigint, string, or boolean.\n * @returns The function `isPrimitiveComparable` returns a boolean value indicating whether the input\n * `value` is a primitive value that can be compared using standard comparison operators (<, >, <=,\n * >=).\n */\nfunction isPrimitiveComparable(value: unknown): value is ComparablePrimitive {\n const valueType = typeof value;\n if (valueType === 'number') return !Number.isNaN(value);\n return valueType === 'bigint' || valueType === 'string' || valueType === 'boolean';\n}\n\n/**\n * The function `tryObjectToPrimitive` attempts to convert an object to a comparable primitive value by\n * first checking the `valueOf` method and then the `toString` method.\n * @param {object} obj - The `obj` parameter in the `tryObjectToPrimitive` function is an object that\n * you want to convert to a primitive value. The function attempts to convert the object to a primitive\n * value by first checking if the object has a `valueOf` method. If the `valueOf` method exists, it\n * @returns The function `tryObjectToPrimitive` returns a value of type `ComparablePrimitive` if a\n * primitive comparable value is found within the object, or a string value if the object has a custom\n * `toString` method that does not return `'[object Object]'`. If neither condition is met, the\n * function returns `null`.\n */\nfunction tryObjectToPrimitive(obj: object): ComparablePrimitive | null {\n if (typeof obj.valueOf === 'function') {\n const valueOfResult = obj.valueOf();\n if (valueOfResult !== obj) {\n if (isPrimitiveComparable(valueOfResult)) return valueOfResult;\n if (typeof valueOfResult === 'object' && valueOfResult !== null) return tryObjectToPrimitive(valueOfResult);\n }\n }\n if (typeof obj.toString === 'function') {\n const stringResult = obj.toString();\n if (stringResult !== '[object Object]') return stringResult;\n }\n return null;\n}\n\n/**\n * The function `isComparable` in TypeScript checks if a value is comparable, handling primitive values\n * and objects with optional force comparison.\n * @param {unknown} value - The `value` parameter in the `isComparable` function represents the value\n * that you want to check if it is comparable. It can be of any type (`unknown`), and the function will\n * determine if it is comparable based on certain conditions.\n * @param [isForceObjectComparable=false] - The `isForceObjectComparable` parameter in the\n * `isComparable` function is a boolean flag that determines whether to treat non-primitive values as\n * comparable objects. When set to `true`, it forces the function to consider non-primitive values as\n * comparable objects, regardless of their type.\n * @returns The function `isComparable` returns a boolean value indicating whether the `value` is\n * considered comparable or not.\n */\nexport function isComparable(value: unknown, isForceObjectComparable = false): value is Comparable {\n if (value === null || value === undefined) return false;\n if (isPrimitiveComparable(value)) return true;\n\n if (typeof value !== 'object') return false;\n if (value instanceof Date) return !Number.isNaN(value.getTime());\n if (isForceObjectComparable) return true;\n const comparableValue = tryObjectToPrimitive(value);\n if (comparableValue === null || comparableValue === undefined) return false;\n return isPrimitiveComparable(comparableValue);\n}\n","/**\n * The function `toBinaryString` converts a number to a binary string representation with a specified\n * number of digits.\n * @param {number} num - The `num` parameter in the `toBinaryString` function represents the number\n * that you want to convert to a binary string.\n * @param [digit=32] - The `digit` parameter in the `toBinaryString` function represents the number of\n * digits the binary string should have. By default, it is set to 32, meaning that the binary string\n * will be padded with zeros at the beginning to ensure it is 32 bits long. You can provide a\n * @returns The function `toBinaryString` takes a number as input and converts it to a binary string\n * representation with a specified number of digits (default is 32). The binary string is padded with\n * zeros at the beginning to ensure it has the specified number of digits. The function returns the\n * binary string representation of the input number.\n */\nexport function toBinaryString(num: number, digit = 32) {\n // Convert number to binary string\n let binaryString = (num >>> 0).toString(2); // Use the unsigned right shift operator to ensure you get a binary representation of a 32-bit unsigned integer\n\n // Use pad Start to ensure the string length is 32 bits\n binaryString = binaryString.padStart(digit, '0');\n\n return binaryString;\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n EntryCallback,\n HashMapLinkedNode,\n HashMapOptions,\n HashMapStoreItem,\n LinkedHashMapOptions\n} from '../../types';\nimport { IterableEntryBase } from '../base';\nimport { isWeakKey, rangeCheck } from '../../utils';\n\n/**\n * 1. Key-Value Pair Storage: HashMap stores key-value pairs. Each key map to a value.\n * 2. Fast Lookup: It's used when you need to quickly find, insert, or delete entries based on a key.\n * 3. Unique Keys: Keys are unique.\n * If you try to insert another entry with the same key, the new one will replace the old entry.\n * 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.\n */\nexport class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {\n /**\n * The constructor function initializes a HashMap object with an optional initial collection and\n * options.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type\n * `T`. It is an optional parameter and its default value is an empty array `[]`.\n * @param [options] - The `options` parameter is an optional object that can contain two properties:\n */\n constructor(entryOrRawElements: Iterable<R | [K, V]> = [], options?: HashMapOptions<K, V, R>) {\n super();\n if (options) {\n const { hashFn, toEntryFn } = options;\n if (hashFn) this._hashFn = hashFn;\n if (toEntryFn) this._toEntryFn = toEntryFn;\n }\n if (entryOrRawElements) {\n this.setMany(entryOrRawElements);\n }\n }\n\n protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};\n\n /**\n * The function returns the store object, which is a dictionary of HashMapStoreItem objects.\n * @returns The store property is being returned. It is a dictionary-like object with string keys and\n * values of type HashMapStoreItem<K, V>.\n */\n get store(): { [p: string]: HashMapStoreItem<K, V> } {\n return this._store;\n }\n\n protected _objMap: Map<object, V> = new Map();\n\n /**\n * The function returns the object map.\n * @returns The `objMap` property is being returned, which is a `Map` object with keys of type\n * `object` and values of type `V`.\n */\n get objMap(): Map<object, V> {\n return this._objMap;\n }\n\n protected _toEntryFn?: (rawElement: R) => [K, V];\n\n /**\n * The function returns the value of the _toEntryFn property.\n * @returns The function being returned is `this._toEntryFn`.\n */\n get toEntryFn() {\n return this._toEntryFn;\n }\n\n protected _size = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n protected _hashFn: (key: K) => string = (key: K) => String(key);\n\n /**\n * The hasFn function is a function that takes in an item and returns a boolean\n * indicating whether the item is contained within the hash table.\n *\n * @return The hash function\n */\n get hashFn() {\n return this._hashFn;\n }\n\n /**\n * The function checks if a given element is an array with exactly two elements.\n * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any\n * data type.\n * @returns a boolean value.\n */\n isEntry(rawElement: any): rawElement is [K, V] {\n return Array.isArray(rawElement) && rawElement.length === 2;\n }\n\n /**\n * The function checks if the size of an object is equal to zero and returns a boolean value.\n * @returns A boolean value indicating whether the size of the object is 0 or not.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * The clear() function resets the state of an object by clearing its internal store, object map, and\n * size.\n */\n clear() {\n this._store = {};\n this._objMap.clear();\n this._size = 0;\n }\n\n /**\n * The `set` function adds a key-value pair to a map-like data structure, incrementing the size if\n * the key is not already present.\n * @param {K} key - The key parameter is the key used to identify the value in the data structure. It\n * can be of any type, but if it is an object, it will be stored in a Map, otherwise it will be\n * stored in a regular JavaScript object.\n * @param {V} value - The value parameter represents the value that you want to associate with the\n * key in the data structure.\n */\n set(key: K, value: V): boolean {\n if (this._isObjKey(key)) {\n if (!this.objMap.has(key)) {\n this._size++;\n }\n this.objMap.set(key, value);\n } else {\n const strKey = this._getNoObjKey(key);\n if (this.store[strKey] === undefined) {\n this._size++;\n }\n this._store[strKey] = { key, value };\n }\n return true;\n }\n\n /**\n * The function `setMany` takes an iterable collection of objects, maps each object to a key-value\n * pair using a mapping function, and sets each key-value pair in the current object.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type\n * `T`.\n * @returns The `setMany` function is returning an array of booleans.\n */\n setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const rawEle of entryOrRawElements) {\n let key: K | undefined, value: V | undefined;\n if (this.isEntry(rawEle)) {\n key = rawEle[0];\n value = rawEle[1];\n } else if (this._toEntryFn) {\n const item = this._toEntryFn(rawEle);\n key = item[0];\n value = item[1];\n }\n\n if (key !== undefined && value !== undefined) results.push(this.set(key, value));\n }\n return results;\n }\n\n /**\n * The `get` function retrieves a value from a map based on a given key, either from an object map or\n * a string map.\n * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be\n * of any type, but it should be compatible with the key type used when the map was created.\n * @returns The method `get(key: K)` returns a value of type `V` if the key exists in the `_objMap`\n * or `_store`, otherwise it returns `undefined`.\n */\n override get(key: K): V | undefined {\n if (this._isObjKey(key)) {\n return this.objMap.get(key);\n } else {\n const strKey = this._getNoObjKey(key);\n return this._store[strKey]?.value;\n }\n }\n\n /**\n * The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it\n * is an object key or not.\n * @param {K} key - The parameter \"key\" is of type K, which means it can be any type.\n * @returns The `has` method is returning a boolean value.\n */\n override has(key: K): boolean {\n if (this._isObjKey(key)) {\n return this.objMap.has(key);\n } else {\n const strKey = this._getNoObjKey(key);\n return strKey in this.store;\n }\n }\n\n /**\n * The `delete` function removes an element from a map-like data structure based on the provided key.\n * @param {K} key - The `key` parameter is the key of the element that you want to delete from the\n * data structure.\n * @returns The `delete` method returns a boolean value. It returns `true` if the key was\n * successfully deleted from the map, and `false` if the key was not found in the map.\n */\n delete(key: K): boolean {\n if (this._isObjKey(key)) {\n if (this.objMap.has(key)) {\n this._size--;\n }\n\n return this.objMap.delete(key);\n } else {\n const strKey = this._getNoObjKey(key);\n if (strKey in this.store) {\n delete this.store[strKey];\n this._size--;\n return true;\n }\n return false;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The clone function creates a new HashMap with the same key-value pairs as\n * this one. The clone function is useful for creating a copy of an existing\n * HashMap, and then modifying that copy without affecting the original.\n *\n * @return A new hashmap with the same values as this one\n */\n clone(): HashMap<K, V, R> {\n return new HashMap<K, V, R>(this, { hashFn: this._hashFn, toEntryFn: this._toEntryFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function in TypeScript creates a new HashMap by applying a callback function to each\n * key-value pair in the original HashMap.\n * @param callbackfn - The callback function that will be called for each key-value pair in the\n * HashMap. It takes four parameters:\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The `map` method is returning a new `HashMap` object with the transformed values based on\n * the provided callback function.\n */\n map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: any): HashMap<K, VM> {\n const resultMap = new HashMap<K, VM>();\n let index = 0;\n for (const [key, value] of this) {\n resultMap.set(key, callbackfn.call(thisArg, value, key, index++, this));\n }\n return resultMap;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new HashMap containing key-value pairs from the original HashMap\n * that satisfy a given predicate function.\n * @param predicate - The predicate parameter is a function that takes four arguments: value, key,\n * index, and map. It is used to determine whether an element should be included in the filtered map\n * or not. The function should return a boolean value - true if the element should be included, and\n * false otherwise.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs\n * from the original `HashMap` that pass the provided `predicate` function.\n */\n filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): HashMap<K, V> {\n const filteredMap = new HashMap<K, V>();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index++, this)) {\n filteredMap.set(key, value);\n }\n }\n return filteredMap;\n }\n\n /**\n * The function returns an iterator that yields key-value pairs from both an object store and an\n * object map.\n */\n protected *_getIterator(): IterableIterator<[K, V]> {\n for (const node of Object.values(this.store)) {\n yield [node.key, node.value] as [K, V];\n }\n for (const node of this.objMap) {\n yield node as [K, V];\n }\n }\n\n /**\n * The function checks if a given key is an object or a function.\n * @param {any} key - The parameter \"key\" can be of any type.\n * @returns a boolean value.\n */\n protected _isObjKey(key: any): key is object | ((...args: any[]) => any) {\n const keyType = typeof key;\n return (keyType === 'object' || keyType === 'function') && key !== null;\n }\n\n /**\n * The function `_getNoObjKey` takes a key and returns a string representation of the key, handling\n * different types of keys.\n * @param {K} key - The `key` parameter is of type `K`, which represents the type of the key being\n * passed to the `_getNoObjKey` function.\n * @returns a string value.\n */\n protected _getNoObjKey(key: K): string {\n const keyType = typeof key;\n\n let strKey: string;\n if (keyType !== 'string' && keyType !== 'number' && keyType !== 'symbol') {\n strKey = this._hashFn(key);\n } else {\n if (keyType === 'number') {\n // TODO numeric key should has its own hash\n strKey = <string>key;\n } else {\n strKey = <string>key;\n }\n }\n return strKey;\n }\n}\n\n/**\n * 1. Maintaining the Order of Element Insertion: Unlike HashMap, LinkedHashMap maintains the order in which entries are inserted. Therefore, when you traverse it, entries will be returned in the order they were inserted into the map.\n * 2. Based on Hash Table and Linked List: It combines the structures of a hash table and a linked list, using the hash table to ensure fast access, while maintaining the order of entries through the linked list.\n * 3. Time Complexity: Similar to HashMap, LinkedHashMap offers constant-time performance for get and put operations in most cases.\n */\nexport class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {\n protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;\n\n /**\n * The constructor initializes a LinkedHashMap object with an optional raw collection and options.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements. It is\n * used to initialize the HashMapLinked instance with key-value pairs. Each element in the\n * `entryOrRawElements` is converted to a key-value pair using the `toEntryFn` function (if provided) and\n * then added to the HashMap\n * @param [options] - The `options` parameter is an optional object that can contain the following\n * properties:\n */\n constructor(entryOrRawElements: Iterable<R | [K, V]> = [], options?: LinkedHashMapOptions<K, V, R>) {\n super();\n this._sentinel = <HashMapLinkedNode<K, V>>{};\n this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;\n\n if (options) {\n const { hashFn, objHashFn, toEntryFn } = options;\n if (hashFn) this._hashFn = hashFn;\n if (objHashFn) this._objHashFn = objHashFn;\n\n if (toEntryFn) {\n this._toEntryFn = toEntryFn;\n }\n }\n\n if (entryOrRawElements) {\n this.setMany(entryOrRawElements);\n }\n }\n\n protected _hashFn: (key: K) => string = (key: K) => String(key);\n\n /**\n * The function returns the hash function used for generating a hash value for a given key.\n * @returns The hash function that takes a key of type K and returns a string.\n */\n get hashFn(): (key: K) => string {\n return this._hashFn;\n }\n\n protected _objHashFn: (key: K) => object = (key: K) => <object>key;\n\n /**\n * The function returns the object hash function.\n * @returns The function `objHashFn` is being returned.\n */\n get objHashFn(): (key: K) => object {\n return this._objHashFn;\n }\n\n protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};\n\n /**\n * The function returns a record of HashMapLinkedNode objects with string keys.\n * @returns The method is returning a Record object, which is a TypeScript type that represents an\n * object with string keys and values that are HashMapLinkedNode objects with keys of type K and\n * values of type V or undefined.\n */\n get noObjMap(): Record<string, HashMapLinkedNode<K, V | undefined>> {\n return this._noObjMap;\n }\n\n protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();\n\n /**\n * The function returns the WeakMap object used to map objects to HashMapLinkedNode instances.\n * @returns The `objMap` property is being returned.\n */\n get objMap(): WeakMap<object, HashMapLinkedNode<K, V | undefined>> {\n return this._objMap;\n }\n\n protected _head: HashMapLinkedNode<K, V | undefined>;\n\n /**\n * The function returns the head node of a HashMapLinkedNode.\n * @returns The method `getHead()` is returning a `HashMapLinkedNode` object with key type `K` and\n * a value type `V | undefined`.\n */\n get head(): HashMapLinkedNode<K, V | undefined> {\n return this._head;\n }\n\n protected _tail: HashMapLinkedNode<K, V | undefined>;\n\n /**\n * The function returns the tail node of a HashMapLinkedNode.\n * @returns The `_tail` property of type `HashMapLinkedNode<K, V | undefined>` is being returned.\n */\n get tail(): HashMapLinkedNode<K, V | undefined> {\n return this._tail;\n }\n\n protected _toEntryFn?: (rawElement: R) => [K, V] = (rawElement: R) => {\n if (this.isEntry(rawElement)) {\n // TODO, For performance optimization, it may be necessary to only inspect the first element traversed.\n return rawElement;\n } else {\n throw new Error(\n \"If the provided entryOrRawElements does not adhere to the [key, value] type format, the toEntryFn in the constructor's options parameter needs to specified.\"\n );\n }\n };\n\n /**\n * The function returns the value of the _toEntryFn property.\n * @returns The function being returned is `this._toEntryFn`.\n */\n get toEntryFn() {\n return this._toEntryFn;\n }\n\n protected _size = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object.\n */\n get size() {\n return this._size;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function returns the key-value pair at the front of a data structure.\n * @returns The front element of the data structure, represented as a tuple with a key (K) and a\n * value (V).\n */\n get first() {\n if (this._size === 0) return;\n return <[K, V]>[this.head.key, this.head.value];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function returns the key-value pair at the end of a data structure.\n * @returns The method is returning an array containing the key-value pair of the tail element in the\n * data structure.\n */\n get last() {\n if (this._size === 0) return;\n return <[K, V]>[this.tail.key, this.tail.value];\n }\n\n /**\n * The `begin()` function in TypeScript iterates over a linked list and yields key-value pairs.\n */\n *begin() {\n let node = this.head;\n while (node !== this._sentinel) {\n yield [node.key, node.value];\n node = node.next;\n }\n }\n\n /**\n * The function `reverseBegin()` iterates over a linked list in reverse order, yielding each node's\n * key and value.\n */\n *reverseBegin() {\n let node = this.tail;\n while (node !== this._sentinel) {\n yield [node.key, node.value];\n node = node.prev;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `set` function adds a new key-value pair to a data structure, either using an object key or a\n * string key.\n * @param {K} key - The `key` parameter is the key to be set in the data structure. It can be of any\n * type, but typically it is a string or symbol.\n * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the\n * value associated with the key being set in the data structure.\n * @returns the size of the data structure after the key-value pair has been set.\n */\n set(key: K, value?: V): boolean {\n let node;\n const isNewKey = !this.has(key); // Check if the key is new\n\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n node = this.objMap.get(hash);\n\n if (!node && isNewKey) {\n // Create a new node\n node = { key: <K>hash, value, prev: this.tail, next: this._sentinel };\n this.objMap.set(hash, node);\n } else if (node) {\n // Update the value of an existing node\n node.value = value;\n }\n } else {\n const hash = this._hashFn(key);\n node = this.noObjMap[hash];\n\n if (!node && isNewKey) {\n this.noObjMap[hash] = node = { key, value, prev: this.tail, next: this._sentinel };\n } else if (node) {\n // Update the value of an existing node\n node.value = value;\n }\n }\n\n if (node && isNewKey) {\n // Update the head and tail of the linked list\n if (this._size === 0) {\n this._head = node;\n this._sentinel.next = node;\n } else {\n this.tail.next = node;\n node.prev = this.tail; // Make sure that the prev of the new node points to the current tail node\n }\n this._tail = node;\n this._sentinel.prev = node;\n this._size++;\n }\n\n return true;\n }\n\n /**\n * The function `setMany` takes an iterable collection, converts each element into a key-value pair\n * using a provided function, and sets each key-value pair in the current object, returning an array\n * of booleans indicating the success of each set operation.\n * @param entryOrRawElements - The entryOrRawElements parameter is an iterable collection of elements of type\n * R.\n * @returns The `setMany` function returns an array of booleans.\n */\n setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const rawEle of entryOrRawElements) {\n let key: K | undefined, value: V | undefined;\n if (this.isEntry(rawEle)) {\n key = rawEle[0];\n value = rawEle[1];\n } else if (this._toEntryFn) {\n const item = this._toEntryFn(rawEle);\n key = item[0];\n value = item[1];\n }\n\n if (key !== undefined && value !== undefined) results.push(this.set(key, value));\n }\n return results;\n }\n\n /**\n * The function checks if a given key exists in a map, using different logic depending on whether the\n * key is a weak key or not.\n * @param {K} key - The `key` parameter is the key that is being checked for existence in the map.\n * @returns The method `has` is returning a boolean value.\n */\n override has(key: K): boolean {\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n return this.objMap.has(hash);\n } else {\n const hash = this._hashFn(key);\n return hash in this.noObjMap;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `get` retrieves the value associated with a given key from a map, either by using the\n * key directly or by using an index stored in the key object.\n * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be\n * of any type, but typically it is a string or symbol.\n * @returns The value associated with the given key is being returned. If the key is an object key,\n * the value is retrieved from the `_nodes` array using the index stored in the `OBJ_KEY_INDEX`\n * property of the key. If the key is a string key, the value is retrieved from the `_noObjMap` object\n * using the key itself. If the key is not found, `undefined` is\n */\n override get(key: K): V | undefined {\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n const node = this.objMap.get(hash);\n return node ? node.value : undefined;\n } else {\n const hash = this._hashFn(key);\n const node = this.noObjMap[hash];\n return node ? node.value : undefined;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `at` retrieves the key-value pair at a specified index in a linked list.\n * @param {number} index - The index parameter is a number that represents the position of the\n * element we want to retrieve from the data structure.\n * @returns The method `at(index: number)` is returning an array containing the key-value pair at\n * the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,\n * where `K` is the key and `V` is the value.\n */\n at(index: number): V | undefined {\n rangeCheck(index, 0, this._size - 1);\n let node = this.head;\n while (index--) {\n node = node.next;\n }\n return node.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a key-value pair from a map-like data structure.\n * @param {K} key - The `key` parameter is the key that you want to delete from the data structure.\n * It can be of any type, but typically it is a string or an object.\n * @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key\n * was not found.\n */\n delete(key: K): boolean {\n let node;\n\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n // Get nodes from WeakMap\n node = this.objMap.get(hash);\n\n if (!node) {\n return false; // If the node does not exist, return false\n }\n\n // Remove nodes from WeakMap\n this.objMap.delete(hash);\n } else {\n const hash = this._hashFn(key);\n // Get nodes from noObjMap\n node = this.noObjMap[hash];\n\n if (!node) {\n return false; // If the node does not exist, return false\n }\n\n // Remove nodes from orgMap\n delete this.noObjMap[hash];\n }\n\n // Remove node from doubly linked list\n this._deleteNode(node);\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `deleteAt` function deletes a node at a specified index in a linked list.\n * @param {number} index - The index parameter represents the position at which the node should be\n * deleted in the linked list.\n * @returns The size of the list after deleting the element at the specified index.\n */\n deleteAt(index: number): boolean {\n rangeCheck(index, 0, this._size - 1);\n let node = this.head;\n while (index--) {\n node = node.next;\n }\n return this._deleteNode(node);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if a data structure is empty by comparing its size to zero.\n * @returns The method is returning a boolean value indicating whether the size of the object is 0 or\n * not.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * The function checks if a given element is an array with exactly two elements.\n * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any\n * data type.\n * @returns a boolean value.\n */\n isEntry(rawElement: any): rawElement is [K, V] {\n return Array.isArray(rawElement) && rawElement.length === 2;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function clears all the entries in a data structure and resets its properties.\n */\n clear(): void {\n this._noObjMap = {};\n this._size = 0;\n this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function creates a new instance of a `LinkedHashMap` with the same key-value pairs as\n * the original.\n * @returns The `clone()` method is returning a new instance of `LinkedHashMap<K, V>` that is a clone\n * of the original `LinkedHashMap` object.\n */\n clone(): LinkedHashMap<K, V> {\n const cloned = new LinkedHashMap<K, V>([], { hashFn: this._hashFn, objHashFn: this._objHashFn });\n for (const entry of this) {\n const [key, value] = entry;\n cloned.set(key, value);\n }\n return cloned;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new `LinkedHashMap` containing key-value pairs from the original\n * map that satisfy a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes four arguments:\n * `value`, `key`, `index`, and `this`. It should return a boolean value indicating whether the\n * current element should be included in the filtered map or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the `predicate` function. It is used when you want to bind a\n * specific object as the context for the `predicate` function. If `thisArg` is not provided, `this\n * @returns a new `LinkedHashMap` object that contains the key-value pairs from the original\n * `LinkedHashMap` object that satisfy the given predicate function.\n */\n filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): LinkedHashMap<K, V> {\n const filteredMap = new LinkedHashMap<K, V>();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index, this)) {\n filteredMap.set(key, value);\n }\n index++;\n }\n return filteredMap;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function in TypeScript creates a new `LinkedHashMap` by applying a callback function to\n * each key-value pair in the original map.\n * @param callback - The callback parameter is a function that will be called for each key-value pair\n * in the map. It takes four arguments: the value of the current key-value pair, the key of the\n * current key-value pair, the index of the current key-value pair, and the map itself. The callback\n * function should\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. If provided, the callback function will\n * be called with `thisArg` as its `this` value. If not provided, `this` will refer to the current\n * map\n * @returns a new `LinkedHashMap` object with the values mapped according to the provided callback\n * function.\n */\n map<VM>(callback: EntryCallback<K, V, VM>, thisArg?: any): LinkedHashMap<K, VM> {\n const mappedMap = new LinkedHashMap<K, VM>();\n let index = 0;\n for (const [key, value] of this) {\n const newValue = callback.call(thisArg, value, key, index, this);\n mappedMap.set(key, newValue);\n index++;\n }\n return mappedMap;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n * where n is the number of entries in the LinkedHashMap.\n *\n * The above function is an iterator that yields key-value pairs from a linked list.\n */\n protected *_getIterator() {\n let node = this.head;\n while (node !== this._sentinel) {\n yield [node.key, node.value] as [K, V];\n node = node.next;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_deleteNode` function removes a node from a doubly linked list and updates the head and tail\n * pointers if necessary.\n * @param node - The `node` parameter is an instance of the `HashMapLinkedNode` class, which\n * represents a node in a linked list. It contains a key-value pair and references to the previous\n * and next nodes in the list.\n */\n protected _deleteNode(node: HashMapLinkedNode<K, V | undefined>): boolean {\n const { prev, next } = node;\n prev.next = next;\n next.prev = prev;\n\n if (node === this.head) {\n this._head = next;\n }\n\n if (node === this.tail) {\n this._tail = prev;\n }\n\n this._size -= 1;\n return true;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback, SinglyLinkedListOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\nexport class SinglyLinkedListNode<E = any> {\n /**\n * The constructor function initializes an instance of a class with a given value and sets the next property to undefined.\n * @param {E} value - The \"value\" parameter is of type E, which means it can be any data type. It represents the value that\n * will be stored in the node of a linked list.\n */\n constructor(value: E) {\n this._value = value;\n this._next = undefined;\n }\n\n protected _value: E;\n\n /**\n * The function returns the value of a protected variable.\n * @returns The value of the variable `_value` is being returned.\n */\n get value(): E {\n return this._value;\n }\n\n /**\n * The above function sets the value of a variable.\n * @param {E} value - The parameter \"value\" is of type E, which means it can be any type.\n */\n set value(value: E) {\n this._value = value;\n }\n\n protected _next: SinglyLinkedListNode<E> | undefined;\n\n /**\n * The `next` function returns the next node in a singly linked list.\n * @returns The `next` property is being returned. It can be either a `SinglyLinkedListNode<E>`\n * object or `undefined`.\n */\n get next(): SinglyLinkedListNode<E> | undefined {\n return this._next;\n }\n\n /**\n * The \"next\" property of a SinglyLinkedListNode is set to the provided value.\n * @param {SinglyLinkedListNode<E> | undefined} value - The `value` parameter is of type\n * `SinglyLinkedListNode<E> | undefined`. This means that it can accept either a\n * `SinglyLinkedListNode` object or `undefined` as its value.\n */\n set next(value: SinglyLinkedListNode<E> | undefined) {\n this._next = value;\n }\n}\n\nexport class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R, SinglyLinkedList<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: SinglyLinkedListOptions<E, R>) {\n super(options);\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else {\n this.push(el as E);\n }\n }\n }\n }\n\n protected _head: SinglyLinkedListNode<E> | undefined;\n\n /**\n * The `head` function returns the first node of a singly linked list.\n * @returns The method is returning either a SinglyLinkedListNode object or undefined.\n */\n get head(): SinglyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: SinglyLinkedListNode<E> | undefined;\n\n /**\n * The `tail` function returns the last node of a singly linked list.\n * @returns The method is returning either a SinglyLinkedListNode object or undefined.\n */\n get tail(): SinglyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n /**\n * The above function returns the value of the first element in a linked list, or undefined if the\n * list is empty.\n * @returns The value of the first node in the linked list, or undefined if the linked list is empty.\n */\n get first(): E | undefined {\n return this.head?.value;\n }\n\n /**\n * The function returns the value of the last element in a linked list, or undefined if the list is\n * empty.\n * @returns The value of the last node in the linked list, or undefined if the linked list is empty.\n */\n get last(): E | undefined {\n return this.tail?.value;\n }\n\n protected _size: number = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `fromArray` function creates a new SinglyLinkedList instance and populates it with the elements from the given\n * array.\n * @param {E[]} data - The `data` parameter is an array of elements of type `E`.\n * @returns The `fromArray` function returns a `SinglyLinkedList` object.\n */\n static fromArray<E>(data: E[]) {\n const singlyLinkedList = new SinglyLinkedList<E>();\n for (const item of data) {\n singlyLinkedList.push(item);\n }\n return singlyLinkedList;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds a new element to the end of a singly linked list.\n * @param {E} element - The \"element\" parameter represents the value of the element that you want to\n * add to the linked list.\n * @returns The `push` method is returning a boolean value, `true`.\n */\n push(element: E): boolean {\n const newNode = new SinglyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n this.tail!.next = newNode;\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `pop` function removes and returns the value of the last element in a linked list.\n * @returns The method is returning the value of the element that is being popped from the end of the\n * list.\n */\n pop(): E | undefined {\n if (!this.head) return undefined;\n if (this.head === this.tail) {\n const value = this.head.value;\n this._head = undefined;\n this._tail = undefined;\n this._size--;\n return value;\n }\n\n let current = this.head;\n while (current.next !== this.tail) {\n current = current.next!;\n }\n const value = this.tail!.value;\n current.next = undefined;\n this._tail = current;\n this._size--;\n return value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift()` function removes and returns the value of the first element in a linked list.\n * @returns The value of the removed node.\n */\n shift(): E | undefined {\n if (!this.head) return undefined;\n const removedNode = this.head;\n this._head = this.head.next;\n this._size--;\n return removedNode.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The unshift function adds a new element to the beginning of a singly linked list.\n * @param {E} element - The \"element\" parameter represents the value of the element that you want to\n * add to the beginning of the singly linked list.\n * @returns The `unshift` method is returning a boolean value, `true`.\n */\n unshift(element: E): boolean {\n const newNode = new SinglyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n newNode.next = this.head;\n this._head = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `at` returns the value at a specified index in a linked list, or undefined if the index is out of range.\n * @param {number} index - The index parameter is a number that represents the position of the element we want to\n * retrieve from the list.\n * @returns The method `at(index: number): E | undefined` returns the value at the specified index in the linked list, or\n * `undefined` if the index is out of bounds.\n */\n at(index: number): E | undefined {\n if (index < 0 || index >= this._size) return undefined;\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current!.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `getNodeAt` returns the node at a given index in a singly linked list.\n * @param {number} index - The `index` parameter is a number that represents the position of the node we want to\n * retrieve from the linked list. It indicates the zero-based index of the node we want to access.\n * @returns The method `getNodeAt(index: number)` returns a `SinglyLinkedListNode<E>` object if the node at the\n * specified index exists, or `undefined` if the index is out of bounds.\n */\n getNodeAt(index: number): SinglyLinkedListNode<E> | undefined {\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `deleteAt` function removes an element at a specified index from a linked list and returns the removed element.\n * @param {number} index - The index parameter represents the position of the element that needs to be deleted in the\n * data structure. It is of type number.\n * @returns The method `deleteAt` returns the value of the node that was deleted, or `undefined` if the index is out of\n * bounds.\n */\n deleteAt(index: number): boolean {\n if (index < 0 || index >= this._size) return false;\n if (index === 0) {\n this.shift();\n return true;\n }\n if (index === this._size - 1) {\n this.pop();\n return true;\n }\n\n const prevNode = this.getNodeAt(index - 1);\n const removedNode = prevNode!.next;\n prevNode!.next = removedNode!.next;\n this._size--;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The delete function removes a node with a specific value from a singly linked list.\n * @param {E | SinglyLinkedListNode<E>} valueOrNode - The `valueOrNode` parameter can accept either a value of type `E`\n * or a `SinglyLinkedListNode<E>` object.\n * @returns The `delete` method returns a boolean value. It returns `true` if the value or node is found and\n * successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.\n */\n delete(valueOrNode: E | SinglyLinkedListNode<E> | undefined): boolean {\n if (valueOrNode === undefined) return false;\n let value: E;\n if (valueOrNode instanceof SinglyLinkedListNode) {\n value = valueOrNode.value;\n } else {\n value = valueOrNode;\n }\n let current = this.head,\n prev = undefined;\n\n while (current) {\n if (current.value === value) {\n if (prev === undefined) {\n this._head = current.next;\n if (current === this.tail) {\n this._tail = undefined;\n }\n } else {\n prev.next = current.next;\n if (current === this.tail) {\n this._tail = prev;\n }\n }\n this._size--;\n return true;\n }\n prev = current;\n current = current.next;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `addAt` function inserts a value at a specified index in a singly linked list.\n * @param {number} index - The index parameter represents the position at which the new value should be inserted in the\n * linked list. It is of type number.\n * @param {E} value - The `value` parameter represents the value that you want to insert into the linked list at the\n * specified index.\n * @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`\n * if the index is out of bounds.\n */\n addAt(index: number, value: E): boolean {\n if (index < 0 || index > this._size) return false;\n if (index === 0) {\n this.unshift(value);\n return true;\n }\n if (index === this._size) {\n this.push(value);\n return true;\n }\n\n const newNode = new SinglyLinkedListNode(value);\n const prevNode = this.getNodeAt(index - 1);\n newNode.next = prevNode!.next;\n prevNode!.next = newNode;\n this._size++;\n return true;\n }\n\n /**\n * The function checks if the length of a data structure is equal to zero and returns a boolean value indicating\n * whether it is empty or not.\n * @returns A boolean value indicating whether the length of the object is equal to 0.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * The `clear` function resets the linked list by setting the head, tail, and length to undefined and 0 respectively.\n */\n clear(): void {\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toArray` function converts a linked list into an array.\n * @returns The `toArray()` method is returning an array of type `E[]`.\n */\n toArray(): E[] {\n const array: E[] = [];\n let current = this.head;\n while (current) {\n array.push(current.value);\n current = current.next;\n }\n return array;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reverse` function reverses the order of the nodes in a singly linked list.\n * @returns The reverse() method does not return anything. It has a return type of void.\n */\n reverse(): this {\n if (!this.head || this.head === this.tail) return this;\n\n let prev: SinglyLinkedListNode<E> | undefined = undefined;\n let current: SinglyLinkedListNode<E> | undefined = this.head;\n let next: SinglyLinkedListNode<E> | undefined = undefined;\n\n while (current) {\n next = current.next;\n current.next = prev;\n prev = current;\n current = next;\n }\n\n [this._head, this._tail] = [this.tail!, this.head!];\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `indexOf` function returns the index of the first occurrence of a given value in a linked list.\n * @param {E} value - The value parameter is the value that you want to find the index of in the linked list.\n * @returns The method is returning the index of the first occurrence of the specified value in the linked list. If the\n * value is not found, it returns -1.\n */\n indexOf(value: E): number {\n let index = 0;\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n return index;\n }\n index++;\n current = current.next;\n }\n\n return -1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function finds a node in a singly linked list by its value and returns the node if found, otherwise returns\n * undefined.\n * @param {E} value - The value parameter is the value that we want to search for in the linked list.\n * @returns a `SinglyLinkedListNode<E>` if a node with the specified value is found in the linked list. If no node with\n * the specified value is found, the function returns `undefined`.\n */\n getNode(value: E): SinglyLinkedListNode<E> | undefined {\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n return current;\n }\n current = current.next;\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `addBefore` function inserts a new value before an existing value in a singly linked list.\n * @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node that you want to insert the\n * new value before. It can be either the value itself or a node containing the value in the linked list.\n * @param {E} newValue - The `newValue` parameter represents the value that you want to insert into the linked list.\n * @returns The method `addBefore` returns a boolean value. It returns `true` if the new value was successfully\n * inserted before the existing value, and `false` otherwise.\n */\n addBefore(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {\n if (!this.head) return false;\n\n let existingValue: E;\n if (existingValueOrNode instanceof SinglyLinkedListNode) {\n existingValue = existingValueOrNode.value;\n } else {\n existingValue = existingValueOrNode;\n }\n if (this.head.value === existingValue) {\n this.unshift(newValue);\n return true;\n }\n\n let current = this.head;\n while (current.next) {\n if (current.next.value === existingValue) {\n const newNode = new SinglyLinkedListNode(newValue);\n newNode.next = current.next;\n current.next = newNode;\n this._size++;\n return true;\n }\n current = current.next;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `addAfter` function inserts a new node with a given value after an existing node in a singly linked list.\n * @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node in the linked list after which\n * the new value will be inserted. It can be either the value of the existing node or the existing node itself.\n * @param {E} newValue - The value that you want to insert into the linked list after the existing value or node.\n * @returns The method returns a boolean value. It returns true if the new value was successfully inserted after the\n * existing value or node, and false if the existing value or node was not found in the linked list.\n */\n addAfter(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {\n let existingNode: E | SinglyLinkedListNode<E> | undefined;\n\n if (existingValueOrNode instanceof SinglyLinkedListNode) {\n existingNode = existingValueOrNode;\n } else {\n existingNode = this.getNode(existingValueOrNode);\n }\n\n if (existingNode) {\n const newNode = new SinglyLinkedListNode(newValue);\n newNode.next = existingNode.next;\n existingNode.next = newNode;\n if (existingNode === this.tail) {\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function counts the number of occurrences of a given value in a linked list.\n * @param {E} value - The value parameter is the value that you want to count the occurrences of in the linked list.\n * @returns The count of occurrences of the given value in the linked list.\n */\n countOccurrences(value: E): number {\n let count = 0;\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n count++;\n }\n current = current.next;\n }\n\n return count;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function returns a new instance of the `SinglyLinkedList` class with the same values\n * as the original list.\n * @returns The `clone()` method is returning a new instance of the `SinglyLinkedList` class, which\n * is a clone of the original list.\n */\n clone(): SinglyLinkedList<E, R> {\n return new SinglyLinkedList<E, R>(this, { toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new SinglyLinkedList by iterating over the elements of the current\n * list and applying a callback function to each element to determine if it should be included in the\n * filtered list.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * list. It takes three arguments: the current element, the index of the current element, and the\n * list itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list or not\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `SinglyLinkedList` object that contains the\n * elements that pass the filter condition specified by the `callback` function.\n */\n filter(callback: ElementCallback<E, R, boolean, SinglyLinkedList<E, R>>, thisArg?: any): SinglyLinkedList<E, R> {\n const filteredList = new SinglyLinkedList<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.push(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and returns a new SinglyLinkedList with the results\n * of applying the callback to each element in the original list.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the original list. It takes three arguments: `current` (the current element being processed),\n * `index` (the index of the current element), and `this` (the original list). It should return a\n * value\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * convert the raw element (`RR`) to the desired element type (`T`). It takes the raw element as\n * input and returns the converted element. If this parameter is not provided, the raw element will\n * be used as is.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `SinglyLinkedList` class with the mapped elements.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, SinglyLinkedList<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): SinglyLinkedList<EM, RM> {\n const mappedList = new SinglyLinkedList<EM, RM>([], { toElementFn });\n let index = 0;\n for (const current of this) {\n mappedList.push(callback.call(thisArg, current, index, this));\n index++;\n }\n\n return mappedList;\n }\n\n /**\n * The function `_getIterator` returns an iterable iterator that yields the values of a linked list.\n */\n protected *_getIterator(): IterableIterator<E> {\n let current = this.head;\n\n while (current) {\n yield current.value;\n current = current.next;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { DoublyLinkedListOptions, ElementCallback } from '../../types';\nimport { IterableElementBase } from '../base';\n\nexport class DoublyLinkedListNode<E = any> {\n /**\n * The constructor function initializes the value, next, and previous properties of an object.\n * @param {E} value - The \"value\" parameter is the value that will be stored in the node. It can be of any data type, as it\n * is defined as a generic type \"E\".\n */\n constructor(value: E) {\n this._value = value;\n this._next = undefined;\n this._prev = undefined;\n }\n\n protected _value: E;\n\n /**\n * The function returns the value of a protected variable.\n * @returns The value of the variable `_value` is being returned.\n */\n get value(): E {\n return this._value;\n }\n\n /**\n * The above function sets the value of a variable.\n * @param {E} value - The parameter \"value\" is of type E, which means it can be any type.\n */\n set value(value: E) {\n this._value = value;\n }\n\n protected _next: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The \"next\" function returns the next node in a doubly linked list.\n * @returns The `next` property is being returned. It can be either a `DoublyLinkedListNode<E>`\n * object or `undefined`.\n */\n get next(): DoublyLinkedListNode<E> | undefined {\n return this._next;\n }\n\n /**\n * The \"next\" property of a DoublyLinkedListNode is set to the provided value.\n * @param {DoublyLinkedListNode<E> | undefined} value - The `value` parameter is of type\n * `DoublyLinkedListNode<E> | undefined`. This means that it can accept either a\n * `DoublyLinkedListNode` object or `undefined` as its value.\n */\n set next(value: DoublyLinkedListNode<E> | undefined) {\n this._next = value;\n }\n\n protected _prev: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The `prev` function returns the previous node in a doubly linked list.\n * @returns The `prev` property of the `DoublyLinkedListNode` class is being returned. It can either\n * be a `DoublyLinkedListNode` object or `undefined`.\n */\n get prev(): DoublyLinkedListNode<E> | undefined {\n return this._prev;\n }\n\n /**\n * The function sets the previous node of a doubly linked list node.\n * @param {DoublyLinkedListNode<E> | undefined} value - The `value` parameter is of type\n * `DoublyLinkedListNode<E> | undefined`. This means that it can accept either a\n * `DoublyLinkedListNode` object or `undefined` as its value.\n */\n set prev(value: DoublyLinkedListNode<E> | undefined) {\n this._prev = value;\n }\n}\n\n/**\n * 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.\n * 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.\n * 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.\n * 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.\n */\nexport class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R, DoublyLinkedList<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: DoublyLinkedListOptions<E, R>) {\n super(options);\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else this.push(el as E);\n }\n }\n }\n\n protected _head: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The `head` function returns the first node of a doubly linked list.\n * @returns The method `getHead()` returns either a `DoublyLinkedListNode<E>` object or `undefined`.\n */\n get head(): DoublyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The `tail` function returns the last node of a doubly linked list.\n * @returns The `get tail()` method is returning either a `DoublyLinkedListNode<E>` object or\n * `undefined`.\n */\n get tail(): DoublyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n protected _size: number;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `get first` function returns the first node in a doubly linked list, or undefined if the list is empty.\n * @returns The method `get first()` returns the first node of the doubly linked list, or `undefined` if the list is empty.\n */\n get first(): E | undefined {\n return this.head?.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `get last` function returns the last node in a doubly linked list, or undefined if the list is empty.\n * @returns The method `get last()` returns the last node of the doubly linked list, or `undefined` if the list is empty.\n */\n get last(): E | undefined {\n return this.tail?.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `fromArray` function creates a new instance of a DoublyLinkedList and populates it with the elements from the\n * given array.\n * @param {E[]} data - The `data` parameter is an array of elements of type `E`.\n * @returns The `fromArray` function returns a DoublyLinkedList object.\n */\n static fromArray<E>(data: E[]) {\n return new DoublyLinkedList<E>(data);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds a new element to the end of a doubly linked list.\n * @param {E} element - The \"element\" parameter represents the value that you want to add to the\n * doubly linked list.\n * @returns The `push` method is returning a boolean value, `true`.\n */\n push(element: E): boolean {\n const newNode = new DoublyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n newNode.prev = this.tail;\n this.tail!.next = newNode;\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop()` function removes and returns the value of the last element in a linked list.\n * @returns The method is returning the value of the removed node.\n */\n pop(): E | undefined {\n if (!this.tail) return undefined;\n const removedNode = this.tail;\n if (this.head === this.tail) {\n this._head = undefined;\n this._tail = undefined;\n } else {\n this._tail = removedNode.prev;\n this.tail!.next = undefined;\n }\n this._size--;\n return removedNode.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift()` function removes and returns the value of the first element in a doubly linked list.\n * @returns The value of the removed node.\n */\n shift(): E | undefined {\n if (!this.head) return undefined;\n const removedNode = this.head;\n if (this.head === this.tail) {\n this._head = undefined;\n this._tail = undefined;\n } else {\n this._head = removedNode.next;\n this.head!.prev = undefined;\n }\n this._size--;\n return removedNode.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The unshift function adds a new element to the beginning of a doubly linked list.\n * @param {E} element - The \"element\" parameter represents the value of the element that you want to\n * add to the beginning of the doubly linked list.\n * @returns The `unshift` method is returning a boolean value, `true`.\n */\n unshift(element: E): boolean {\n const newNode = new DoublyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n newNode.next = this.head;\n this.head!.prev = newNode;\n this._head = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `at` function returns the value at a specified index in a linked list, or undefined if the index is out of bounds.\n * @param {number} index - The index parameter is a number that represents the position of the element we want to\n * retrieve from the list.\n * @returns The method is returning the value at the specified index in the linked list. If the index is out of bounds\n * or the linked list is empty, it will return undefined.\n */\n at(index: number): E | undefined {\n if (index < 0 || index >= this._size) return undefined;\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current!.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `getNodeAt` returns the node at a given index in a doubly linked list, or undefined if the index is out of\n * range.\n * @param {number} index - The `index` parameter is a number that represents the position of the node we want to\n * retrieve from the doubly linked list. It indicates the zero-based index of the node we want to access.\n * @returns The method `getNodeAt(index: number)` returns a `DoublyLinkedListNode<E>` object if the index is within the\n * valid range of the linked list, otherwise it returns `undefined`.\n */\n getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {\n if (index < 0 || index >= this._size) return undefined;\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `findNodeByValue` searches for a node with a specific value in a doubly linked list and returns the\n * node if found, otherwise it returns undefined.\n * @param {E} value - The `value` parameter is the value that we want to search for in the doubly linked list.\n * @returns The function `findNodeByValue` returns a `DoublyLinkedListNode<E>` if a node with the specified value `value`\n * is found in the linked list. If no such node is found, it returns `undefined`.\n */\n getNode(value: E | undefined): DoublyLinkedListNode<E> | undefined {\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n return current;\n }\n current = current.next;\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `insert` function inserts a value at a specified index in a doubly linked list.\n * @param {number} index - The index parameter represents the position at which the new value should be inserted in the\n * DoublyLinkedList. It is of type number.\n * @param {E} value - The `value` parameter represents the value that you want to insert into the Doubly Linked List at the\n * specified index.\n * @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`\n * if the index is out of bounds.\n */\n addAt(index: number, value: E): boolean {\n if (index < 0 || index > this._size) return false;\n if (index === 0) {\n this.unshift(value);\n return true;\n }\n if (index === this._size) {\n this.push(value);\n return true;\n }\n\n const newNode = new DoublyLinkedListNode(value);\n const prevNode = this.getNodeAt(index - 1);\n const nextNode = prevNode!.next;\n newNode.prev = prevNode;\n newNode.next = nextNode;\n prevNode!.next = newNode;\n nextNode!.prev = newNode;\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(1) or O(n)\n * Space Complexity: O(1)\n *\n * The `addBefore` function inserts a new value before an existing value or node in a doubly linked list.\n * @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list\n * before which the new value will be inserted. It can be either the value of the existing node or the existing node\n * itself.\n * @param {E} newValue - The `newValue` parameter represents the value that you want to insert into the doubly linked\n * list.\n * @returns The method returns a boolean value. It returns `true` if the insertion is successful, and `false` if the\n * insertion fails.\n */\n addBefore(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {\n let existingNode;\n\n if (existingValueOrNode instanceof DoublyLinkedListNode) {\n existingNode = existingValueOrNode;\n } else {\n existingNode = this.getNode(existingValueOrNode);\n }\n\n if (existingNode) {\n const newNode = new DoublyLinkedListNode(newValue);\n newNode.prev = existingNode.prev;\n if (existingNode.prev) {\n existingNode.prev.next = newNode;\n }\n newNode.next = existingNode;\n existingNode.prev = newNode;\n if (existingNode === this.head) {\n this._head = newNode;\n }\n this._size++;\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(1) or O(n)\n * Space Complexity: O(1)\n *\n * The `addAfter` function inserts a new node with a given value after an existing node in a doubly linked list.\n * @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list\n * after which the new value will be inserted. It can be either the value of the existing node or the existing node\n * itself.\n * @param {E} newValue - The value that you want to insert into the doubly linked list.\n * @returns The method returns a boolean value. It returns true if the insertion is successful, and false if the\n * existing value or node is not found in the doubly linked list.\n */\n addAfter(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {\n let existingNode;\n\n if (existingValueOrNode instanceof DoublyLinkedListNode) {\n existingNode = existingValueOrNode;\n } else {\n existingNode = this.getNode(existingValueOrNode);\n }\n\n if (existingNode) {\n const newNode = new DoublyLinkedListNode(newValue);\n newNode.next = existingNode.next;\n if (existingNode.next) {\n existingNode.next.prev = newNode;\n }\n newNode.prev = existingNode;\n existingNode.next = newNode;\n if (existingNode === this.tail) {\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `deleteAt` function removes an element at a specified index from a linked list and returns the removed element.\n * @param {number} index - The index parameter represents the position of the element that needs to be deleted in the\n * data structure. It is of type number.\n * @returns The method `deleteAt` returns the value of the node that was deleted, or `undefined` if the index is out of\n * bounds.\n */\n deleteAt(index: number): boolean {\n if (index < 0 || index >= this._size) return false;\n if (index === 0) {\n this.shift();\n return true;\n }\n if (index === this._size - 1) {\n this.pop();\n return true;\n }\n\n const removedNode = this.getNodeAt(index);\n const prevNode = removedNode!.prev;\n const nextNode = removedNode!.next;\n prevNode!.next = nextNode;\n nextNode!.prev = prevNode;\n this._size--;\n return true;\n }\n\n /**\n * Time Complexity: O(1) or O(n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a node from a doubly linked list based on either the node itself or its value.\n * @param {E | DoublyLinkedListNode<E>} valOrNode - The `valOrNode` parameter can accept either a value of type `E` or\n * a `DoublyLinkedListNode<E>` object.\n * @returns The `delete` method returns a boolean value. It returns `true` if the value or node was successfully\n * deleted from the doubly linked list, and `false` if the value or node was not found in the list.\n */\n delete(valOrNode: E | DoublyLinkedListNode<E> | undefined): boolean {\n let node: DoublyLinkedListNode<E> | undefined;\n\n if (valOrNode instanceof DoublyLinkedListNode) {\n node = valOrNode;\n } else {\n node = this.getNode(valOrNode);\n }\n\n if (node) {\n if (node === this.head) {\n this.shift();\n } else if (node === this.tail) {\n this.pop();\n } else {\n const prevNode = node.prev;\n const nextNode = node.next;\n prevNode!.next = nextNode;\n nextNode!.prev = prevNode;\n this._size--;\n }\n return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if a variable has a size greater than zero and returns a boolean value.\n * @returns A boolean value is being returned.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function resets the linked list by setting the head, tail, and size to undefined and 0 respectively.\n */\n clear(): void {\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function returns the index of the first occurrence of a given value in a linked list.\n * @param {E} value - The parameter `value` is of type `E`, which means it can be any data type. It represents the value\n * that we are searching for in the linked list.\n * @returns The method `indexOf` returns the index of the first occurrence of the specified value `value` in the linked\n * list. If the value is not found, it returns -1.\n */\n indexOf(value: E): number {\n let index = 0;\n let current = this.head;\n while (current) {\n if (current.value === value) {\n return index;\n }\n index++;\n current = current.next;\n }\n return -1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `findBackward` function iterates through a linked list from the last node to the first node and returns the last\n * value that satisfies the given callback function, or undefined if no value satisfies the callback.\n * @param callback - A function that takes a value of type E as its parameter and returns a boolean value. This\n * function is used to determine whether a given value satisfies a certain condition.\n * @returns The method `findBackward` returns the last value in the linked list that satisfies the condition specified by\n * the callback function. If no value satisfies the condition, it returns `undefined`.\n */\n findBackward(callback: (value: E) => boolean): E | undefined {\n let current = this.tail;\n while (current) {\n if (callback(current.value)) {\n return current.value;\n }\n current = current.prev;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reverse` function reverses the order of the elements in a doubly linked list.\n */\n reverse(): this {\n let current = this.head;\n [this._head, this._tail] = [this.tail, this.head];\n while (current) {\n const next = current.next;\n [current.prev, current.next] = [current.next, current.prev];\n current = next;\n }\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toArray` function converts a linked list into an array.\n * @returns The `toArray()` method is returning an array of type `E[]`.\n */\n toArray(): E[] {\n const array: E[] = [];\n let current = this.head;\n while (current) {\n array.push(current.value);\n current = current.next;\n }\n return array;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toReversedArray` function converts a doubly linked list into an array in reverse order.\n * @returns The `toReversedArray()` function returns an array of type `E[]`.\n */\n toReversedArray(): E[] {\n const array: E[] = [];\n let current = this.tail;\n while (current) {\n array.push(current.value);\n current = current.prev;\n }\n return array;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function creates a new instance of the `DoublyLinkedList` class with the same values\n * as the original list.\n * @returns The `clone()` method is returning a new instance of the `DoublyLinkedList` class, which\n * is a copy of the original list.\n */\n clone(): DoublyLinkedList<E, R> {\n return new DoublyLinkedList<E, R>(this);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new DoublyLinkedList by iterating over the elements of the current\n * list and applying a callback function to each element, returning only the elements for which the\n * callback function returns true.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the DoublyLinkedList. It takes three arguments: the current element, the index of the current\n * element, and the DoublyLinkedList itself. The callback function should return a boolean value\n * indicating whether the current element should be included\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `DoublyLinkedList` object that contains the\n * elements that pass the filter condition specified by the `callback` function.\n */\n filter(callback: ElementCallback<E, R, boolean, DoublyLinkedList<E, R>>, thisArg?: any): DoublyLinkedList<E, R> {\n const filteredList = new DoublyLinkedList<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.push(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and returns a new DoublyLinkedList with the results\n * of applying the callback to each element in the original list.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * original DoublyLinkedList. It takes three arguments: current (the current element being\n * processed), index (the index of the current element), and this (the original DoublyLinkedList).\n * The callback function should return a value of type\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * convert the raw element (`RR`) to the desired element type (`T`). It takes the raw element as\n * input and returns the converted element. If this parameter is not provided, the raw element will\n * be used as is.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `DoublyLinkedList` class with elements of type `T` and `RR`.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, DoublyLinkedList<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): DoublyLinkedList<EM, RM> {\n const mappedList = new DoublyLinkedList<EM, RM>([], { toElementFn });\n let index = 0;\n for (const current of this) {\n mappedList.push(callback.call(thisArg, current, index, this));\n index++;\n }\n\n return mappedList;\n }\n\n /**\n * The function returns an iterator that iterates over the values of a linked list.\n */\n protected *_getIterator(): IterableIterator<E> {\n let current = this.head;\n\n while (current) {\n yield current.value;\n current = current.next;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { SkipLinkedListOptions } from '../../types';\n\nexport class SkipListNode<K, V> {\n key: K;\n value: V;\n forward: SkipListNode<K, V>[];\n\n constructor(key: K, value: V, level: number) {\n this.key = key;\n this.value = value;\n this.forward = new Array(level);\n }\n}\n\nexport class SkipList<K, V> {\n /**\n * The constructor function initializes a SkipLinkedList object with optional options and elements.\n * @param elements - The `elements` parameter is an iterable containing key-value pairs `[K, V]`. It\n * is used to initialize the SkipLinkedList with the given key-value pairs. If no elements are\n * provided, the SkipLinkedList will be empty.\n * @param {SkipLinkedListOptions} [options] - The `options` parameter is an optional object that can\n * contain two properties:\n */\n constructor(elements: Iterable<[K, V]> = [], options?: SkipLinkedListOptions) {\n if (options) {\n const { maxLevel, probability } = options;\n if (typeof maxLevel === 'number') this._maxLevel = maxLevel;\n if (typeof probability === 'number') this._probability = probability;\n }\n\n if (elements) {\n for (const [key, value] of elements) this.add(key, value);\n }\n }\n\n protected _head: SkipListNode<K, V> = new SkipListNode<K, V>(undefined as any, undefined as any, this.maxLevel);\n\n /**\n * The function returns the head node of a SkipList.\n * @returns The method is returning a SkipListNode object with generic key type K and value type V.\n */\n get head(): SkipListNode<K, V> {\n return this._head;\n }\n\n protected _level: number = 0;\n\n /**\n * The function returns the value of the protected variable _level.\n * @returns The level property of the object.\n */\n get level(): number {\n return this._level;\n }\n\n protected _maxLevel: number = 16;\n\n /**\n * The function returns the maximum level.\n * @returns The value of the variable `_maxLevel` is being returned.\n */\n get maxLevel(): number {\n return this._maxLevel;\n }\n\n protected _probability: number = 0.5;\n\n /**\n * The function returns the probability value.\n * @returns The probability value stored in the protected variable `_probability` is being returned.\n */\n get probability(): number {\n return this._probability;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Get the value of the first element (the smallest element) in the Skip List.\n * @returns The value of the first element, or undefined if the Skip List is empty.\n */\n get first(): V | undefined {\n const firstNode = this.head.forward[0];\n return firstNode ? firstNode.value : undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Get the value of the last element (the largest element) in the Skip List.\n * @returns The value of the last element, or undefined if the Skip List is empty.\n */\n get last(): V | undefined {\n let current = this.head;\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i]) {\n current = current.forward[i];\n }\n }\n return current.value;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The add function adds a new node with a given key and value to a Skip List data structure.\n * @param {K} key - The key parameter represents the key of the node that needs to be added to the skip list.\n * @param {V} value - The \"value\" parameter represents the value associated with the key that is being added to the Skip\n * List.\n */\n add(key: K, value: V): void {\n const newNode = new SkipListNode(key, value, this._randomLevel());\n const update: SkipListNode<K, V>[] = new Array(this.maxLevel).fill(this.head);\n let current = this.head;\n\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n update[i] = current;\n }\n\n for (let i = 0; i < newNode.forward.length; i++) {\n newNode.forward[i] = update[i].forward[i];\n update[i].forward[i] = newNode;\n }\n\n if (!newNode.forward[0]) {\n this._level = Math.max(this.level, newNode.forward.length);\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `get` retrieves the value associated with a given key from a skip list data structure.\n * @param {K} key - The `key` parameter is the key of the element that we want to retrieve from the data structure.\n * @returns The method `get(key: K)` returns the value associated with the given key if it exists in the data structure,\n * otherwise it returns `undefined`.\n */\n get(key: K): V | undefined {\n let current = this.head;\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n }\n\n current = current.forward[0];\n\n if (current && current.key === key) {\n return current.value;\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function checks if a key exists in a data structure.\n * @param {K} key - The parameter \"key\" is of type K, which represents the type of the key being\n * checked.\n * @returns a boolean value.\n */\n has(key: K): boolean {\n return this.get(key) !== undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a node with a specific key from a Skip List data structure.\n * @param {K} key - The key parameter represents the key of the node that needs to be removed from the skip list.\n * @returns The `delete` method returns a boolean value. It returns `true` if the key was successfully removed from the\n * skip list, and `false` if the key was not found in the skip list.\n */\n delete(key: K): boolean {\n const update: SkipListNode<K, V>[] = new Array(this.maxLevel).fill(this.head);\n let current = this.head;\n\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n update[i] = current;\n }\n\n current = current.forward[0];\n\n if (current && current.key === key) {\n for (let i = 0; i < this.level; i++) {\n if (update[i].forward[i] !== current) {\n break;\n }\n update[i].forward[i] = current.forward[i];\n }\n while (this.level > 0 && !this.head.forward[this.level - 1]) {\n this._level--;\n }\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Get the value of the first element in the Skip List that is greater than the given key.\n * @param key - the given key.\n * @returns The value of the first element greater than the given key, or undefined if there is no such element.\n */\n higher(key: K): V | undefined {\n let current = this.head;\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key <= key) {\n current = current.forward[i];\n }\n }\n const nextNode = current.forward[0];\n return nextNode ? nextNode.value : undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Get the value of the last element in the Skip List that is less than the given key.\n * @param key - the given key.\n * @returns The value of the last element less than the given key, or undefined if there is no such element.\n */\n lower(key: K): V | undefined {\n let current = this.head;\n let lastLess = undefined;\n\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n if (current.key < key) {\n lastLess = current;\n }\n }\n\n return lastLess ? lastLess.value : undefined;\n }\n\n /**\n * Time Complexity: O(maxLevel)\n * Space Complexity: O(1)\n *\n * The function \"_randomLevel\" generates a random level based on a given probability and maximum level.\n * @returns the level, which is a number.\n */\n protected _randomLevel(): number {\n let level = 1;\n while (Math.random() < this.probability && level < this.maxLevel) {\n level++;\n }\n return level;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback, StackOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\n/**\n * 1. Last In, First Out (LIFO): The core characteristic of a stack is its last in, first out nature, meaning the last element added to the stack will be the first to be removed.\n * 2. Uses: Stacks are commonly used for managing a series of tasks or elements that need to be processed in a last in, first out manner. They are widely used in various scenarios, such as in function calls in programming languages, evaluation of arithmetic expressions, and backtracking algorithms.\n * 3. Performance: Stack operations are typically O(1) in time complexity, meaning that regardless of the stack's size, adding, removing, and viewing the top element are very fast operations.\n * 4. Function Calls: In most modern programming languages, the records of function calls are managed through a stack. When a function is called, its record (including parameters, local variables, and return address) is 'pushed' into the stack. When the function returns, its record is 'popped' from the stack.\n * 5. Expression Evaluation: Used for the evaluation of arithmetic or logical expressions, especially when dealing with parenthesis matching and operator precedence.\n * 6. Backtracking Algorithms: In problems where multiple branches need to be explored but only one branch can be explored at a time, stacks can be used to save the state at each branching point.\n */\nexport class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: StackOptions<E, R>) {\n super(options);\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else {\n this.push(el as E);\n }\n }\n }\n }\n\n protected _elements: E[] = [];\n\n /**\n * The elements function returns the elements of this set.\n * @return An array of elements\n */\n get elements(): E[] {\n return this._elements;\n }\n\n /**\n * The size() function returns the number of elements in an array.\n * @returns The size of the elements array.\n */\n get size(): number {\n return this.elements.length;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function \"fromArray\" creates a new Stack object from an array of elements.\n * @param {E[]} elements - The `elements` parameter is an array of elements of type `E`.\n * @returns {Stack} The method is returning a new instance of the Stack class, initialized with the elements from the input\n * array.\n */\n static fromArray<E>(elements: E[]): Stack<E> {\n return new Stack(elements);\n }\n\n /**\n * The function checks if an array is empty and returns a boolean value.\n * @returns A boolean value indicating whether the `_elements` array is empty or not.\n */\n isEmpty(): boolean {\n return this.elements.length === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `peek` function returns the last element of an array, or undefined if the array is empty.\n * @returns The `peek()` function returns the last element of the `_elements` array, or `undefined` if the array is empty.\n */\n peek(): E | undefined {\n if (this.isEmpty()) return undefined;\n\n return this.elements[this.elements.length - 1];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds an element to the stack and returns the updated stack.\n * @param {E} element - The parameter \"element\" is of type E, which means it can be any data type.\n * @returns The `push` method is returning the updated `Stack<E>` object.\n */\n push(element: E): boolean {\n this.elements.push(element);\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop` function removes and returns the last element from an array, or returns undefined if the array is empty.\n * @returns The `pop()` method is returning the last element of the array `_elements` if the array is not empty. If the\n * array is empty, it returns `undefined`.\n */\n pop(): E | undefined {\n if (this.isEmpty()) return;\n\n return this.elements.pop();\n }\n\n /**\n * The delete function removes an element from the stack.\n * @param element: E Specify the element to be deleted\n * @return A boolean value indicating whether the element was successfully deleted or not\n */\n delete(element: E): boolean {\n const index = this.elements.indexOf(element);\n return this.deleteAt(index);\n }\n\n /**\n * The deleteAt function deletes the element at a given index.\n * @param index: number Determine the index of the element to be deleted\n * @return A boolean value\n */\n deleteAt(index: number): boolean {\n const spliced = this.elements.splice(index, 1);\n return spliced.length === 1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The toArray function returns a copy of the elements in an array.\n * @returns An array of type E.\n */\n toArray(): E[] {\n return this.elements.slice();\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function clears the elements array.\n */\n clear(): void {\n this._elements = [];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone()` function returns a new `Stack` object with the same elements as the original stack.\n * @returns The `clone()` method is returning a new `Stack` object with a copy of the `_elements` array.\n */\n clone(): Stack<E, R> {\n return new Stack<E, R>(this, { toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new stack containing elements from the original stack that satisfy\n * a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being iterated over, the index of the current element, and the stack itself.\n * It should return a boolean value indicating whether the element should be included in the filtered\n * stack or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Stack` object that contains the elements that\n * satisfy the given predicate function.\n */\n filter(predicate: ElementCallback<E, R, boolean, Stack<E, R>>, thisArg?: any): Stack<E, R> {\n const newStack = new Stack<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const el of this) {\n if (predicate.call(thisArg, el, index, this)) {\n newStack.push(el);\n }\n index++;\n }\n return newStack;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and applies it to each element in the stack,\n * returning a new stack with the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * stack. It takes three arguments: the current element, the index of the element, and the stack\n * itself. It should return a new value that will be added to the new stack.\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * transform the raw element (`RM`) into a new element (`EM`) before pushing it into the new stack.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new Stack object with elements of type EM and raw elements of type RM.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Stack<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Stack<EM, RM> {\n const newStack = new Stack<EM, RM>([], { toElementFn });\n let index = 0;\n for (const el of this) {\n newStack.push(callback.call(thisArg, el, index, this));\n index++;\n }\n return newStack;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Custom iterator for the Stack class.\n * @returns An iterator object.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (let i = 0; i < this.elements.length; i++) {\n yield this.elements[i];\n }\n }\n}\n","/**\n * @license MIT\n * @copyright Pablo Zeng <zrwusa@gmail.com>\n * @class\n */\nimport type { ElementCallback, QueueOptions } from '../../types';\nimport { IterableElementBase } from '../base';\nimport { SinglyLinkedList } from '../linked-list';\n\n/**\n * 1. First In, First Out (FIFO): The core feature of a queue is its first in, first out nature. The element added to the queue first will be the one to be removed first.\n * 2. Operations: The main operations include enqueue (adding an element to the end of the queue) and dequeue (removing and returning the element at the front of the queue). Typically, there is also a peek operation (looking at the front element without removing it).\n * 3. Uses: Queues are commonly used to manage a series of tasks or elements that need to be processed in order. For example, managing task queues in a multi-threaded environment, or in algorithms for data structures like trees and graphs for breadth-first search.\n * 4. Task Scheduling: Managing the order of task execution in operating systems or applications.\n * 5. Data Buffering: Acting as a buffer for data packets in network communication.\n * 6. Breadth-First Search (BFS): In traversal algorithms for graphs and trees, queues store elements that are to be visited.\n * 7. Real-time Queuing: Like queuing systems in banks or supermarkets.\n */\nexport class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: QueueOptions<E, R>) {\n super(options);\n\n if (options) {\n const { autoCompactRatio = 0.5 } = options;\n this._autoCompactRatio = autoCompactRatio;\n }\n\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) this.push(this.toElementFn(el as R));\n else this.push(el as E);\n }\n }\n }\n\n protected _elements: E[] = [];\n\n /**\n * The elements function returns the elements of this set.\n * @return An array of the elements in the stack\n */\n get elements(): E[] {\n return this._elements;\n }\n\n protected _offset: number = 0;\n\n /**\n * The offset function returns the offset of the current page.\n * @return The value of the protected variable _offset\n */\n get offset(): number {\n return this._offset;\n }\n\n /**\n * The size function returns the number of elements in an array.\n * @returns {number} The size of the array, which is the difference between the length of the array and the offset.\n */\n get size(): number {\n return this.elements.length - this.offset;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `first` function returns the first element of the array `_elements` if it exists, otherwise it returns `undefined`.\n * @returns The `get first()` method returns the first element of the data structure, represented by the `_elements` array at\n * the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.\n */\n get first(): E | undefined {\n return this.size > 0 ? this.elements[this.offset] : undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `last` function returns the last element in an array-like data structure, or undefined if the structure is empty.\n * @returns The method `get last()` returns the last element of the `_elements` array if the array is not empty. If the\n * array is empty, it returns `undefined`.\n */\n get last(): E | undefined {\n return this.size > 0 ? this.elements[this.elements.length - 1] : undefined;\n }\n\n protected _autoCompactRatio: number = 0.5;\n\n /**\n * This function returns the value of the autoCompactRatio property.\n * @returns The `autoCompactRatio` property of the object, which is a number.\n */\n get autoCompactRatio(): number {\n return this._autoCompactRatio;\n }\n\n /**\n * The above function sets the autoCompactRatio property to a specified number in TypeScript.\n * @param {number} v - The parameter `v` represents the value that will be assigned to the\n * `_autoCompactRatio` property.\n */\n set autoCompactRatio(v: number) {\n this._autoCompactRatio = v;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function \"fromArray\" creates a new Queue object from an array of elements.Creates a queue from an existing array.\n * @public\n * @param {E[]} elements - The \"elements\" parameter is an array of elements of type E.\n * @returns The method is returning a new instance of the Queue class, initialized with the elements from the input\n * array.\n */\n static fromArray<E>(elements: E[]): Queue<E> {\n return new Queue(elements);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds an element to the end of the queue and returns true. Adds an element at the back of the queue.\n * @param {E} element - The `element` parameter represents the element that you want to add to the queue.\n * @returns Always returns true, indicating the element was successfully added.\n */\n push(element: E): boolean {\n this.elements.push(element);\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift` function removes and returns the first element in the queue, and adjusts the internal data structure if\n * necessary to optimize performance.\n * @returns The function `shift()` returns either the first element in the queue or `undefined` if the queue is empty.\n */\n shift(): E | undefined {\n if (this.size === 0) return undefined;\n\n const first = this.first;\n this._offset += 1;\n\n if (this.offset / this.elements.length > this.autoCompactRatio) this.compact();\n return first;\n }\n\n /**\n * The delete function removes an element from the list.\n * @param {E} element - Specify the element to be deleted\n * @return A boolean value indicating whether the element was successfully deleted or not\n */\n delete(element: E): boolean {\n const index = this.elements.indexOf(element);\n return this.deleteAt(index);\n }\n\n /**\n * The deleteAt function deletes the element at a given index.\n * @param {number} index - Determine the index of the element to be deleted\n * @return A boolean value\n */\n deleteAt(index: number): boolean {\n const spliced = this.elements.splice(index, 1);\n return spliced.length === 1;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * @param index\n */\n at(index: number): E | undefined {\n return this.elements[index + this._offset];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if a data structure is empty by comparing its size to zero.\n * @returns {boolean} A boolean value indicating whether the size of the object is 0 or not.\n */\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(n)\n *\n * The toArray() function returns an array of elements from the current offset to the end of the _elements array.\n * @returns An array of type E is being returned.\n */\n toArray(): E[] {\n return this.elements.slice(this.offset);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the elements array and offset to their initial values.\n */\n clear(): void {\n this._elements = [];\n this._offset = 0;\n }\n\n /**\n * The `compact` function in TypeScript slices the elements array based on the offset and resets the\n * offset to zero.\n * @returns The `compact()` method is returning a boolean value of `true`.\n */\n compact(): boolean {\n this._elements = this.elements.slice(this.offset);\n this._offset = 0;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone()` function returns a new Queue object with the same elements as the original Queue.\n * @returns The `clone()` method is returning a new instance of the `Queue` class.\n */\n clone(): Queue<E, R> {\n return new Queue(this.elements.slice(this.offset), { toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new `Queue` object containing elements from the original `Queue`\n * that satisfy a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being iterated over, the index of the current element, and the queue itself.\n * It should return a boolean value indicating whether the element should be included in the filtered\n * queue or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Queue` object that contains the elements that\n * satisfy the given predicate function.\n */\n filter(predicate: ElementCallback<E, R, boolean, Queue<E, R>>, thisArg?: any): Queue<E, R> {\n const newDeque = new Queue<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const el of this) {\n if (predicate.call(thisArg, el, index, this)) {\n newDeque.push(el);\n }\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Queue<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Queue<EM, RM> {\n const newDeque = new Queue<EM, RM>([], { toElementFn });\n let index = 0;\n for (const el of this) {\n newDeque.push(callback.call(thisArg, el, index, this));\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `_getIterator` returns an iterable iterator for the elements in the class.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (const item of this.elements.slice(this.offset)) {\n yield item;\n }\n }\n}\n\n/**\n * 1. First In, First Out (FIFO) Strategy: Like other queue implementations, LinkedListQueue follows the first in, first out principle, meaning the element that is added to the queue first will be the first to be removed.\n * 2. Based on Linked List: LinkedListQueue uses a linked list to store elements. Each node in the linked list contains data and a pointer to the next node.\n * 3. Memory Usage: Since each element requires additional space to store a pointer to the next element, linked lists may use more memory compared to arrays.\n * 4. Frequent Enqueuing and Dequeuing Operations: If your application involves frequent enqueuing and dequeuing operations and is less concerned with random access, then LinkedListQueue is a good choice.\n */\nexport class LinkedListQueue<E = any, R = any> extends SinglyLinkedList<E, R> {\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n * The `clone` function returns a new instance of the `LinkedListQueue` class with the same values as\n * the current instance.\n * @returns The `clone()` method is returning a new instance of `LinkedListQueue` with the same\n * values as the original `LinkedListQueue`.\n */\n override clone(): LinkedListQueue<E, R> {\n return new LinkedListQueue<E, R>(this, { toElementFn: this.toElementFn });\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { DequeOptions, ElementCallback, IterableWithSizeOrLength } from '../../types';\nimport { IterableElementBase } from '../base';\nimport { calcMinUnitsRequired, rangeCheck } from '../../utils';\n\n/**\n * 1. Operations at Both Ends: Supports adding and removing elements at both the front and back of the queue. This allows it to be used as a stack (last in, first out) and a queue (first in, first out).\n * 2. Efficient Random Access: Being based on an array, it offers fast random access capability, allowing constant time access to any element.\n * 3. Continuous Memory Allocation: Since it is based on an array, all elements are stored contiguously in memory, which can bring cache friendliness and efficient memory access.\n * 4. Efficiency: Adding and removing elements at both ends of a deque is usually very fast. However, when the dynamic array needs to expand, it may involve copying the entire array to a larger one, and this operation has a time complexity of O(n).\n * 5. Performance jitter: Deque may experience performance jitter, but DoublyLinkedList will not\n */\nexport class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E, R>> {\n /**\n * The constructor initializes a Deque object with optional iterable of elements and options.\n * @param elements - An iterable object (such as an array or a Set) that contains the initial\n * elements to be added to the deque. It can also be an object with a `length` or `size` property\n * that represents the number of elements in the iterable object. If no elements are provided, an\n * empty deque\n * @param {DequeOptions} [options] - The `options` parameter is an optional object that can contain\n * configuration options for the deque. In this code, it is used to set the `bucketSize` option,\n * which determines the size of each bucket in the deque. If the `bucketSize` option is not provided\n * or is not a number\n */\n constructor(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R> = [], options?: DequeOptions<E, R>) {\n super(options);\n\n if (options) {\n const { bucketSize, maxLen } = options;\n if (typeof bucketSize === 'number') this._bucketSize = bucketSize;\n if (typeof maxLen === 'number' && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;\n }\n\n let _size: number;\n if ('length' in elements) {\n if (elements.length instanceof Function) _size = elements.length();\n else _size = elements.length;\n } else {\n if (elements.size instanceof Function) _size = elements.size();\n else _size = elements.size;\n }\n\n this._bucketCount = calcMinUnitsRequired(_size, this._bucketSize) || 1;\n for (let i = 0; i < this._bucketCount; ++i) {\n this._buckets.push(new Array(this._bucketSize));\n }\n const needBucketNum = calcMinUnitsRequired(_size, this._bucketSize);\n this._bucketFirst = this._bucketLast = (this._bucketCount >> 1) - (needBucketNum >> 1);\n this._firstInBucket = this._lastInBucket = (this._bucketSize - (_size % this._bucketSize)) >> 1;\n\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else {\n this.push(el as E);\n }\n }\n }\n\n protected _bucketSize: number = 1 << 12;\n\n /**\n * The bucketSize function returns the size of the bucket.\n *\n * @return The size of the bucket\n */\n get bucketSize() {\n return this._bucketSize;\n }\n\n protected _maxLen: number = -1;\n\n /**\n * The maxLen function returns the max length of the deque.\n *\n * @return The max length of the deque\n */\n get maxLen() {\n return this._maxLen;\n }\n\n protected _bucketFirst = 0;\n\n /**\n * The function returns the value of the protected variable `_bucketFirst`.\n * @returns The value of the `_bucketFirst` property.\n */\n get bucketFirst(): number {\n return this._bucketFirst;\n }\n\n protected _firstInBucket = 0;\n\n /**\n * The function returns the value of the protected variable _firstInBucket.\n * @returns The method is returning the value of the variable `_firstInBucket`, which is of type\n * `number`.\n */\n get firstInBucket(): number {\n return this._firstInBucket;\n }\n\n protected _bucketLast = 0;\n\n /**\n * The function returns the value of the protected variable `_bucketLast`.\n * @returns The value of the `_bucketLast` property, which is a number.\n */\n get bucketLast(): number {\n return this._bucketLast;\n }\n\n protected _lastInBucket = 0;\n\n /**\n * The function returns the value of the protected variable _lastInBucket.\n * @returns The method is returning the value of the variable `_lastInBucket`, which is of type\n * `number`.\n */\n get lastInBucket(): number {\n return this._lastInBucket;\n }\n\n protected _bucketCount = 0;\n\n /**\n * The function returns the number of buckets.\n * @returns The number of buckets.\n */\n get bucketCount(): number {\n return this._bucketCount;\n }\n\n protected _buckets: E[][] = [];\n\n /**\n * The buckets function returns the buckets property of the object.\n * @return The buckets property\n */\n get buckets() {\n return this._buckets;\n }\n\n protected _size = 0;\n\n /**\n * The size function returns the number of items in the stack.\n * @return The number of values in the set\n */\n get size() {\n return this._size;\n }\n\n /**\n * The function returns the first element in a collection if it exists, otherwise it returns\n * undefined.\n * @returns The first element of the collection, of type E, is being returned.\n */\n get first(): E | undefined {\n if (this._size === 0) return;\n return this._buckets[this._bucketFirst][this._firstInBucket];\n }\n\n /**\n * The last function returns the last element in the queue.\n * @return The last element in the array\n */\n get last(): E | undefined {\n if (this._size === 0) return;\n return this._buckets[this._bucketLast][this._lastInBucket];\n }\n\n /**\n * Time Complexity - Amortized O(1) (possible reallocation),\n * Space Complexity - O(n) (due to potential resizing).\n *\n * The push function adds an element to a data structure and reallocates memory if necessary.\n * @param {E} element - The `element` parameter represents the value that you want to add to the data\n * structure.\n * @returns The size of the data structure after the element has been pushed.\n */\n push(element: E): boolean {\n if (this._size) {\n if (this._lastInBucket < this._bucketSize - 1) {\n this._lastInBucket += 1;\n } else if (this._bucketLast < this._bucketCount - 1) {\n this._bucketLast += 1;\n this._lastInBucket = 0;\n } else {\n this._bucketLast = 0;\n this._lastInBucket = 0;\n }\n if (this._bucketLast === this._bucketFirst && this._lastInBucket === this._firstInBucket) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketLast][this._lastInBucket] = element;\n if (this._maxLen > 0 && this._size > this._maxLen) this.shift();\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop()` function removes and returns the last element from a data structure, updating the\n * internal state variables accordingly.\n * @returns The element that was removed from the data structure is being returned.\n */\n pop(): E | undefined {\n if (this._size === 0) return;\n const element = this._buckets[this._bucketLast][this._lastInBucket];\n if (this._size !== 1) {\n if (this._lastInBucket > 0) {\n this._lastInBucket -= 1;\n } else if (this._bucketLast > 0) {\n this._bucketLast -= 1;\n this._lastInBucket = this._bucketSize - 1;\n } else {\n this._bucketLast = this._bucketCount - 1;\n this._lastInBucket = this._bucketSize - 1;\n }\n }\n this._size -= 1;\n return element;\n }\n\n /**\n * Time Complexity: Amortized O(1)\n * Space Complexity: O(n)\n *\n * The `unshift` function adds an element to the beginning of an array-like data structure and\n * returns the new size of the structure.\n * @param {E} element - The `element` parameter represents the element that you want to add to the\n * beginning of the data structure.\n * @returns The size of the data structure after the element has been added.\n */\n unshift(element: E): boolean {\n if (this._size) {\n if (this._firstInBucket > 0) {\n this._firstInBucket -= 1;\n } else if (this._bucketFirst > 0) {\n this._bucketFirst -= 1;\n this._firstInBucket = this._bucketSize - 1;\n } else {\n this._bucketFirst = this._bucketCount - 1;\n this._firstInBucket = this._bucketSize - 1;\n }\n if (this._bucketFirst === this._bucketLast && this._firstInBucket === this._lastInBucket) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketFirst][this._firstInBucket] = element;\n if (this._maxLen > 0 && this._size > this._maxLen) this.pop();\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift()` function removes and returns the first element from a data structure, updating the\n * internal state variables accordingly.\n * @returns The element that is being removed from the beginning of the data structure is being\n * returned.\n */\n shift(): E | undefined {\n if (this._size === 0) return;\n const element = this._buckets[this._bucketFirst][this._firstInBucket];\n if (this._size !== 1) {\n if (this._firstInBucket < this._bucketSize - 1) {\n this._firstInBucket += 1;\n } else if (this._bucketFirst < this._bucketCount - 1) {\n this._bucketFirst += 1;\n this._firstInBucket = 0;\n } else {\n this._bucketFirst = 0;\n this._firstInBucket = 0;\n }\n }\n this._size -= 1;\n return element;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if the size of an object is equal to zero and returns a boolean value.\n * @returns A boolean value indicating whether the size of the object is 0 or not.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear() function resets the state of the object by initializing all variables to their default\n * values.\n */\n clear(): void {\n this._buckets = [new Array(this._bucketSize)];\n this._bucketCount = 1;\n this._bucketFirst = this._bucketLast = this._size = 0;\n this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;\n }\n\n /**\n * The below function is a generator that yields elements from a collection one by one.\n */\n *begin(): Generator<E> {\n let index = 0;\n while (index < this._size) {\n yield this.at(index);\n index++;\n }\n }\n\n /**\n * The function `reverseBegin()` is a generator that yields elements in reverse order starting from\n * the last element.\n */\n *reverseBegin(): Generator<E> {\n let index = this._size - 1;\n while (index >= 0) {\n yield this.at(index);\n index--;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `at` function retrieves an element at a specified position in an array-like data structure.\n * @param {number} pos - The `pos` parameter represents the position of the element that you want to\n * retrieve from the data structure. It is of type `number` and should be a valid index within the\n * range of the data structure.\n * @returns The element at the specified position in the data structure is being returned.\n */\n at(pos: number): E {\n rangeCheck(pos, 0, this._size - 1);\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n return this._buckets[bucketIndex][indexInBucket]!;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `setAt` function sets an element at a specific position in an array-like data structure.\n * @param {number} pos - The `pos` parameter represents the position at which the element needs to be\n * set. It is of type `number`.\n * @param {E} element - The `element` parameter is the value that you want to set at the specified\n * position in the data structure.\n */\n setAt(pos: number, element: E): boolean {\n rangeCheck(pos, 0, this._size - 1);\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n this._buckets[bucketIndex][indexInBucket] = element;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `addAt` function inserts one or more elements at a specified position in an array-like data\n * structure.\n * @param {number} pos - The `pos` parameter represents the position at which the element(s) should\n * be inserted. It is of type `number`.\n * @param {E} element - The `element` parameter represents the element that you want to insert into\n * the array at the specified position.\n * @param [num=1] - The `num` parameter represents the number of times the `element` should be\n * inserted at the specified position (`pos`). By default, it is set to 1, meaning that the `element`\n * will be inserted once. However, you can provide a different value for `num` if you want\n * @returns The size of the array after the insertion is being returned.\n */\n addAt(pos: number, element: E, num = 1): boolean {\n const length = this._size;\n rangeCheck(pos, 0, length);\n if (pos === 0) {\n while (num--) this.unshift(element);\n } else if (pos === this._size) {\n while (num--) this.push(element);\n } else {\n const arr: E[] = [];\n for (let i = pos; i < this._size; ++i) {\n arr.push(this.at(i));\n }\n this.cut(pos - 1, true);\n for (let i = 0; i < num; ++i) this.push(element);\n for (let i = 0; i < arr.length; ++i) this.push(arr[i]);\n }\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `cut` function updates the state of the object based on the given position and returns the\n * updated size.\n * @param {number} pos - The `pos` parameter represents the position at which the string should be\n * cut. It is a number that indicates the index of the character where the cut should be made.\n * @param {boolean} isCutSelf - If true, the original deque will not be cut, and return a new deque\n * @returns The method is returning the updated size of the data structure.\n */\n cut(pos: number, isCutSelf = false): Deque<E> {\n if (isCutSelf) {\n if (pos < 0) {\n this.clear();\n return this;\n }\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n this._bucketLast = bucketIndex;\n this._lastInBucket = indexInBucket;\n this._size = pos + 1;\n return this;\n } else {\n const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });\n\n for (let i = 0; i <= pos; i++) {\n newDeque.push(this.at(i));\n }\n\n return newDeque;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1) or O(n)\n *\n * The `cutRest` function cuts the elements from a specified position in a deque and returns a new\n * deque with the cut elements.\n * @param {number} pos - The `pos` parameter represents the position from which to cut the Deque. It\n * is a number that indicates the index of the element in the Deque where the cut should start.\n * @param [isCutSelf=false] - isCutSelf is a boolean parameter that determines whether the original\n * Deque should be modified or a new Deque should be created. If isCutSelf is true, the original\n * Deque will be modified by cutting off elements starting from the specified position. If isCutSelf\n * is false, a new De\n * @returns The function `cutRest` returns either the modified original deque (`this`) or a new deque\n * (`newDeque`) depending on the value of the `isCutSelf` parameter.\n */\n cutRest(pos: number, isCutSelf = false): Deque<E> {\n if (isCutSelf) {\n if (pos < 0) {\n return this;\n }\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n this._bucketFirst = bucketIndex;\n this._firstInBucket = indexInBucket;\n this._size = this._size - pos;\n return this;\n } else {\n const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });\n if (pos < 0) pos = 0;\n for (let i = pos; i < this._size; i++) {\n newDeque.push(this.at(i));\n }\n\n return newDeque;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1) or O(n)\n *\n * The `deleteAt` function removes an element at a specified position in an array-like data\n * structure.\n * @param {number} pos - The `pos` parameter in the `deleteAt` function represents the position at\n * which an element needs to be deleted from the data structure. It is of type `number` and indicates\n * the index of the element to be deleted.\n * @returns The size of the data structure after the deletion operation is performed.\n */\n deleteAt(pos: number): boolean {\n rangeCheck(pos, 0, this._size - 1);\n if (pos === 0) this.shift();\n else if (pos === this._size - 1) this.pop();\n else {\n const length = this._size - 1;\n let { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(pos);\n for (let i = pos; i < length; ++i) {\n const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(pos + 1);\n this._buckets[curBucket][curPointer] = this._buckets[nextBucket][nextPointer];\n curBucket = nextBucket;\n curPointer = nextPointer;\n }\n this.pop();\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes all occurrences of a specified element from an array-like data\n * structure.\n * @param {E} element - The `element` parameter represents the element that you want to delete from\n * the data structure.\n * @returns The size of the data structure after the element has been deleted.\n */\n delete(element: E): boolean {\n const size = this._size;\n if (size === 0) return false;\n let i = 0;\n let index = 0;\n while (i < size) {\n const oldElement = this.at(i);\n if (oldElement !== element) {\n this.setAt(index, oldElement!);\n index += 1;\n }\n i += 1;\n }\n this.cut(index - 1, true);\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The reverse() function reverses the order of the buckets and the elements within each bucket in a\n * data structure.\n * @returns The reverse() method is returning the object itself (this) after performing the reverse\n * operation on the buckets and updating the relevant properties.\n */\n reverse(): this {\n this._buckets.reverse().forEach(function (bucket) {\n bucket.reverse();\n });\n const { _bucketFirst, _bucketLast, _firstInBucket, _lastInBucket } = this;\n this._bucketFirst = this._bucketCount - _bucketLast - 1;\n this._bucketLast = this._bucketCount - _bucketFirst - 1;\n this._firstInBucket = this._bucketSize - _lastInBucket - 1;\n this._lastInBucket = this._bucketSize - _firstInBucket - 1;\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `unique()` function removes duplicate elements from an array-like data structure and returns\n * the number of unique elements.\n * @returns The size of the modified array is being returned.\n */\n unique(): this {\n if (this._size <= 1) {\n return this;\n }\n let index = 1;\n let prev = this.at(0);\n for (let i = 1; i < this._size; ++i) {\n const cur = this.at(i);\n if (cur !== prev) {\n prev = cur;\n this.setAt(index++, cur);\n }\n }\n this.cut(index - 1, true);\n return this;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `sort` function sorts the elements in a data structure using a provided comparator function.\n * @param [comparator] - The `comparator` parameter is a function that takes in two elements `x` and\n * `y` of type `E` and returns a number. The comparator function is used to determine the order of\n * the elements in the sorted array.\n * @returns Deque<E>\n */\n sort(comparator?: (x: E, y: E) => number): this {\n const arr: E[] = [];\n for (let i = 0; i < this._size; ++i) {\n arr.push(this.at(i));\n }\n arr.sort(comparator);\n for (let i = 0; i < this._size; ++i) {\n this.setAt(i, arr[i]);\n }\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `shrinkToFit` function reorganizes the elements in an array-like data structure to minimize\n * memory usage.\n * @returns Nothing is being returned. The function is using the `return` statement to exit early if\n * `this._size` is 0, but it does not return any value.\n */\n shrinkToFit(): void {\n if (this._size === 0) return;\n const newBuckets = [];\n if (this._bucketFirst === this._bucketLast) return;\n else if (this._bucketFirst < this._bucketLast) {\n for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {\n newBuckets.push(this._buckets[i]);\n }\n } else {\n for (let i = this._bucketFirst; i < this._bucketCount; ++i) {\n newBuckets.push(this._buckets[i]);\n }\n for (let i = 0; i <= this._bucketLast; ++i) {\n newBuckets.push(this._buckets[i]);\n }\n }\n this._bucketFirst = 0;\n this._bucketLast = newBuckets.length - 1;\n this._buckets = newBuckets;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function \"indexOf\" returns the index of the first occurrence of a given element in an array,\n * or -1 if the element is not found.\n * @param {E} element - The \"element\" parameter represents the element that you want to find the\n * index of in the data structure.\n * @returns The indexOf function returns the index of the first occurrence of the specified element\n * in the data structure. If the element is not found, it returns -1.\n */\n indexOf(element: E): number {\n for (let i = 0; i < this._size; ++i) {\n if (this.at(i) === element) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toArray` function converts the elements of a data structure into an array.\n * @returns The `toArray()` method is returning an array of elements of type `E`.\n */\n toArray(): E[] {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone()` function returns a new instance of the `Deque` class with the same elements and\n * bucket size as the original instance.\n * @returns The `clone()` method is returning a new instance of the `Deque` class with the same\n * elements as the original deque (`this`) and the same bucket size.\n */\n clone(): Deque<E, R> {\n return new Deque<E, R>(this, { bucketSize: this.bucketSize, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new deque containing elements from the original deque that satisfy\n * a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being iterated over, the index of the current element, and the deque itself.\n * It should return a boolean value indicating whether the element should be included in the filtered\n * deque or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Deque` object that contains the elements that\n * satisfy the given predicate function.\n */\n filter(predicate: ElementCallback<E, R, boolean, Deque<E, R>>, thisArg?: any): Deque<E, R> {\n const newDeque = new Deque<E, R>([], { bucketSize: this._bucketSize, toElementFn: this.toElementFn });\n let index = 0;\n for (const el of this) {\n if (predicate.call(thisArg, el, index, this)) {\n newDeque.push(el);\n }\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and applies it to each element in the deque,\n * returning a new deque with the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * deque. It takes three arguments: the current element, the index of the element, and the deque\n * itself. It should return a value of type EM.\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * transform the raw element (`RM`) into a new element (`EM`) before adding it to the new deque. If\n * provided, this function will be called for each raw element in the original deque.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new Deque object with elements of type EM and raw elements of type RM.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Deque<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Deque<EM, RM> {\n const newDeque = new Deque<EM, RM>([], { bucketSize: this._bucketSize, toElementFn });\n let index = 0;\n for (const el of this) {\n newDeque.push(callback.call(thisArg, el, index, this));\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The above function is an implementation of the iterator protocol in TypeScript, allowing the\n * object to be iterated over using a for...of loop.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (let i = 0; i < this._size; ++i) {\n yield this.at(i);\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `_reallocate` function reallocates the buckets in an array, adding new buckets if needed.\n * @param {number} [needBucketNum] - The `needBucketNum` parameter is an optional number that\n * specifies the number of new buckets needed. If not provided, it will default to half of the\n * current bucket count (`this._bucketCount >> 1`) or 1 if the current bucket count is less than 2.\n */\n protected _reallocate(needBucketNum?: number) {\n const newBuckets = [];\n const addBucketNum = needBucketNum || this._bucketCount >> 1 || 1;\n for (let i = 0; i < addBucketNum; ++i) {\n newBuckets[i] = new Array(this._bucketSize);\n }\n for (let i = this._bucketFirst; i < this._bucketCount; ++i) {\n newBuckets[newBuckets.length] = this._buckets[i];\n }\n for (let i = 0; i < this._bucketLast; ++i) {\n newBuckets[newBuckets.length] = this._buckets[i];\n }\n newBuckets[newBuckets.length] = [...this._buckets[this._bucketLast]];\n this._bucketFirst = addBucketNum;\n this._bucketLast = newBuckets.length - 1;\n for (let i = 0; i < addBucketNum; ++i) {\n newBuckets[newBuckets.length] = new Array(this._bucketSize);\n }\n this._buckets = newBuckets;\n this._bucketCount = newBuckets.length;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function calculates the bucket index and index within the bucket based on the given position.\n * @param {number} pos - The `pos` parameter represents the position within the data structure. It is\n * a number that indicates the index or position of an element within the structure.\n * @returns an object with two properties: \"bucketIndex\" and \"indexInBucket\".\n */\n protected _getBucketAndPosition(pos: number) {\n let bucketIndex: number;\n let indexInBucket: number;\n\n const overallIndex = this._firstInBucket + pos;\n bucketIndex = this._bucketFirst + Math.floor(overallIndex / this._bucketSize);\n\n if (bucketIndex >= this._bucketCount) {\n bucketIndex -= this._bucketCount;\n }\n\n indexInBucket = ((overallIndex + 1) % this._bucketSize) - 1;\n if (indexInBucket < 0) {\n indexInBucket = this._bucketSize - 1;\n }\n\n return { bucketIndex, indexInBucket };\n }\n}\n","/**\n * data-structure-typed\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\n\nimport type { Comparator, DFSOrderPattern, ElementCallback, HeapOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\n/**\n * 1. Complete Binary Tree: Heaps are typically complete binary trees, meaning every level is fully filled except possibly for the last level, which has nodes as far left as possible.\n * 2. Heap Properties: Each node in a heap follows a specific order property, which varies depending on the type of heap:\n * Max Heap: The value of each parent node is greater than or equal to the value of its children.\n * Min Heap: The value of each parent node is less than or equal to the value of its children.\n * 3. Root Node Access: In a heap, the largest element (in a max heap) or the smallest element (in a min heap) is always at the root of the tree.\n * 4. Efficient Insertion and Deletion: Due to its structure, a heap allows for insertion and deletion operations in logarithmic time (O(log n)).\n * 5. Managing Dynamic Data Sets: Heaps effectively manage dynamic data sets, especially when frequent access to the largest or smallest elements is required.\n * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.\n * 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.\n * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prime's minimum-spanning tree algorithm, which use heaps to improve performance.\n */\nexport class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>> {\n /**\n * The constructor initializes a heap data structure with optional elements and options.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the heap.\n * It is an optional parameter, and if not provided, the heap will\n * be initialized as empty.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the heap.\n * In this case, it is used to specify a custom comparator\n * function for comparing elements in the heap.\n * The comparator function is used to determine the\n * order of elements in the heap.\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: HeapOptions<E, R>) {\n super(options);\n\n if (options) {\n const { comparator } = options;\n if (comparator) this._comparator = comparator;\n }\n\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) this.add(this.toElementFn(el as R));\n else this.add(el as E);\n }\n }\n }\n\n protected _elements: E[] = [];\n\n /**\n * The function returns an array of elements.\n * @returns The element array is being returned.\n */\n get elements(): E[] {\n return this._elements;\n }\n\n /**\n * Get the size (number of elements) of the heap.\n */\n get size(): number {\n return this.elements.length;\n }\n\n /**\n * Get the last element in the heap, which is not necessarily a leaf node.\n * @returns The last element or undefined if the heap is empty.\n */\n get leaf(): E | undefined {\n return this.elements[this.size - 1] ?? undefined;\n }\n\n /**\n * Static method that creates a binary heap from an array of elements and a comparison function.\n * @returns A new Heap instance.\n * @param elements\n * @param options\n */\n static heapify<E = any, R = any>(elements: Iterable<E>, options: HeapOptions<E, R>): Heap<E> {\n return new Heap<E>(elements, options);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Insert an element into the heap and maintain the heap properties.\n * @param element - The element to be inserted.\n */\n add(element: E): boolean {\n this._elements.push(element);\n return this._bubbleUp(this.elements.length - 1);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @returns The top element or undefined if the heap is empty.\n */\n poll(): E | undefined {\n if (this.elements.length === 0) return;\n const value = this.elements[0];\n const last = this.elements.pop()!;\n if (this.elements.length) {\n this.elements[0] = last;\n this._sinkDown(0, this.elements.length >> 1);\n }\n return value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Peek at the top element of the heap without removing it.\n * @returns The top element or undefined if the heap is empty.\n */\n peek(): E | undefined {\n return this.elements[0];\n }\n\n /**\n * Check if the heap is empty.\n * @returns True if the heap is empty, otherwise false.\n */\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n /**\n * Reset the elements of the heap. Make the elements empty.\n */\n clear(): void {\n this._elements = [];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Clear and add elements of the heap\n * @param elements\n */\n refill(elements: E[]): boolean[] {\n this._elements = elements;\n return this.fix();\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * Use a comparison function to check whether a binary heap contains a specific element.\n * @param element - the element to check.\n * @returns Returns true if the specified element is contained; otherwise, returns false.\n */\n override has(element: E): boolean {\n return this.elements.includes(element);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes an element from an array-like data structure, maintaining the order\n * and structure of the remaining elements.\n * @param {E} element - The `element` parameter represents the element that you want to delete from\n * the array `this.elements`.\n * @returns The `delete` function is returning a boolean value. It returns `true` if the element was\n * successfully deleted from the array, and `false` if the element was not found in the array.\n */\n delete(element: E): boolean {\n const index = this.elements.indexOf(element);\n if (index < 0) return false;\n if (index === 0) {\n this.poll();\n } else if (index === this.elements.length - 1) {\n this.elements.pop();\n } else {\n this.elements.splice(index, 1, this.elements.pop()!);\n this._bubbleUp(index);\n this._sinkDown(index, this.elements.length >> 1);\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * Depth-first search (DFS) method, different traversal orders can be selected。\n * @param order - Traverse order parameter: 'IN' (in-order), 'PRE' (pre-order) or 'POST' (post-order).\n * @returns An array containing elements traversed in the specified order.\n */\n dfs(order: DFSOrderPattern = 'PRE'): E[] {\n const result: E[] = [];\n\n // Auxiliary recursive function, traverses the binary heap according to the traversal order\n const _dfs = (index: number) => {\n const left = 2 * index + 1,\n right = left + 1;\n if (index < this.size) {\n if (order === 'IN') {\n _dfs(left);\n result.push(this.elements[index]);\n _dfs(right);\n } else if (order === 'PRE') {\n result.push(this.elements[index]);\n _dfs(left);\n _dfs(right);\n } else if (order === 'POST') {\n _dfs(left);\n _dfs(right);\n result.push(this.elements[index]);\n }\n }\n };\n\n _dfs(0); // Traverse starting from the root node\n\n return result;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Convert the heap to an array.\n * @returns An array containing the elements of the heap.\n */\n toArray(): E[] {\n return [...this.elements];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Clone the heap, creating a new heap with the same elements.\n * @returns A new Heap instance containing the same elements.\n */\n clone(): Heap<E, R> {\n return new Heap<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * Sort the elements in the heap and return them as an array.\n * @returns An array containing the elements sorted in ascending order.\n */\n sort(): E[] {\n const visitedNode: E[] = [];\n const cloned = new Heap<E, R>(this, { comparator: this.comparator });\n while (cloned.size !== 0) {\n const top = cloned.poll();\n if (top !== undefined) visitedNode.push(top);\n }\n return visitedNode;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * Fix the entire heap to maintain heap properties.\n */\n fix(): boolean[] {\n const results: boolean[] = [];\n for (let i = Math.floor(this.size / 2); i >= 0; i--) results.push(this._sinkDown(i, this.elements.length >> 1));\n return results;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new Heap object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Heap` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n filter(callback: ElementCallback<E, R, boolean, Heap<E, R>>, thisArg?: any): Heap<E, R> {\n const filteredList = new Heap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.add(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `Heap` class with the mapped elements.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Heap<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Heap<EM, RM> {\n const mappedHeap: Heap<EM, RM> = new Heap<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedHeap.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedHeap;\n }\n\n protected _DEFAULT_COMPARATOR = (a: E, b: E): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a > b) return 1;\n if (a < b) return -1;\n return 0;\n };\n\n protected _comparator: Comparator<E> = this._DEFAULT_COMPARATOR;\n\n /**\n * The function returns the value of the _comparator property.\n * @returns The `_comparator` property is being returned.\n */\n get comparator() {\n return this._comparator;\n }\n\n /**\n * The function `_getIterator` returns an iterable iterator for the elements in the class.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (const element of this.elements) {\n yield element;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Float operation to maintain heap properties after adding an element.\n * @param index - The index of the newly added element.\n */\n protected _bubbleUp(index: number): boolean {\n const element = this.elements[index];\n while (index > 0) {\n const parent = (index - 1) >> 1;\n const parentItem = this.elements[parent];\n if (this.comparator(parentItem, element) <= 0) break;\n this.elements[index] = parentItem;\n index = parent;\n }\n this.elements[index] = element;\n return true;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Sinking operation to maintain heap properties after removing the top element.\n * @param index - The index from which to start sinking.\n * @param halfLength\n */\n protected _sinkDown(index: number, halfLength: number): boolean {\n const element = this.elements[index];\n while (index < halfLength) {\n let left = (index << 1) | 1;\n const right = left + 1;\n let minItem = this.elements[left];\n if (right < this.elements.length && this.comparator(minItem, this.elements[right]) > 0) {\n left = right;\n minItem = this.elements[right];\n }\n if (this.comparator(minItem, element) >= 0) break;\n this.elements[index] = minItem;\n index = left;\n }\n this.elements[index] = element;\n return true;\n }\n}\n\nexport class FibonacciHeapNode<E> {\n element: E;\n degree: number;\n left?: FibonacciHeapNode<E>;\n right?: FibonacciHeapNode<E>;\n child?: FibonacciHeapNode<E>;\n parent?: FibonacciHeapNode<E>;\n marked: boolean;\n\n /**\n * The constructor function initializes an object with an element and a degree, and sets the marked\n * property to false.\n * @param {E} element - The \"element\" parameter represents the value or data that will be stored in\n * the node of a data structure. It can be any type of data, such as a number, string, object, or\n * even another data structure.\n * @param [degree=0] - The degree parameter represents the degree of the element in a data structure\n * called a Fibonacci heap. The degree of a node is the number of children it has. By default, the\n * degree is set to 0 when a new node is created.\n */\n constructor(element: E, degree = 0) {\n this.element = element;\n this.degree = degree;\n this.marked = false;\n }\n}\n\nexport class FibonacciHeap<E> {\n /**\n * The constructor function initializes a FibonacciHeap object with an optional comparator function.\n * @param [comparator] - The `comparator` parameter is an optional argument that represents a\n * function used to compare elements in the FibonacciHeap. If a comparator function is provided, it\n * will be used to determine the order of elements in the heap. If no comparator function is\n * provided, a default comparator function will be used.\n */\n constructor(comparator?: Comparator<E>) {\n this.clear();\n this._comparator = comparator || this._defaultComparator;\n\n if (typeof this.comparator !== 'function') {\n throw new Error('FibonacciHeap constructor: given comparator should be a function.');\n }\n }\n\n protected _root?: FibonacciHeapNode<E>;\n\n /**\n * The function returns the root node of a Fibonacci heap.\n * @returns The method is returning either a FibonacciHeapNode object or undefined.\n */\n get root(): FibonacciHeapNode<E> | undefined {\n return this._root;\n }\n\n protected _size = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n protected _min?: FibonacciHeapNode<E>;\n\n /**\n * The function returns the minimum node in a Fibonacci heap.\n * @returns The method is returning the minimum node of the Fibonacci heap, which is of type\n * `FibonacciHeapNode<E>`. If there is no minimum node, it will return `undefined`.\n */\n get min(): FibonacciHeapNode<E> | undefined {\n return this._min;\n }\n\n protected _comparator: Comparator<E>;\n\n /**\n * The function returns the comparator used for comparing elements.\n * @returns The `_comparator` property of the object.\n */\n get comparator(): Comparator<E> {\n return this._comparator;\n }\n\n /**\n * Get the size (number of elements) of the heap.\n * @returns {number} The size of the heap. Returns 0 if the heap is empty. Returns -1 if the heap is invalid.\n */\n clear(): void {\n this._root = undefined;\n this._min = undefined;\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Insert an element into the heap and maintain the heap properties.\n * @param element\n * @returns {FibonacciHeap<E>} FibonacciHeap<E> - The heap itself.\n */\n add(element: E): FibonacciHeap<E> {\n return this.push(element);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Insert an element into the heap and maintain the heap properties.\n * @param element\n * @returns {FibonacciHeap<E>} FibonacciHeap<E> - The heap itself.\n */\n push(element: E): FibonacciHeap<E> {\n const node = this.createNode(element);\n node.left = node;\n node.right = node;\n this.mergeWithRoot(node);\n\n if (!this.min || this.comparator(node.element, this.min.element) <= 0) {\n this._min = node;\n }\n\n this._size++;\n return this;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Peek at the top element of the heap without removing it.\n * @returns The top element or undefined if the heap is empty.\n * @protected\n */\n peek(): E | undefined {\n return this.min ? this.min.element : undefined;\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n *\n * Get the size (number of elements) of the heap.\n * @param {FibonacciHeapNode<E>} head - The head of the linked list.\n * @protected\n * @returns FibonacciHeapNode<E>[] - An array containing the elements of the linked list.\n */\n consumeLinkedList(head?: FibonacciHeapNode<E>): FibonacciHeapNode<E>[] {\n const elements: FibonacciHeapNode<E>[] = [];\n if (!head) return elements;\n\n let node: FibonacciHeapNode<E> | undefined = head;\n let flag = false;\n\n while (true) {\n if (node === head && flag) break;\n else if (node === head) flag = true;\n\n if (node) {\n elements.push(node);\n node = node.right;\n }\n }\n\n return elements;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * @param parent\n * @param node\n */\n mergeWithChild(parent: FibonacciHeapNode<E>, node: FibonacciHeapNode<E>): void {\n if (!parent.child) {\n parent.child = node;\n } else {\n node.right = parent.child.right;\n node.left = parent.child;\n parent.child.right!.left = node;\n parent.child.right = node;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @returns The top element or undefined if the heap is empty.\n */\n poll(): E | undefined {\n return this.pop();\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @returns The top element or undefined if the heap is empty.\n */\n pop(): E | undefined {\n if (this._size === 0) return undefined;\n\n const z = this.min!;\n if (z.child) {\n const elements = this.consumeLinkedList(z.child);\n for (const node of elements) {\n this.mergeWithRoot(node);\n node.parent = undefined;\n }\n }\n\n this.removeFromRoot(z);\n\n if (z === z.right) {\n this._min = undefined;\n this._root = undefined;\n } else {\n this._min = z.right;\n this._consolidate();\n }\n\n this._size--;\n\n return z.element;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * merge two heaps. The heap that is merged will be cleared. The heap that is merged into will remain.\n * @param heapToMerge\n */\n merge(heapToMerge: FibonacciHeap<E>): void {\n if (heapToMerge.size === 0) {\n return; // Nothing to merge\n }\n\n // Merge the root lists of the two heaps\n if (this.root && heapToMerge.root) {\n const thisRoot = this.root;\n const otherRoot = heapToMerge.root;\n\n const thisRootRight = thisRoot.right!;\n const otherRootLeft = otherRoot.left!;\n\n thisRoot.right = otherRoot;\n otherRoot.left = thisRoot;\n\n thisRootRight.left = otherRootLeft;\n otherRootLeft.right = thisRootRight;\n }\n\n // Update the minimum node\n if (!this.min || (heapToMerge.min && this.comparator(heapToMerge.min.element, this.min.element) < 0)) {\n this._min = heapToMerge.min;\n }\n\n // Update the size\n this._size += heapToMerge.size;\n\n // Clear the heap that was merged\n heapToMerge.clear();\n }\n\n /**\n * Create a new node.\n * @param element\n * @protected\n */\n createNode(element: E): FibonacciHeapNode<E> {\n return new FibonacciHeapNode<E>(element);\n }\n\n /**\n * Default comparator function used by the heap.\n * @param {E} a\n * @param {E} b\n * @protected\n */\n protected _defaultComparator(a: E, b: E): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Merge the given node with the root list.\n * @param node - The node to be merged.\n */\n protected mergeWithRoot(node: FibonacciHeapNode<E>): void {\n if (!this.root) {\n this._root = node;\n } else {\n node.right = this.root.right;\n node.left = this.root;\n this.root.right!.left = node;\n this.root.right = node;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @param node - The node to be removed.\n * @protected\n */\n protected removeFromRoot(node: FibonacciHeapNode<E>): void {\n if (this.root === node) this._root = node.right;\n if (node.left) node.left.right = node.right;\n if (node.right) node.right.left = node.left;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @param y\n * @param x\n * @protected\n */\n protected _link(y: FibonacciHeapNode<E>, x: FibonacciHeapNode<E>): void {\n this.removeFromRoot(y);\n y.left = y;\n y.right = y;\n this.mergeWithChild(x, y);\n x.degree++;\n y.parent = x;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @protected\n */\n protected _consolidate(): void {\n const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this._size);\n const elements = this.consumeLinkedList(this.root);\n let x: FibonacciHeapNode<E> | undefined,\n y: FibonacciHeapNode<E> | undefined,\n d: number,\n t: FibonacciHeapNode<E> | undefined;\n\n for (const node of elements) {\n x = node;\n d = x.degree;\n\n while (A[d]) {\n y = A[d] as FibonacciHeapNode<E>;\n\n if (this.comparator(x.element, y.element) > 0) {\n t = x;\n x = y;\n y = t;\n }\n\n this._link(y, x);\n A[d] = undefined;\n d++;\n }\n\n A[d] = x;\n }\n\n for (let i = 0; i < this._size; i++) {\n if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) {\n this._min = A[i]!;\n }\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, HeapOptions } from '../../types';\nimport { Heap } from './heap';\n\n/**\n * 1. Complete Binary Tree: Heaps are typically complete binary trees, meaning every level is fully filled except possibly for the last level, which has nodes as far left as possible.\n * 2. Heap Properties: The value of each parent node is greater than or equal to the value of its children.\n * 3. Root Node Access: In a heap, the largest element (in a max heap) or the smallest element (in a min heap) is always at the root of the tree.\n * 4. Efficient Insertion and Deletion: Due to its structure, a heap allows for insertion and deletion operations in logarithmic time (O(log n)).\n * 5. Managing Dynamic Data Sets: Heaps effectively manage dynamic data sets, especially when frequent access to the largest or smallest elements is required.\n * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.\n * 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.\n * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prim's minimum-spanning tree algorithm, which use heaps to improve performance.\n */\nexport class MaxHeap<E = any, R = any> extends Heap<E, R> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: HeapOptions<E, R>) {\n super(elements, {\n comparator: (a: E, b: E): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a < b) return 1;\n if (a > b) return -1;\n return 0;\n },\n ...options\n });\n }\n\n /**\n * The `clone` function returns a new instance of the `MaxHeap` class with the same properties as the\n * current instance.\n * @returns The `clone()` method is returning a new instance of the `MaxHeap` class with the same\n * properties as the current instance.\n */\n override clone(): MaxHeap<E, R> {\n return new MaxHeap<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MaxHeap object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MaxHeap` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(callback: ElementCallback<E, R, boolean, MaxHeap<E, R>>, thisArg?: any): MaxHeap<E, R> {\n const filteredList = new MaxHeap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.add(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MaxHeap` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MaxHeap<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MaxHeap<EM, RM> {\n const mappedHeap: MaxHeap<EM, RM> = new MaxHeap<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedHeap.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedHeap;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, HeapOptions } from '../../types';\nimport { Heap } from './heap';\n\n/**\n * 1. Complete Binary Tree: Heaps are typically complete binary trees, meaning every level is fully filled except possibly for the last level, which has nodes as far left as possible.\n * 2. MinHeap Properties: The value of each parent node is less than or equal to the value of its children.\n * 3. Root Node Access: In a heap, the largest element (in a max heap) or the smallest element (in a min heap) is always at the root of the tree.\n * 4. Efficient Insertion and Deletion: Due to its structure, a heap allows for insertion and deletion operations in logarithmic time (O(log n)).\n * 5. Managing Dynamic Data Sets: Heaps effectively manage dynamic data sets, especially when frequent access to the largest or smallest elements is required.\n * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.\n * 7. Efficient Sorting Algorithms: For example, heap sort. MinHeap sort uses the properties of a heap to sort elements.\n * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prim's minimum spanning tree algorithm, which use heaps to improve performance.\n */\nexport class MinHeap<E = any, R = any> extends Heap<E, R> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: HeapOptions<E, R>) {\n super(elements, options);\n }\n\n /**\n * The `clone` function returns a new instance of the `MinHeap` class with the same comparator and\n * toElementFn as the original instance.\n * @returns The `clone()` method is returning a new instance of the `MinHeap` class with the same\n * properties as the current instance.\n */\n override clone(): MinHeap<E, R> {\n return new MinHeap<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MinHeap object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MinHeap` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(callback: ElementCallback<E, R, boolean, MinHeap<E, R>>, thisArg?: any): MinHeap<E, R> {\n const filteredList = new MinHeap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.add(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MinHeap` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MinHeap<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MinHeap<EM, RM> {\n const mappedHeap: MinHeap<EM, RM> = new MinHeap<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedHeap.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedHeap;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { DijkstraResult, EntryCallback, VertexKey } from '../../types';\nimport { uuidV4 } from '../../utils';\nimport { IterableEntryBase } from '../base';\nimport { IGraph } from '../../interfaces';\nimport { Heap } from '../heap';\nimport { Queue } from '../queue';\n\nexport abstract class AbstractVertex<V = any> {\n key: VertexKey;\n value: V | undefined;\n\n /**\n * The function is a protected constructor that takes an key and an optional value as parameters.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex. It is\n * used to uniquely identify the vertex object.\n * @param {V} [value] - The parameter \"value\" is an optional parameter of type V. It is used to assign a value to the\n * vertex. If no value is provided, it will be set to undefined.\n */\n protected constructor(key: VertexKey, value?: V) {\n this.key = key;\n this.value = value;\n }\n}\n\nexport abstract class AbstractEdge<E = any> {\n value: E | undefined;\n weight: number;\n\n /**\n * The above function is a protected constructor that initializes the weight, value, and hash code properties of an\n * object.\n * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the object. If\n * a value is provided, it will be assigned to the `_weight` property. If no value is provided, the default value of 1\n * will be assigned.\n * @param {VO} [value] - The `value` parameter is of type `VO`, which means it can be any type. It is an optional parameter,\n * meaning it can be omitted when creating an instance of the class.\n */\n protected constructor(weight?: number, value?: E) {\n this.weight = weight !== undefined ? weight : 1;\n this.value = value;\n this._hashCode = uuidV4();\n }\n\n protected _hashCode: string;\n\n get hashCode(): string {\n return this._hashCode;\n }\n\n /**\n * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.\n * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.\n */\n}\n\nexport abstract class AbstractGraph<\n V = any,\n E = any,\n VO extends AbstractVertex<V> = AbstractVertex<V>,\n EO extends AbstractEdge<E> = AbstractEdge<E>\n >\n extends IterableEntryBase<VertexKey, V | undefined>\n implements IGraph<V, E, VO, EO>\n{\n constructor() {\n super();\n }\n\n protected _vertexMap: Map<VertexKey, VO> = new Map<VertexKey, VO>();\n\n get vertexMap(): Map<VertexKey, VO> {\n return this._vertexMap;\n }\n\n set vertexMap(v: Map<VertexKey, VO>) {\n this._vertexMap = v;\n }\n\n get size(): number {\n return this._vertexMap.size;\n }\n\n /**\n * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.\n * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.\n * @param key\n * @param value\n */\n abstract createVertex(key: VertexKey, value?: V): VO;\n\n /**\n * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.\n * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.\n * @param srcOrV1\n * @param destOrV2\n * @param weight\n * @param value\n */\n abstract createEdge(srcOrV1: VertexKey, destOrV2: VertexKey, weight?: number, value?: E): EO;\n\n abstract deleteEdge(edge: EO): EO | undefined;\n\n abstract getEdge(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined;\n\n abstract degreeOf(vertexOrKey: VO | VertexKey): number;\n\n abstract edgeSet(): EO[];\n\n abstract edgesOf(vertexOrKey: VO | VertexKey): EO[];\n\n abstract getNeighbors(vertexOrKey: VO | VertexKey): VO[];\n\n abstract getEndsOfEdge(edge: EO): [VO, VO] | undefined;\n\n /**\n * Time Complexity: O(1) - Constant time for Map lookup.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function \"getVertex\" returns the vertex with the specified ID or undefined if it doesn't exist.\n * @param {VertexKey} vertexKey - The `vertexKey` parameter is the identifier of the vertex that you want to retrieve from\n * the `_vertexMap` map.\n * @returns The method `getVertex` returns the vertex with the specified `vertexKey` if it exists in the `_vertexMap`\n * map. If the vertex does not exist, it returns `undefined`.\n */\n getVertex(vertexKey: VertexKey): VO | undefined {\n return this._vertexMap.get(vertexKey) || undefined;\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map lookup.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function checks if a vertex exists in a graph.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns a boolean value.\n */\n hasVertex(vertexOrKey: VO | VertexKey): boolean {\n return this._vertexMap.has(this._getVertexKey(vertexOrKey));\n }\n\n addVertex(vertex: VO): boolean;\n\n addVertex(key: VertexKey, value?: V): boolean;\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n */\n\n addVertex(keyOrVertex: VertexKey | VO, value?: V): boolean {\n if (keyOrVertex instanceof AbstractVertex) {\n return this._addVertex(keyOrVertex);\n } else {\n const newVertex = this.createVertex(keyOrVertex, value);\n return this._addVertex(newVertex);\n }\n }\n\n isVertexKey(potentialKey: any): potentialKey is VertexKey {\n const potentialKeyType = typeof potentialKey;\n return potentialKeyType === 'string' || potentialKeyType === 'number';\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n */\n\n abstract deleteVertex(vertexOrKey: VO | VertexKey): boolean;\n\n /**\n * Time Complexity: O(K), where K is the number of vertexMap to be removed.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function removes all vertexMap from a graph and returns a boolean indicating if any vertexMap were removed.\n * @param {VO[] | VertexKey[]} vertexMap - The `vertexMap` parameter can be either an array of vertexMap (`VO[]`) or an array\n * of vertex IDs (`VertexKey[]`).\n * @returns a boolean value. It returns true if at least one vertex was successfully removed, and false if no vertexMap\n * were removed.\n */\n removeManyVertices(vertexMap: VO[] | VertexKey[]): boolean {\n const removed: boolean[] = [];\n for (const v of vertexMap) {\n removed.push(this.deleteVertex(v));\n }\n return removed.length > 0;\n }\n\n /**\n * Time Complexity: O(1) - Depends on the implementation in the concrete class.\n * Space Complexity: O(1) - Depends on the implementation in the concrete class.\n *\n * The function checks if there is an edge between two vertexMap and returns a boolean value indicating the result.\n * @param {VertexKey | VO} v1 - The parameter v1 can be either a VertexKey or a VO. A VertexKey represents the unique\n * identifier of a vertex in a graph, while VO represents the type of the vertex object itself.\n * @param {VertexKey | VO} v2 - The parameter `v2` represents the second vertex in the edge. It can be either a\n * `VertexKey` or a `VO` type, which represents the type of the vertex.\n * @returns A boolean value is being returned.\n */\n hasEdge(v1: VertexKey | VO, v2: VertexKey | VO): boolean {\n const edge = this.getEdge(v1, v2);\n return !!edge;\n }\n\n addEdge(edge: EO): boolean;\n\n addEdge(src: VO | VertexKey, dest: VO | VertexKey, weight?: number, value?: E): boolean;\n\n /**\n * Time Complexity: O(1) - Depends on the implementation in the concrete class.\n * Space Complexity: O(1) - Depends on the implementation in the concrete class.\n */\n\n addEdge(srcOrEdge: VO | VertexKey | EO, dest?: VO | VertexKey, weight?: number, value?: E): boolean {\n if (srcOrEdge instanceof AbstractEdge) {\n return this._addEdge(srcOrEdge);\n } else {\n if (dest instanceof AbstractVertex || typeof dest === 'string' || typeof dest === 'number') {\n if (!(this.hasVertex(srcOrEdge) && this.hasVertex(dest))) return false;\n if (srcOrEdge instanceof AbstractVertex) srcOrEdge = srcOrEdge.key;\n if (dest instanceof AbstractVertex) dest = dest.key;\n const newEdge = this.createEdge(srcOrEdge, dest, weight, value);\n return this._addEdge(newEdge);\n } else {\n throw new Error('dest must be a Vertex or vertex key while srcOrEdge is an Edge');\n }\n }\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map and Edge operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function sets the weight of an edge between two vertexMap in a graph.\n * @param {VertexKey | VO} srcOrKey - The `srcOrKey` parameter can be either a `VertexKey` or a `VO` object. It represents\n * the source vertex of the edge.\n * @param {VertexKey | VO} destOrKey - The `destOrKey` parameter represents the destination vertex of the edge. It can be\n * either a `VertexKey` or a vertex object `VO`.\n * @param {number} weight - The weight parameter represents the weight of the edge between the source vertex (srcOrKey)\n * and the destination vertex (destOrKey).\n * @returns a boolean value. If the edge exists between the source and destination vertexMap, the function will update\n * the weight of the edge and return true. If the edge does not exist, the function will return false.\n */\n setEdgeWeight(srcOrKey: VertexKey | VO, destOrKey: VertexKey | VO, weight: number): boolean {\n const edge = this.getEdge(srcOrKey, destOrKey);\n if (edge) {\n edge.weight = weight;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Time Complexity: O(P), where P is the number of paths found (in the worst case, exploring all paths).\n * Space Complexity: O(P) - Linear space, where P is the number of paths found.\n *\n * The function `getAllPathsBetween` finds all paths between two vertexMap in a graph using depth-first search.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).\n * It is the starting vertex for finding paths.\n * @param {VO | VertexKey} v2 - The parameter `v2` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).\n * @param limit - The count of limitation of result array.\n * @returns The function `getAllPathsBetween` returns an array of arrays of vertexMap (`VO[][]`).\n */\n getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey, limit = 1000): VO[][] {\n const paths: VO[][] = [];\n const vertex1 = this._getVertex(v1);\n const vertex2 = this._getVertex(v2);\n\n if (!(vertex1 && vertex2)) {\n return [];\n }\n\n const stack: { vertex: VO; path: VO[] }[] = [];\n stack.push({ vertex: vertex1, path: [vertex1] });\n\n while (stack.length > 0) {\n const { vertex, path } = stack.pop()!;\n\n if (vertex === vertex2) {\n paths.push(path);\n if (paths.length >= limit) return paths;\n }\n\n const neighbors = this.getNeighbors(vertex);\n for (const neighbor of neighbors) {\n if (!path.includes(neighbor)) {\n const newPath = [...path, neighbor];\n stack.push({ vertex: neighbor, path: newPath });\n }\n }\n }\n return paths;\n }\n\n /**\n * Time Complexity: O(L), where L is the length of the path.\n * Space Complexity: O(1) - Constant space.\n *\n * The function calculates the sum of weights along a given path.\n * @param {VO[]} path - An array of vertexMap (VO) representing a path in a graph.\n * @returns The function `getPathSumWeight` returns the sum of the weights of the edgeMap in the given path.\n */\n getPathSumWeight(path: VO[]): number {\n let sum = 0;\n for (let i = 0; i < path.length; i++) {\n sum += this.getEdge(path[i], path[i + 1])?.weight || 0;\n }\n return sum;\n }\n\n /**\n * Time Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).\n * Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).\n *\n * The function `getMinCostBetween` calculates the minimum cost between two vertexMap in a graph, either based on edge\n * weights or using a breadth-first search algorithm.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex or its ID.\n * @param {VO | VertexKey} v2 - The parameter `v2` represents the destination vertex or its ID. It is the vertex to which\n * you want to find the minimum cost or weight from the source vertex `v1`.\n * @param {boolean} [isWeight] - isWeight is an optional parameter that indicates whether the graph edgeMap have weights.\n * If isWeight is set to true, the function will calculate the minimum cost between v1 and v2 based on the weights of\n * the edgeMap. If isWeight is set to false or not provided, the function will calculate the\n * @returns The function `getMinCostBetween` returns a number representing the minimum cost between two vertexMap (`v1`\n * and `v2`). If the `isWeight` parameter is `true`, it calculates the minimum weight among all paths between the\n * vertexMap. If `isWeight` is `false` or not provided, it uses a breadth-first search (BFS) algorithm to calculate the\n * minimum number of\n */\n getMinCostBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): number | undefined {\n if (isWeight === undefined) isWeight = false;\n\n if (isWeight) {\n const allPaths = this.getAllPathsBetween(v1, v2);\n let min = Infinity;\n for (const path of allPaths) {\n min = Math.min(this.getPathSumWeight(path), min);\n }\n return min;\n } else {\n // BFS\n const vertex2 = this._getVertex(v2);\n const vertex1 = this._getVertex(v1);\n if (!(vertex1 && vertex2)) {\n return undefined;\n }\n\n const visited: Map<VO, boolean> = new Map();\n const queue = new Queue<VO>([vertex1]);\n visited.set(vertex1, true);\n let cost = 0;\n while (queue.size > 0) {\n for (let i = 0; i < queue.size; i++) {\n const cur = queue.shift();\n if (cur === vertex2) {\n return cost;\n }\n // TODO consider optimizing to AbstractGraph\n if (cur !== undefined) {\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n visited.set(neighbor, true);\n queue.push(neighbor);\n }\n }\n }\n }\n cost++;\n }\n return undefined;\n }\n }\n\n /**\n * Time Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm or DFS).\n * Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm or DFS).\n *\n * The function `getMinPathBetween` returns the minimum path between two vertexMap in a graph, either based on weight or\n * using a breadth-first search algorithm.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex of the path. It can be either a vertex\n * object (`VO`) or a vertex ID (`VertexKey`).\n * @param {VO | VertexKey} v2 - VO | VertexKey - The second vertex or vertex ID between which we want to find the minimum\n * path.\n * @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edgeMap in finding the\n * minimum path. If set to true, the function will use Dijkstra's algorithm to find the minimum weighted path. If set\n * to false, the function will use breadth-first search (BFS) to find the minimum path.\n * @param isDFS - If set to true, it enforces the use of getAllPathsBetween to first obtain all possible paths,\n * followed by iterative computation of the shortest path. This approach may result in exponential time complexity,\n * so the default method is to use the Dijkstra algorithm to obtain the shortest weighted path.\n * @returns The function `getMinPathBetween` returns an array of vertexMap (`VO[]`) representing the minimum path between\n * two vertexMap (`v1` and `v2`). If there is no path between the vertexMap, it returns `undefined`.\n */\n getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS = false): VO[] | undefined {\n if (isWeight === undefined) isWeight = false;\n\n if (isWeight) {\n if (isDFS) {\n const allPaths = this.getAllPathsBetween(v1, v2, 10000);\n let min = Infinity;\n let minIndex = -1;\n let index = 0;\n for (const path of allPaths) {\n const pathSumWeight = this.getPathSumWeight(path);\n if (pathSumWeight < min) {\n min = pathSumWeight;\n minIndex = index;\n }\n index++;\n }\n return allPaths[minIndex] || undefined;\n } else {\n return this.dijkstra(v1, v2, true, true)?.minPath ?? [];\n }\n } else {\n // DFS\n let minPath: VO[] = [];\n const vertex1 = this._getVertex(v1);\n const vertex2 = this._getVertex(v2);\n if (!(vertex1 && vertex2)) return [];\n\n const dfs = (cur: VO, dest: VO, visiting: Set<VO>, path: VO[]) => {\n visiting.add(cur);\n if (cur === dest) {\n minPath = [vertex1, ...path];\n return;\n }\n\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!visiting.has(neighbor)) {\n path.push(neighbor);\n dfs(neighbor, dest, visiting, path);\n path.pop();\n }\n }\n\n visiting.delete(cur);\n };\n\n dfs(vertex1, vertex2, new Set<VO>(), []);\n return minPath;\n }\n }\n\n /**\n * Time Complexity: O(V^2 + E) - Quadratic time in the worst case (no heap optimization).\n * Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).\n *\n * The function `dijkstraWithoutHeap` implements Dijkstra's algorithm to find the shortest path between two vertexMap in\n * a graph without using a heap data structure.\n * @param {VO | VertexKey} src - The source vertex from which to start the Dijkstra's algorithm. It can be either a\n * vertex object or a vertex ID.\n * @param {VO | VertexKey | undefined} [dest] - The `dest` parameter in the `dijkstraWithoutHeap` function is an optional\n * parameter that specifies the destination vertex for the Dijkstra algorithm. It can be either a vertex object or its\n * identifier. If no destination is provided, the value is set to `undefined`.\n * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum\n * distance from the source vertex to the destination vertex should be calculated and returned in the result. If\n * `getMinDist` is set to `true`, the `minDist` property in the result will contain the minimum distance\n * @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate\n * paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the\n * shortest paths from the source vertex to all other vertexMap in the graph. If `genPaths\n * @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<VO>`.\n */\n dijkstraWithoutHeap(\n src: VO | VertexKey,\n dest: VO | VertexKey | undefined = undefined,\n getMinDist: boolean = false,\n genPaths: boolean = false\n ): DijkstraResult<VO> {\n let minDist = Infinity;\n let minDest: VO | undefined = undefined;\n let minPath: VO[] = [];\n const paths: VO[][] = [];\n\n const vertexMap = this._vertexMap;\n const distMap: Map<VO, number> = new Map();\n const seen: Set<VO> = new Set();\n const preMap: Map<VO, VO | undefined> = new Map(); // predecessor\n const srcVertex = this._getVertex(src);\n\n const destVertex = dest ? this._getVertex(dest) : undefined;\n\n if (!srcVertex) {\n return undefined;\n }\n\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);\n }\n distMap.set(srcVertex, 0);\n preMap.set(srcVertex, undefined);\n\n const getMinOfNoSeen = () => {\n let min = Infinity;\n let minV: VO | undefined = undefined;\n for (const [key, value] of distMap) {\n if (!seen.has(key)) {\n if (value < min) {\n min = value;\n minV = key;\n }\n }\n }\n return minV;\n };\n\n const getPaths = (minV: VO | undefined) => {\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n\n if (vertexOrKey instanceof AbstractVertex) {\n const path: VO[] = [vertexOrKey];\n let parent = preMap.get(vertexOrKey);\n while (parent) {\n path.push(parent);\n parent = preMap.get(parent);\n }\n const reversed = path.reverse();\n if (vertex[1] === minV) minPath = reversed;\n paths.push(reversed);\n }\n }\n };\n\n for (let i = 1; i < vertexMap.size; i++) {\n const cur = getMinOfNoSeen();\n if (cur) {\n seen.add(cur);\n if (destVertex && destVertex === cur) {\n if (getMinDist) {\n minDist = distMap.get(destVertex) || Infinity;\n }\n if (genPaths) {\n getPaths(destVertex);\n }\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!seen.has(neighbor)) {\n const edge = this.getEdge(cur, neighbor);\n if (edge) {\n const curFromMap = distMap.get(cur);\n const neighborFromMap = distMap.get(neighbor);\n // TODO after no-non-undefined-assertion not ensure the logic\n if (curFromMap !== undefined && neighborFromMap !== undefined) {\n if (edge.weight + curFromMap < neighborFromMap) {\n distMap.set(neighbor, edge.weight + curFromMap);\n preMap.set(neighbor, cur);\n }\n }\n }\n }\n }\n }\n }\n\n if (getMinDist)\n distMap.forEach((d, v) => {\n if (v !== srcVertex) {\n if (d < minDist) {\n minDist = d;\n if (genPaths) minDest = v;\n }\n }\n });\n\n if (genPaths) getPaths(minDest);\n\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n\n /**\n * Time Complexity: O((V + E) * log(V)) - Depends on the implementation (using a binary heap).\n * Space Complexity: O(V + E) - Depends on the implementation (using a binary heap).\n *\n * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative.\n * The `dijkstra` function implements Dijkstra's algorithm to find the shortest path between a source vertex and an\n * optional destination vertex, and optionally returns the minimum distance, the paths, and other information.\n * @param {VO | VertexKey} src - The `src` parameter represents the source vertex from which the Dijkstra algorithm will\n * start. It can be either a vertex object or a vertex ID.\n * @param {VO | VertexKey | undefined} [dest] - The `dest` parameter is the destination vertex or vertex ID. It specifies the\n * vertex to which the shortest path is calculated from the source vertex. If no destination is provided, the algorithm\n * will calculate the shortest paths to all other vertexMap from the source vertex.\n * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum\n * distance from the source vertex to the destination vertex should be calculated and returned in the result. If\n * `getMinDist` is set to `true`, the `minDist` property in the result will contain the minimum distance\n * @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate\n * paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the\n * shortest paths from the source vertex to all other vertexMap in the graph. If `genPaths\n * @returns The function `dijkstra` returns an object of type `DijkstraResult<VO>`.\n */\n dijkstra(\n src: VO | VertexKey,\n dest: VO | VertexKey | undefined = undefined,\n getMinDist: boolean = false,\n genPaths: boolean = false\n ): DijkstraResult<VO> {\n let minDist = Infinity;\n let minDest: VO | undefined = undefined;\n let minPath: VO[] = [];\n const paths: VO[][] = [];\n const vertexMap = this._vertexMap;\n const distMap: Map<VO, number> = new Map();\n const seen: Set<VO> = new Set();\n const preMap: Map<VO, VO | undefined> = new Map(); // predecessor\n\n const srcVertex = this._getVertex(src);\n const destVertex = dest ? this._getVertex(dest) : undefined;\n\n if (!srcVertex) return undefined;\n\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);\n }\n\n const heap = new Heap<{ key: number; value: VO }>([], { comparator: (a, b) => a.key - b.key });\n heap.add({ key: 0, value: srcVertex });\n\n distMap.set(srcVertex, 0);\n preMap.set(srcVertex, undefined);\n\n /**\n * The function `getPaths` retrieves all paths from vertexMap to a specified minimum vertex.\n * @param {VO | undefined} minV - The parameter `minV` is of type `VO | undefined`. It represents the minimum vertex value or\n * undefined.\n */\n const getPaths = (minV: VO | undefined) => {\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) {\n const path: VO[] = [vertexOrKey];\n let parent = preMap.get(vertexOrKey);\n while (parent) {\n path.push(parent);\n parent = preMap.get(parent);\n }\n const reversed = path.reverse();\n if (vertex[1] === minV) minPath = reversed;\n paths.push(reversed);\n }\n }\n };\n\n while (heap.size > 0) {\n const curHeapNode = heap.poll();\n const dist = curHeapNode?.key;\n const cur = curHeapNode?.value;\n if (dist !== undefined) {\n if (cur) {\n seen.add(cur);\n if (destVertex && destVertex === cur) {\n if (getMinDist) {\n minDist = distMap.get(destVertex) || Infinity;\n }\n if (genPaths) {\n getPaths(destVertex);\n }\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!seen.has(neighbor)) {\n const weight = this.getEdge(cur, neighbor)?.weight;\n if (typeof weight === 'number') {\n const distSrcToNeighbor = distMap.get(neighbor);\n if (distSrcToNeighbor) {\n if (dist + weight < distSrcToNeighbor) {\n heap.add({ key: dist + weight, value: neighbor });\n preMap.set(neighbor, cur);\n distMap.set(neighbor, dist + weight);\n }\n }\n }\n }\n }\n }\n }\n }\n\n if (getMinDist) {\n distMap.forEach((d, v) => {\n if (v !== srcVertex) {\n if (d < minDist) {\n minDist = d;\n if (genPaths) minDest = v;\n }\n }\n });\n }\n\n if (genPaths) {\n getPaths(minDest);\n }\n\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n\n /**\n * Time Complexity: O(V * E) - Quadratic time in the worst case (Bellman-Ford algorithm).\n * Space Complexity: O(V + E) - Depends on the implementation (Bellman-Ford algorithm).\n *\n * one to rest pairs\n * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edgeMap for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edgeMap, the Bellman-Ford algorithm is more flexible in some scenarios.\n * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to\n * all other vertexMap in a graph, and optionally detects negative cycles and generates the minimum path.\n * @param {VO | VertexKey} src - The `src` parameter is the source vertex from which the Bellman-Ford algorithm will\n * start calculating the shortest paths. It can be either a vertex object or a vertex ID.\n * @param {boolean} [scanNegativeCycle] - A boolean flag indicating whether to scan for negative cycles in the graph.\n * @param {boolean} [getMin] - The `getMin` parameter is a boolean flag that determines whether the algorithm should\n * calculate the minimum distance from the source vertex to all other vertexMap in the graph. If `getMin` is set to\n * `true`, the algorithm will find the minimum distance and update the `min` variable with the minimum\n * @param {boolean} [genPath] - A boolean flag indicating whether to generate paths for all vertexMap from the source\n * vertex.\n * @returns The function `bellmanFord` returns an object with the following properties:\n */\n bellmanFord(src: VO | VertexKey, scanNegativeCycle?: boolean, getMin?: boolean, genPath?: boolean) {\n if (getMin === undefined) getMin = false;\n if (genPath === undefined) genPath = false;\n\n const srcVertex = this._getVertex(src);\n const paths: VO[][] = [];\n const distMap: Map<VO, number> = new Map();\n const preMap: Map<VO, VO> = new Map(); // predecessor\n let min = Infinity;\n let minPath: VO[] = [];\n // TODO\n let hasNegativeCycle: boolean | undefined;\n if (scanNegativeCycle) hasNegativeCycle = false;\n if (!srcVertex) return { hasNegativeCycle, distMap, preMap, paths, min, minPath };\n\n const vertexMap = this._vertexMap;\n const numOfVertices = vertexMap.size;\n const edgeMap = this.edgeSet();\n const numOfEdges = edgeMap.length;\n\n this._vertexMap.forEach(vertex => {\n distMap.set(vertex, Infinity);\n });\n\n distMap.set(srcVertex, 0);\n\n for (let i = 1; i < numOfVertices; ++i) {\n for (let j = 0; j < numOfEdges; ++j) {\n const ends = this.getEndsOfEdge(edgeMap[j]);\n if (ends) {\n const [s, d] = ends;\n const weight = edgeMap[j].weight;\n const sWeight = distMap.get(s);\n const dWeight = distMap.get(d);\n if (sWeight !== undefined && dWeight !== undefined) {\n if (distMap.get(s) !== Infinity && sWeight + weight < dWeight) {\n distMap.set(d, sWeight + weight);\n if (genPath) preMap.set(d, s);\n }\n }\n }\n }\n }\n\n let minDest: VO | undefined = undefined;\n if (getMin) {\n distMap.forEach((d, v) => {\n if (v !== srcVertex) {\n if (d < min) {\n min = d;\n if (genPath) minDest = v;\n }\n }\n });\n }\n\n if (genPath) {\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) {\n const path: VO[] = [vertexOrKey];\n let parent = preMap.get(vertexOrKey);\n while (parent !== undefined) {\n path.push(parent);\n parent = preMap.get(parent);\n }\n const reversed = path.reverse();\n if (vertex[1] === minDest) minPath = reversed;\n paths.push(reversed);\n }\n }\n }\n\n for (let j = 0; j < numOfEdges; ++j) {\n const ends = this.getEndsOfEdge(edgeMap[j]);\n if (ends) {\n const [s] = ends;\n const weight = edgeMap[j].weight;\n const sWeight = distMap.get(s);\n if (sWeight) {\n if (sWeight !== Infinity && sWeight + weight < sWeight) hasNegativeCycle = true;\n }\n }\n }\n\n return { hasNegativeCycle, distMap, preMap, paths, min, minPath };\n }\n\n /**\n * Dijkstra algorithm time: O(logVE) space: O(VO + EO)\n */\n\n /**\n * Dijkstra algorithm time: O(logVE) space: O(VO + EO)\n * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative.\n */\n\n /**\n * BellmanFord time:O(VE) space:O(VO)\n * one to rest pairs\n * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edgeMap for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edgeMap, the Bellman-Ford algorithm is more flexible in some scenarios.\n * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to\n */\n\n /**\n * Time Complexity: O(V^3) - Cubic time (Floyd-Warshall algorithm).\n * Space Complexity: O(V^2) - Quadratic space (Floyd-Warshall algorithm).\n *\n * Not support graph with negative weight cycle\n * all pairs\n * The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edgeMap, and it can simultaneously compute shortest paths between any two nodes.\n * The function implements the Floyd-Warshall algorithm to find the shortest path between all pairs of vertexMap in a\n * graph.\n * @returns The function `floydWarshall()` returns an object with two properties: `costs` and `predecessor`. The `costs`\n * property is a 2D array of numbers representing the shortest path costs between vertexMap in a graph. The\n * `predecessor` property is a 2D array of vertexMap (or `undefined`) representing the predecessor vertexMap in the shortest\n * path between vertexMap in the\n */\n floydWarshall(): { costs: number[][]; predecessor: (VO | undefined)[][] } {\n const idAndVertices = [...this._vertexMap];\n const n = idAndVertices.length;\n\n const costs: number[][] = [];\n const predecessor: (VO | undefined)[][] = [];\n // successors\n\n for (let i = 0; i < n; i++) {\n costs[i] = [];\n predecessor[i] = [];\n for (let j = 0; j < n; j++) {\n predecessor[i][j] = undefined;\n }\n }\n\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n costs[i][j] = this.getEdge(idAndVertices[i][1], idAndVertices[j][1])?.weight || Infinity;\n }\n }\n\n for (let k = 0; k < n; k++) {\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (costs[i][j] > costs[i][k] + costs[k][j]) {\n costs[i][j] = costs[i][k] + costs[k][j];\n predecessor[i][j] = idAndVertices[k][1];\n }\n }\n }\n }\n return { costs, predecessor };\n }\n\n /**\n * O(V+E+C)\n * O(V+C)\n */\n getCycles(isInclude2Cycle: boolean = false): VertexKey[][] {\n const cycles: VertexKey[][] = [];\n const visited: Set<VO> = new Set();\n\n const dfs = (vertex: VO, currentPath: VertexKey[], visited: Set<VO>) => {\n if (visited.has(vertex)) {\n if (\n ((!isInclude2Cycle && currentPath.length > 2) || (isInclude2Cycle && currentPath.length >= 2)) &&\n currentPath[0] === vertex.key\n ) {\n cycles.push([...currentPath]);\n }\n return;\n }\n\n visited.add(vertex);\n currentPath.push(vertex.key);\n\n for (const neighbor of this.getNeighbors(vertex)) {\n if (neighbor) dfs(neighbor, currentPath, visited);\n }\n\n visited.delete(vertex);\n currentPath.pop();\n };\n\n for (const vertex of this.vertexMap.values()) {\n dfs(vertex, [], visited);\n }\n\n // Use a set to eliminate duplicate cycles\n const uniqueCycles = new Map<string, VertexKey[]>();\n\n for (const cycle of cycles) {\n const sorted = [...cycle].sort().toString();\n\n if (uniqueCycles.has(sorted)) continue;\n else {\n uniqueCycles.set(sorted, cycle);\n }\n }\n\n // Convert the unique cycles back to an array\n return [...uniqueCycles].map(cycleString => cycleString[1]);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function iterates over key-value pairs in a data structure and returns an array of\n * pairs that satisfy a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes four arguments:\n * `value`, `key`, `index`, and `this`. It is used to determine whether an element should be included\n * in the filtered array. The callback function should return `true` if the element should be\n * included, and `\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the `predicate` function. It is used when you want to bind a\n * specific object as the context for the `predicate` function. If `thisArg` is provided, it will be\n * @returns The `filter` method returns an array of key-value pairs `[VertexKey, V | undefined][]`\n * that satisfy the given predicate function.\n */\n filter(predicate: EntryCallback<VertexKey, V | undefined, boolean>, thisArg?: any): [VertexKey, V | undefined][] {\n const filtered: [VertexKey, V | undefined][] = [];\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index, this)) {\n filtered.push([key, value]);\n }\n index++;\n }\n return filtered;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function iterates over the elements of a collection and applies a callback function to\n * each element, returning an array of the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * map. It takes four arguments:\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. If `thisArg` is provided, it will be\n * used as the `this` value when calling the callback function. If `thisArg` is not provided, `\n * @returns The `map` function is returning an array of type `T[]`.\n */\n map<T>(callback: EntryCallback<VertexKey, V | undefined, T>, thisArg?: any): T[] {\n const mapped: T[] = [];\n let index = 0;\n for (const [key, value] of this) {\n mapped.push(callback.call(thisArg, value, key, index, this));\n index++;\n }\n return mapped;\n }\n\n protected *_getIterator(): IterableIterator<[VertexKey, V | undefined]> {\n for (const vertex of this._vertexMap.values()) {\n yield [vertex.key, vertex.value];\n }\n }\n\n protected abstract _addEdge(edge: EO): boolean;\n\n protected _addVertex(newVertex: VO): boolean {\n if (this.hasVertex(newVertex)) {\n return false;\n // throw (new Error('Duplicated vertex key is not allowed'));\n }\n this._vertexMap.set(newVertex.key, newVertex);\n return true;\n }\n\n protected _getVertex(vertexOrKey: VertexKey | VO): VO | undefined {\n const vertexKey = this._getVertexKey(vertexOrKey);\n return this._vertexMap.get(vertexKey) || undefined;\n }\n\n protected _getVertexKey(vertexOrKey: VO | VertexKey): VertexKey {\n return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { TopologicalStatus, VertexKey } from '../../types';\nimport { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';\nimport { IGraph } from '../../interfaces';\nimport { arrayRemove } from '../../utils';\n\nexport class DirectedVertex<V = any> extends AbstractVertex<V> {\n /**\n * The constructor function initializes a vertex with an optional value.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex. It is\n * used to uniquely identify the vertex within a graph or data structure.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It is used to initialize the value of the\n * vertex. If no value is provided, the vertex will be initialized with a default value.\n */\n constructor(key: VertexKey, value?: V) {\n super(key, value);\n }\n}\n\nexport class DirectedEdge<E = any> extends AbstractEdge<E> {\n src: VertexKey;\n dest: VertexKey;\n\n /**\n * The constructor function initializes the source and destination vertexMap of an edge, along with an optional weight\n * and value.\n * @param {VertexKey} src - The `src` parameter is the source vertex ID. It represents the starting point of an edge in\n * a graph.\n * @param {VertexKey} dest - The `dest` parameter represents the destination vertex of an edge. It is of type\n * `VertexKey`, which is likely a unique identifier for a vertex in a graph.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.\n * @param {E} [value] - The `value` parameter is an optional parameter of type `E`. It represents the value associated with\n * the edge.\n */\n constructor(src: VertexKey, dest: VertexKey, weight?: number, value?: E) {\n super(weight, value);\n this.src = src;\n this.dest = dest;\n }\n}\n\nexport class DirectedGraph<\n V = any,\n E = any,\n VO extends DirectedVertex<V> = DirectedVertex<V>,\n EO extends DirectedEdge<E> = DirectedEdge<E>\n >\n extends AbstractGraph<V, E, VO, EO>\n implements IGraph<V, E, VO, EO>\n{\n /**\n * The constructor function initializes an instance of a class.\n */\n constructor() {\n super();\n }\n\n protected _outEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();\n\n get outEdgeMap(): Map<VO, EO[]> {\n return this._outEdgeMap;\n }\n\n set outEdgeMap(v: Map<VO, EO[]>) {\n this._outEdgeMap = v;\n }\n\n protected _inEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();\n\n get inEdgeMap(): Map<VO, EO[]> {\n return this._inEdgeMap;\n }\n\n set inEdgeMap(v: Map<VO, EO[]>) {\n this._inEdgeMap = v;\n }\n\n /**\n * The function creates a new vertex with an optional value and returns it.\n * @param {VertexKey} key - The `key` parameter is the unique identifier for the vertex. It is of type `VertexKey`, which\n * could be a number or a string depending on how you want to identify your vertexMap.\n * @param [value] - The 'value' parameter is an optional value that can be assigned to the vertex. If a value is provided,\n * it will be assigned to the 'value' property of the vertex. If no value is provided, the 'value' property will be\n * assigned the same value as the 'key' parameter\n * @returns a new instance of a DirectedVertex object, casted as type VO.\n */\n createVertex(key: VertexKey, value?: V): VO {\n return new DirectedVertex(key, value) as VO;\n }\n\n /**\n * The function creates a directed edge between two vertexMap with an optional weight and value.\n * @param {VertexKey} src - The source vertex ID of the edge. It represents the starting point of the edge.\n * @param {VertexKey} dest - The `dest` parameter is the identifier of the destination vertex for the edge.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge. If no\n * weight is provided, it defaults to 1.\n * @param [value] - The 'value' parameter is an optional value that can be assigned to the edge. It can be of any type and\n * is used to store additional information or data associated with the edge.\n * @returns a new instance of a DirectedEdge object, casted as type EO.\n */\n createEdge(src: VertexKey, dest: VertexKey, weight?: number, value?: E): EO {\n return new DirectedEdge(src, dest, weight ?? 1, value) as EO;\n }\n\n /**\n * Time Complexity: O(|V|) where |V| is the number of vertexMap\n * Space Complexity: O(1)\n *\n * The `getEdge` function retrieves an edge between two vertexMap based on their source and destination IDs.\n * @param {VO | VertexKey | undefined} srcOrKey - The source vertex or its ID. It can be either a vertex object or a vertex ID.\n * @param {VO | VertexKey | undefined} destOrKey - The `destOrKey` parameter in the `getEdge` function represents the\n * destination vertex of the edge. It can be either a vertex object (`VO`), a vertex ID (`VertexKey`), or `undefined` if the\n * destination is not specified.\n * @returns the first edge found between the source and destination vertexMap, or undefined if no such edge is found.\n */\n getEdge(srcOrKey: VO | VertexKey | undefined, destOrKey: VO | VertexKey | undefined): EO | undefined {\n let edgeMap: EO[] = [];\n\n if (srcOrKey !== undefined && destOrKey !== undefined) {\n const src: VO | undefined = this._getVertex(srcOrKey);\n const dest: VO | undefined = this._getVertex(destOrKey);\n\n if (src && dest) {\n const srcOutEdges = this._outEdgeMap.get(src);\n if (srcOutEdges) {\n edgeMap = srcOutEdges.filter(edge => edge.dest === dest.key);\n }\n }\n }\n\n return edgeMap[0] || undefined;\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function removes an edge between two vertexMap in a graph and returns the removed edge.\n * @param {VO | VertexKey} srcOrKey - The source vertex or its ID.\n * @param {VO | VertexKey} destOrKey - The `destOrKey` parameter represents the destination vertex or its ID.\n * @returns the removed edge (EO) if it exists, or undefined if either the source or destination vertex does not exist.\n */\n deleteEdgeSrcToDest(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined {\n const src: VO | undefined = this._getVertex(srcOrKey);\n const dest: VO | undefined = this._getVertex(destOrKey);\n let removed: EO | undefined = undefined;\n if (!src || !dest) {\n return undefined;\n }\n\n const srcOutEdges = this._outEdgeMap.get(src);\n if (srcOutEdges) {\n arrayRemove<EO>(srcOutEdges, (edge: EO) => edge.dest === dest.key);\n }\n\n const destInEdges = this._inEdgeMap.get(dest);\n if (destInEdges) {\n removed = arrayRemove<EO>(destInEdges, (edge: EO) => edge.src === src.key)[0] || undefined;\n }\n return removed;\n }\n\n /**\n * Time Complexity: O(E) where E is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The `deleteEdge` function removes an edge from a graph and returns the removed edge.\n * @param {EO | VertexKey} edgeOrSrcVertexKey - The `edge` parameter can be either an `EO` object (edge object) or\n * a `VertexKey` (key of a vertex).\n * @param {VertexKey} [destVertexKey] - The `destVertexKey` parameter is an optional parameter that\n * represents the key of the destination vertex of the edge. It is used to specify the destination\n * vertex when the `edge` parameter is a vertex key. If `destVertexKey` is not provided, the function\n * assumes that the `edge`\n * @returns the removed edge (EO) or undefined if no edge was removed.\n */\n deleteEdge(edgeOrSrcVertexKey: EO | VertexKey, destVertexKey?: VertexKey): EO | undefined {\n let removed: EO | undefined = undefined;\n let src: VO | undefined, dest: VO | undefined;\n if (this.isVertexKey(edgeOrSrcVertexKey)) {\n if (this.isVertexKey(destVertexKey)) {\n src = this._getVertex(edgeOrSrcVertexKey);\n dest = this._getVertex(destVertexKey);\n } else {\n return;\n }\n } else {\n src = this._getVertex(edgeOrSrcVertexKey.src);\n dest = this._getVertex(edgeOrSrcVertexKey.dest);\n }\n\n if (src && dest) {\n const srcOutEdges = this._outEdgeMap.get(src);\n if (srcOutEdges && srcOutEdges.length > 0) {\n arrayRemove(srcOutEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest?.key);\n }\n\n const destInEdges = this._inEdgeMap.get(dest);\n if (destInEdges && destInEdges.length > 0) {\n removed = arrayRemove(destInEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest!.key)[0];\n }\n }\n\n return removed;\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method is returning a boolean value.\n */\n deleteVertex(vertexOrKey: VO | VertexKey): boolean {\n let vertexKey: VertexKey;\n let vertex: VO | undefined;\n if (this.isVertexKey(vertexOrKey)) {\n vertex = this.getVertex(vertexOrKey);\n vertexKey = vertexOrKey;\n } else {\n vertex = vertexOrKey;\n vertexKey = this._getVertexKey(vertexOrKey);\n }\n\n if (vertex) {\n const neighbors = this.getNeighbors(vertex);\n for (const neighbor of neighbors) {\n // this._inEdgeMap.delete(neighbor);\n this.deleteEdgeSrcToDest(vertex, neighbor);\n }\n this._outEdgeMap.delete(vertex);\n this._inEdgeMap.delete(vertex);\n }\n\n return this._vertexMap.delete(vertexKey);\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function removes edgeMap between two vertexMap and returns the removed edgeMap.\n * @param {VertexKey | VO} v1 - The parameter `v1` can be either a `VertexKey` or a `VO`. A `VertexKey` represents the\n * unique identifier of a vertex in a graph, while `VO` represents the actual vertex object.\n * @param {VertexKey | VO} v2 - The parameter `v2` represents either a `VertexKey` or a `VO` object. It is used to specify\n * the second vertex in the edge that needs to be removed.\n * @returns an array of removed edgeMap (EO[]).\n */\n deleteEdgesBetween(v1: VertexKey | VO, v2: VertexKey | VO): EO[] {\n const removed: EO[] = [];\n\n if (v1 && v2) {\n const v1ToV2 = this.deleteEdgeSrcToDest(v1, v2);\n const v2ToV1 = this.deleteEdgeSrcToDest(v2, v1);\n\n if (v1ToV2) removed.push(v1ToV2);\n if (v2ToV1) removed.push(v2ToV1);\n }\n\n return removed;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `incomingEdgesOf` returns an array of incoming edgeMap for a given vertex or vertex ID.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method `incomingEdgesOf` returns an array of edgeMap (`EO[]`).\n */\n incomingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {\n const target = this._getVertex(vertexOrKey);\n if (target) {\n return this.inEdgeMap.get(target) || [];\n }\n return [];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `outgoingEdgesOf` returns an array of outgoing edgeMap from a given vertex or vertex ID.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can accept either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method `outgoingEdgesOf` returns an array of edgeMap (`EO[]`).\n */\n outgoingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {\n const target = this._getVertex(vertexOrKey);\n if (target) {\n return this._outEdgeMap.get(target) || [];\n }\n return [];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"degreeOf\" returns the total degree of a vertex, which is the sum of its out-degree and in-degree.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The sum of the out-degree and in-degree of the specified vertex or vertex ID.\n */\n degreeOf(vertexOrKey: VertexKey | VO): number {\n return this.outDegreeOf(vertexOrKey) + this.inDegreeOf(vertexOrKey);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"inDegreeOf\" returns the number of incoming edgeMap for a given vertex.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The number of incoming edgeMap of the specified vertex or vertex ID.\n */\n inDegreeOf(vertexOrKey: VertexKey | VO): number {\n return this.incomingEdgesOf(vertexOrKey).length;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `outDegreeOf` returns the number of outgoing edgeMap from a given vertex.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The number of outgoing edgeMap from the specified vertex or vertex ID.\n */\n outDegreeOf(vertexOrKey: VertexKey | VO): number {\n return this.outgoingEdgesOf(vertexOrKey).length;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"edgesOf\" returns an array of both outgoing and incoming edgeMap of a given vertex or vertex ID.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The function `edgesOf` returns an array of edgeMap.\n */\n edgesOf(vertexOrKey: VertexKey | VO): EO[] {\n return [...this.outgoingEdgesOf(vertexOrKey), ...this.incomingEdgesOf(vertexOrKey)];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEdgeSrc\" returns the source vertex of an edge, or undefined if the edge does not exist.\n * @param {EO} e - The parameter \"e\" is of type EO, which represents an edge in a graph.\n * @returns either a vertex object (VO) or undefined.\n */\n getEdgeSrc(e: EO): VO | undefined {\n return this._getVertex(e.src);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEdgeDest\" returns the destination vertex of an edge.\n * @param {EO} e - The parameter \"e\" is of type \"EO\", which represents an edge in a graph.\n * @returns either a vertex object of type VO or undefined.\n */\n getEdgeDest(e: EO): VO | undefined {\n return this._getVertex(e.dest);\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function `getDestinations` returns an array of destination vertexMap connected to a given vertex.\n * @param {VO | VertexKey | undefined} vertex - The `vertex` parameter represents the starting vertex from which we want to\n * find the destinations. It can be either a `VO` object, a `VertexKey` value, or `undefined`.\n * @returns an array of vertexMap (VO[]).\n */\n getDestinations(vertex: VO | VertexKey | undefined): VO[] {\n if (vertex === undefined) {\n return [];\n }\n const destinations: VO[] = [];\n const outgoingEdges = this.outgoingEdgesOf(vertex);\n for (const outEdge of outgoingEdges) {\n const child = this.getEdgeDest(outEdge);\n if (child) {\n destinations.push(child);\n }\n }\n return destinations;\n }\n\n /**\n * Time Complexity: O(|V| + |E|) where |V| is the number of vertexMap and |E| is the number of edgeMap\n * Space Complexity: O(|V|)\n *\n * The `topologicalSort` function performs a topological sort on a graph and returns an array of vertexMap or vertex IDs\n * in the sorted order, or undefined if the graph contains a cycle.\n * @param {'vertex' | 'key'} [propertyName] - The `propertyName` parameter is an optional parameter that specifies the\n * property to use for sorting the vertexMap. It can have two possible values: 'vertex' or 'key'. If 'vertex' is\n * specified, the vertexMap themselves will be used for sorting. If 'key' is specified, the ids of\n * @returns an array of vertexMap or vertex IDs in topological order. If there is a cycle in the graph, it returns undefined.\n */\n topologicalSort(propertyName?: 'vertex' | 'key'): Array<VO | VertexKey> | undefined {\n propertyName = propertyName ?? 'key';\n // When judging whether there is a cycle in the undirected graph, all nodes with degree of **<= 1** are enqueued\n // When judging whether there is a cycle in the directed graph, all nodes with **in degree = 0** are enqueued\n const statusMap: Map<VO | VertexKey, TopologicalStatus> = new Map<VO | VertexKey, TopologicalStatus>();\n for (const entry of this.vertexMap) {\n statusMap.set(entry[1], 0);\n }\n\n let sorted: (VO | VertexKey)[] = [];\n let hasCycle = false;\n const dfs = (cur: VO | VertexKey) => {\n statusMap.set(cur, 1);\n const children = this.getDestinations(cur);\n for (const child of children) {\n const childStatus = statusMap.get(child);\n if (childStatus === 0) {\n dfs(child);\n } else if (childStatus === 1) {\n hasCycle = true;\n }\n }\n statusMap.set(cur, 2);\n sorted.push(cur);\n };\n\n for (const entry of this.vertexMap) {\n if (statusMap.get(entry[1]) === 0) {\n dfs(entry[1]);\n }\n }\n\n if (hasCycle) return undefined;\n\n if (propertyName === 'key') sorted = sorted.map(vertex => (vertex instanceof DirectedVertex ? vertex.key : vertex));\n return sorted.reverse();\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(|E|)\n *\n * The `edgeSet` function returns an array of all the edgeMap in the graph.\n * @returns The `edgeSet()` method returns an array of edgeMap (`EO[]`).\n */\n edgeSet(): EO[] {\n let edgeMap: EO[] = [];\n this._outEdgeMap.forEach(outEdges => {\n edgeMap = [...edgeMap, ...outEdges];\n });\n return edgeMap;\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function `getNeighbors` returns an array of neighboring vertexMap of a given vertex or vertex ID in a graph.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns an array of vertexMap (VO[]).\n */\n getNeighbors(vertexOrKey: VO | VertexKey): VO[] {\n const neighbors: VO[] = [];\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n const outEdges = this.outgoingEdgesOf(vertex);\n for (const outEdge of outEdges) {\n const neighbor = this._getVertex(outEdge.dest);\n // TODO after no-non-undefined-assertion not ensure the logic\n if (neighbor) {\n neighbors.push(neighbor);\n }\n }\n }\n return neighbors;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEndsOfEdge\" returns the source and destination vertexMap of an edge if it exists in the graph,\n * otherwise it returns undefined.\n * @param {EO} edge - The parameter `edge` is of type `EO`, which represents an edge in a graph.\n * @returns The function `getEndsOfEdge` returns an array containing two vertexMap `[VO, VO]` if the edge exists in the\n * graph. If the edge does not exist, it returns `undefined`.\n */\n getEndsOfEdge(edge: EO): [VO, VO] | undefined {\n if (!this.hasEdge(edge.src, edge.dest)) {\n return undefined;\n }\n const v1 = this._getVertex(edge.src);\n const v2 = this._getVertex(edge.dest);\n if (v1 && v2) {\n return [v1, v2];\n } else {\n return undefined;\n }\n }\n\n /**\n * The isEmpty function checks if the graph is empty.\n *\n * @return A boolean value\n */\n isEmpty(): boolean {\n return this.vertexMap.size === 0 && this.inEdgeMap.size === 0 && this.outEdgeMap.size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the vertex map, in-edge map, and out-edge map.\n */\n clear() {\n this._vertexMap = new Map<VertexKey, VO>();\n this._inEdgeMap = new Map<VO, EO[]>();\n this._outEdgeMap = new Map<VO, EO[]>();\n }\n\n /**\n * The clone function creates a new DirectedGraph object with the same vertices and edges as the original.\n *\n * @return A new instance of the directedgraph class\n */\n clone(): DirectedGraph<V, E, VO, EO> {\n const cloned = new DirectedGraph<V, E, VO, EO>();\n cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);\n cloned.inEdgeMap = new Map<VO, EO[]>(this.inEdgeMap);\n cloned.outEdgeMap = new Map<VO, EO[]>(this.outEdgeMap);\n return cloned;\n }\n\n /**\n * Time Complexity: O(V + E)\n * Space Complexity: O(V)\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.\n *\n * The function `tarjan` implements the Tarjan's algorithm to find strongly connected components in a\n * graph.\n * @returns The function `tarjan()` returns an object with three properties: `dfnMap`, `lowMap`, and\n * `SCCs`.\n */\n tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; SCCs: Map<number, VO[]> } {\n const dfnMap = new Map<VO, number>();\n const lowMap = new Map<VO, number>();\n const SCCs = new Map<number, VO[]>();\n\n let time = 0;\n\n const stack: VO[] = [];\n const inStack: Set<VO> = new Set();\n\n const dfs = (vertex: VO) => {\n dfnMap.set(vertex, time);\n lowMap.set(vertex, time);\n time++;\n\n stack.push(vertex);\n inStack.add(vertex);\n\n const neighbors = this.getNeighbors(vertex);\n for (const neighbor of neighbors) {\n if (!dfnMap.has(neighbor)) {\n dfs(neighbor);\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, lowMap.get(neighbor)!));\n } else if (inStack.has(neighbor)) {\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));\n }\n }\n\n if (dfnMap.get(vertex) === lowMap.get(vertex)) {\n const SCC: VO[] = [];\n let poppedVertex: VO | undefined;\n\n do {\n poppedVertex = stack.pop();\n inStack.delete(poppedVertex!);\n SCC.push(poppedVertex!);\n } while (poppedVertex !== vertex);\n\n SCCs.set(SCCs.size, SCC);\n }\n };\n\n for (const vertex of this.vertexMap.values()) {\n if (!dfnMap.has(vertex)) {\n dfs(vertex);\n }\n }\n\n return { dfnMap, lowMap, SCCs };\n }\n\n /**\n * Time Complexity: O(V + E) - Depends on the implementation (Tarjan's algorithm).\n * Space Complexity: O(V) - Depends on the implementation (Tarjan's algorithm).\n *\n * The function returns a map that associates each vertex object with its corresponding depth-first\n * number.\n * @returns A Map object with keys of type VO and values of type number.\n */\n getDFNMap(): Map<VO, number> {\n return this.tarjan().dfnMap;\n }\n\n /**\n * The function returns a Map object that contains the low values of each vertex in a Tarjan\n * algorithm.\n * @returns The method `getLowMap()` is returning a `Map` object with keys of type `VO` and values of\n * type `number`.\n */\n getLowMap(): Map<VO, number> {\n return this.tarjan().lowMap;\n }\n\n /**\n * The function \"getSCCs\" returns a map of strongly connected components (SCCs) using the Tarjan\n * algorithm.\n * @returns a map where the keys are numbers and the values are arrays of VO objects.\n */\n getSCCs(): Map<number, VO[]> {\n return this.tarjan().SCCs;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_addEdge` adds an edge to a graph if the source and destination vertexMap exist.\n * @param {EO} edge - The parameter `edge` is of type `EO`, which represents an edge in a graph. It is the edge that\n * needs to be added to the graph.\n * @returns a boolean value. It returns true if the edge was successfully added to the graph, and false if either the\n * source or destination vertex does not exist in the graph.\n */\n protected _addEdge(edge: EO): boolean {\n if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {\n return false;\n }\n\n const srcVertex = this._getVertex(edge.src);\n const destVertex = this._getVertex(edge.dest);\n\n // TODO after no-non-undefined-assertion not ensure the logic\n if (srcVertex && destVertex) {\n const srcOutEdges = this._outEdgeMap.get(srcVertex);\n if (srcOutEdges) {\n srcOutEdges.push(edge);\n } else {\n this._outEdgeMap.set(srcVertex, [edge]);\n }\n\n const destInEdges = this._inEdgeMap.get(destVertex);\n if (destInEdges) {\n destInEdges.push(edge);\n } else {\n this._inEdgeMap.set(destVertex, [edge]);\n }\n return true;\n } else {\n return false;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { VertexKey } from '../../types';\nimport { IGraph } from '../../interfaces';\nimport { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';\nimport { arrayRemove } from '../../utils';\n\nexport class UndirectedVertex<V = any> extends AbstractVertex<V> {\n /**\n * The constructor function initializes a vertex with an optional value.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex. It is\n * used to uniquely identify the vertex within a graph or network.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It is used to initialize the value of the\n * vertex. If no value is provided, the vertex will be initialized with a default value.\n */\n constructor(key: VertexKey, value?: V) {\n super(key, value);\n }\n}\n\nexport class UndirectedEdge<E = number> extends AbstractEdge<E> {\n endpoints: [VertexKey, VertexKey];\n\n /**\n * The constructor function creates an instance of a class with two vertex IDs, an optional weight, and an optional\n * value.\n * @param {VertexKey} v1 - The first vertex ID of the edge.\n * @param {VertexKey} v2 - The parameter `v2` is a `VertexKey`, which represents the identifier of the second vertex in a\n * graph edge.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.\n * @param {E} [value] - The \"value\" parameter is an optional parameter of type E. It is used to store a value associated\n * with the edge.\n */\n constructor(v1: VertexKey, v2: VertexKey, weight?: number, value?: E) {\n super(weight, value);\n this.endpoints = [v1, v2];\n }\n}\n\nexport class UndirectedGraph<\n V = any,\n E = any,\n VO extends UndirectedVertex<V> = UndirectedVertex<V>,\n EO extends UndirectedEdge<E> = UndirectedEdge<E>\n >\n extends AbstractGraph<V, E, VO, EO>\n implements IGraph<V, E, VO, EO>\n{\n /**\n * The constructor initializes a new Map object to store edgeMap.\n */\n constructor() {\n super();\n this._edgeMap = new Map<VO, EO[]>();\n }\n\n protected _edgeMap: Map<VO, EO[]>;\n\n get edgeMap(): Map<VO, EO[]> {\n return this._edgeMap;\n }\n\n set edgeMap(v: Map<VO, EO[]>) {\n this._edgeMap = v;\n }\n\n /**\n * The function creates a new vertex with an optional value and returns it.\n * @param {VertexKey} key - The `key` parameter is the unique identifier for the vertex. It is used to distinguish one\n * vertex from another in the graph.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the vertex. If a value is provided,\n * it will be used as the value of the vertex. If no value is provided, the `key` parameter will be used as the value of\n * the vertex.\n * @returns The method is returning a new instance of the `UndirectedVertex` class, casted as type `VO`.\n */\n override createVertex(key: VertexKey, value?: VO['value']): VO {\n return new UndirectedVertex(key, value ?? key) as VO;\n }\n\n /**\n * The function creates an undirected edge between two vertexMap with an optional weight and value.\n * @param {VertexKey} v1 - The parameter `v1` represents the first vertex of the edge.\n * @param {VertexKey} v2 - The parameter `v2` represents the second vertex of the edge.\n * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the edge. If\n * no weight is provided, it defaults to 1.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the edge. It can be of any type and\n * is used to store additional information or data associated with the edge.\n * @returns a new instance of the `UndirectedEdge` class, which is casted as type `EO`.\n */\n override createEdge(v1: VertexKey, v2: VertexKey, weight?: number, value?: EO['value']): EO {\n return new UndirectedEdge(v1, v2, weight ?? 1, value) as EO;\n }\n\n /**\n * Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.\n * Space Complexity: O(1)\n *\n * The function `getEdge` returns the first edge that connects two endpoints, or undefined if no such edge exists.\n * @param {VO | VertexKey | undefined} v1 - The parameter `v1` represents a vertex or vertex ID. It can be of type `VO` (vertex\n * object), `undefined`, or `VertexKey` (a string or number representing the ID of a vertex).\n * @param {VO | VertexKey | undefined} v2 - The parameter `v2` represents a vertex or vertex ID. It can be of type `VO` (vertex\n * object), `undefined`, or `VertexKey` (vertex ID).\n * @returns an edge (EO) or undefined.\n */\n getEdge(v1: VO | VertexKey | undefined, v2: VO | VertexKey | undefined): EO | undefined {\n let edgeMap: EO[] | undefined = [];\n\n if (v1 !== undefined && v2 !== undefined) {\n const vertex1: VO | undefined = this._getVertex(v1);\n const vertex2: VO | undefined = this._getVertex(v2);\n\n if (vertex1 && vertex2) {\n edgeMap = this._edgeMap.get(vertex1)?.filter(e => e.endpoints.includes(vertex2.key));\n }\n }\n\n return edgeMap ? edgeMap[0] || undefined : undefined;\n }\n\n /**\n * Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.\n * Space Complexity: O(1)\n *\n * The function removes an edge between two vertexMap in a graph and returns the removed edge.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).\n * @param {VO | VertexKey} v2 - VO | VertexKey - This parameter can be either a vertex object (VO) or a vertex ID\n * (VertexKey). It represents the second vertex of the edge that needs to be removed.\n * @returns the removed edge (EO) if it exists, or undefined if either of the endpoints (VO) does not exist.\n */\n deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | undefined {\n const vertex1: VO | undefined = this._getVertex(v1);\n const vertex2: VO | undefined = this._getVertex(v2);\n\n if (!vertex1 || !vertex2) {\n return undefined;\n }\n\n const v1Edges = this._edgeMap.get(vertex1);\n let removed: EO | undefined = undefined;\n if (v1Edges) {\n removed = arrayRemove<EO>(v1Edges, (e: EO) => e.endpoints.includes(vertex2.key))[0] || undefined;\n }\n const v2Edges = this._edgeMap.get(vertex2);\n if (v2Edges) {\n arrayRemove<EO>(v2Edges, (e: EO) => e.endpoints.includes(vertex1.key));\n }\n return removed;\n }\n\n /**\n * Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.\n * Space Complexity: O(1)\n *\n * The function `deleteEdge` deletes an edge between two endpoints in a graph.\n * @param {EO | VertexKey} edgeOrOneSideVertexKey - The parameter `edgeOrOneSideVertexKey` can be\n * either an edge object or a vertex key.\n * @param {VertexKey} [otherSideVertexKey] - The parameter `otherSideVertexKey` is an optional\n * parameter that represents the key of the vertex on the other side of the edge. It is used when the\n * `edgeOrOneSideVertexKey` parameter is a vertex key, and it specifies the key of the vertex on the\n * other side of the\n * @returns The `deleteEdge` function returns either the deleted edge object (EO) or `undefined`.\n */\n deleteEdge(edgeOrOneSideVertexKey: EO | VertexKey, otherSideVertexKey?: VertexKey): EO | undefined {\n let oneSide: VO | undefined, otherSide: VO | undefined;\n if (this.isVertexKey(edgeOrOneSideVertexKey)) {\n if (this.isVertexKey(otherSideVertexKey)) {\n oneSide = this._getVertex(edgeOrOneSideVertexKey);\n otherSide = this._getVertex(otherSideVertexKey);\n } else {\n return;\n }\n } else {\n oneSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[0]);\n otherSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[1]);\n }\n\n if (oneSide && otherSide) {\n return this.deleteEdgeBetween(oneSide, otherSide);\n } else {\n return;\n }\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method is returning a boolean value.\n */\n deleteVertex(vertexOrKey: VO | VertexKey): boolean {\n let vertexKey: VertexKey;\n let vertex: VO | undefined;\n if (this.isVertexKey(vertexOrKey)) {\n vertex = this.getVertex(vertexOrKey);\n vertexKey = vertexOrKey;\n } else {\n vertex = vertexOrKey;\n vertexKey = this._getVertexKey(vertexOrKey);\n }\n\n const neighbors = this.getNeighbors(vertexOrKey);\n\n if (vertex) {\n neighbors.forEach(neighbor => {\n const neighborEdges = this._edgeMap.get(neighbor);\n if (neighborEdges) {\n const restEdges = neighborEdges.filter(edge => {\n return !edge.endpoints.includes(vertexKey);\n });\n this._edgeMap.set(neighbor, restEdges);\n }\n });\n this._edgeMap.delete(vertex);\n }\n\n return this._vertexMap.delete(vertexKey);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `degreeOf` returns the degree of a vertex in a graph, which is the number of edgeMap connected to that\n * vertex.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The function `degreeOf` returns the degree of a vertex in a graph. The degree of a vertex is the number of\n * edgeMap connected to that vertex.\n */\n degreeOf(vertexOrKey: VertexKey | VO): number {\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n return this._edgeMap.get(vertex)?.length || 0;\n } else {\n return 0;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function returns the edgeMap of a given vertex or vertex ID.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`. A `VertexKey` is a\n * unique identifier for a vertex in a graph, while `VO` represents the type of the vertex.\n * @returns an array of edgeMap.\n */\n edgesOf(vertexOrKey: VertexKey | VO): EO[] {\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n return this._edgeMap.get(vertex) || [];\n } else {\n return [];\n }\n }\n\n /**\n * Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.\n * Space Complexity: O(|E|)\n *\n * The function \"edgeSet\" returns an array of unique edgeMap from a set of edgeMap.\n * @returns The method `edgeSet()` returns an array of type `EO[]`.\n */\n edgeSet(): EO[] {\n const edgeSet: Set<EO> = new Set();\n this._edgeMap.forEach(edgeMap => {\n edgeMap.forEach(edge => {\n edgeSet.add(edge);\n });\n });\n return [...edgeSet];\n }\n\n /**\n * Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.\n * Space Complexity: O(|E|)\n *\n * The function \"getNeighbors\" returns an array of neighboring endpoints for a given vertex or vertex ID.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns an array of vertexMap (VO[]).\n */\n getNeighbors(vertexOrKey: VO | VertexKey): VO[] {\n const neighbors: VO[] = [];\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n const neighborEdges = this.edgesOf(vertex);\n for (const edge of neighborEdges) {\n const neighbor = this._getVertex(edge.endpoints.filter(e => e !== vertex.key)[0]);\n if (neighbor) {\n neighbors.push(neighbor);\n }\n }\n }\n return neighbors;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEndsOfEdge\" returns the endpoints at the ends of an edge if the edge exists in the graph, otherwise\n * it returns undefined.\n * @param {EO} edge - The parameter \"edge\" is of type EO, which represents an edge in a graph.\n * @returns The function `getEndsOfEdge` returns an array containing two endpoints `[VO, VO]` if the edge exists in the\n * graph. If the edge does not exist, it returns `undefined`.\n */\n getEndsOfEdge(edge: EO): [VO, VO] | undefined {\n if (!this.hasEdge(edge.endpoints[0], edge.endpoints[1])) {\n return undefined;\n }\n const v1 = this._getVertex(edge.endpoints[0]);\n const v2 = this._getVertex(edge.endpoints[1]);\n if (v1 && v2) {\n return [v1, v2];\n } else {\n return undefined;\n }\n }\n\n /**\n * The isEmpty function checks if the graph is empty.\n * @return True if the graph is empty and false otherwise\n */\n isEmpty(): boolean {\n return this.vertexMap.size === 0 && this.edgeMap.size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the vertex and edge maps to empty maps.\n */\n clear() {\n this._vertexMap = new Map<VertexKey, VO>();\n this._edgeMap = new Map<VO, EO[]>();\n }\n\n /**\n * The clone function creates a new UndirectedGraph object and copies the\n * vertexMap and edgeMap from this graph to the new one. This is done by\n * assigning each of these properties to their respective counterparts in the\n * cloned graph. The clone function returns a reference to this newly created,\n * cloned UndirectedGraph object.\n *\n * @return A new instance of the undirectedgraph class\n */\n clone(): UndirectedGraph<V, E, VO, EO> {\n const cloned = new UndirectedGraph<V, E, VO, EO>();\n cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);\n cloned.edgeMap = new Map<VO, EO[]>(this.edgeMap);\n return cloned;\n }\n\n /**\n * Time Complexity: O(V + E)\n * Space Complexity: O(V)\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * 1. Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time\n *\n * The function `tarjan` implements the Tarjan's algorithm to find bridges and cut vertices in a\n * graph.\n * @returns The function `tarjan()` returns an object with the following properties:\n */\n tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; bridges: EO[]; cutVertices: VO[] } {\n const dfnMap = new Map<VO, number>();\n const lowMap = new Map<VO, number>();\n const bridges: EO[] = [];\n const cutVertices: VO[] = [];\n\n let time = 0;\n\n const dfs = (vertex: VO, parent: VO | undefined) => {\n dfnMap.set(vertex, time);\n lowMap.set(vertex, time);\n time++;\n\n const neighbors = this.getNeighbors(vertex);\n let childCount = 0;\n\n for (const neighbor of neighbors) {\n if (!dfnMap.has(neighbor)) {\n childCount++;\n dfs(neighbor, vertex);\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, lowMap.get(neighbor)!));\n\n if (lowMap.get(neighbor)! > dfnMap.get(vertex)!) {\n // Found a bridge\n const edge = this.getEdge(vertex, neighbor);\n if (edge) {\n bridges.push(edge);\n }\n }\n\n if (parent !== undefined && lowMap.get(neighbor)! >= dfnMap.get(vertex)!) {\n // Found an articulation point\n cutVertices.push(vertex);\n }\n } else if (neighbor !== parent) {\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));\n }\n }\n\n if (parent === undefined && childCount > 1) {\n // Special case for root in DFS tree\n cutVertices.push(vertex);\n }\n };\n\n for (const vertex of this.vertexMap.values()) {\n if (!dfnMap.has(vertex)) {\n dfs(vertex, undefined);\n }\n }\n\n return {\n dfnMap,\n lowMap,\n bridges,\n cutVertices\n };\n }\n\n /**\n * The function \"getBridges\" returns an array of bridges in a graph using the Tarjan's algorithm.\n * @returns The function `getBridges()` is returning the bridges found using the Tarjan's algorithm.\n */\n getBridges() {\n return this.tarjan().bridges;\n }\n\n /**\n * The function \"getCutVertices\" returns an array of cut vertices using the Tarjan's algorithm.\n * @returns the cut vertices found using the Tarjan's algorithm.\n */\n getCutVertices() {\n return this.tarjan().cutVertices;\n }\n\n /**\n * The function returns the dfnMap property of the result of the tarjan() function.\n * @returns the `dfnMap` property of the result of calling the `tarjan()` function.\n */\n getDFNMap() {\n return this.tarjan().dfnMap;\n }\n\n /**\n * The function returns the lowMap property of the result of the tarjan() function.\n * @returns the lowMap property of the result of calling the tarjan() function.\n */\n getLowMap() {\n return this.tarjan().lowMap;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function adds an edge to the graph by updating the adjacency list with the vertexMap of the edge.\n * @param {EO} edge - The parameter \"edge\" is of type EO, which represents an edge in a graph.\n * @returns a boolean value.\n */\n protected _addEdge(edge: EO): boolean {\n for (const end of edge.endpoints) {\n const endVertex = this._getVertex(end);\n if (endVertex === undefined) return false;\n if (endVertex) {\n const edgeMap = this._edgeMap.get(endVertex);\n if (edgeMap) {\n edgeMap.push(edge);\n } else {\n this._edgeMap.set(endVertex, [edge]);\n }\n }\n }\n return true;\n }\n}\n","import type { MapGraphCoordinate, VertexKey } from '../../types';\nimport { DirectedEdge, DirectedGraph, DirectedVertex } from './directed-graph';\n\nexport class MapVertex<V = any> extends DirectedVertex<V> {\n lat: number;\n long: number;\n\n /**\n * The constructor function initializes an object with an key, latitude, longitude, and an optional value.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex.\n * @param {number} lat - The \"lat\" parameter represents the latitude of a vertex. Latitude is a geographic coordinate\n * that specifies the north-south position of a point on the Earth's surface. It is measured in degrees, with positive\n * values representing points north of the equator and negative values representing points south of the equator.\n * @param {number} long - The \"long\" parameter represents the longitude of a location. Longitude is a geographic\n * coordinate that specifies the east-west position of a point on the Earth's surface. It is measured in degrees, with\n * values ranging from -180 to 180.\n * @param {V} [value] - The \"value\" parameter is an optional value of type V. It is not required to be provided when\n * creating an instance of the class.\n */\n constructor(key: VertexKey, value: V, lat: number, long: number) {\n super(key, value);\n this.lat = lat;\n this.long = long;\n }\n}\n\nexport class MapEdge<E = any> extends DirectedEdge<E> {\n /**\n * The constructor function initializes a new instance of a class with the given source, destination, weight, and\n * value.\n * @param {VertexKey} src - The `src` parameter is the source vertex ID. It represents the starting point of an edge in\n * a graph.\n * @param {VertexKey} dest - The `dest` parameter is the identifier of the destination vertex for an edge.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.\n * @param {E} [value] - The \"value\" parameter is an optional parameter of type E. It is used to store additional\n * information or data associated with the edge.\n */\n constructor(src: VertexKey, dest: VertexKey, weight?: number, value?: E) {\n super(src, dest, weight, value);\n }\n}\n\nexport class MapGraph<\n V = any,\n E = any,\n VO extends MapVertex<V> = MapVertex<V>,\n EO extends MapEdge<E> = MapEdge<E>\n> extends DirectedGraph<V, E, VO, EO> {\n /**\n * The constructor function initializes the originCoord and bottomRight properties of a MapGraphCoordinate object.\n * @param {MapGraphCoordinate} originCoord - The `originCoord` parameter is a `MapGraphCoordinate` object that represents the\n * starting point or reference point of the map graph. It defines the coordinates of the top-left corner of the map\n * graph.\n * @param {MapGraphCoordinate} [bottomRight] - The `bottomRight` parameter is an optional parameter of type\n * `MapGraphCoordinate`. It represents the bottom right coordinate of a map graph. If this parameter is not provided,\n * it will default to `undefined`.\n */\n constructor(originCoord: MapGraphCoordinate, bottomRight?: MapGraphCoordinate) {\n super();\n this._originCoord = originCoord;\n this._bottomRight = bottomRight;\n }\n\n protected _originCoord: MapGraphCoordinate = [0, 0];\n\n get originCoord(): MapGraphCoordinate {\n return this._originCoord;\n }\n\n protected _bottomRight: MapGraphCoordinate | undefined;\n\n get bottomRight(): MapGraphCoordinate | undefined {\n return this._bottomRight;\n }\n\n /**\n * The function creates a new vertex with the given key, value, latitude, and longitude.\n * @param {VertexKey} key - The key parameter is the unique identifier for the vertex. It is of type VertexKey, which could\n * be a string or a number depending on how you define it in your code.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the `value` property of the vertex. It\n * is of type `V`, which means it should be of the same type as the `value` property of the vertex class `VO`.\n * @param {number} lat - The `lat` parameter represents the latitude of the vertex. It is a number that specifies the\n * position of the vertex on the Earth's surface in the north-south direction.\n * @param {number} long - The `long` parameter represents the longitude coordinate of the vertex.\n * @returns The method is returning a new instance of the `MapVertex` class, casted as type `VO`.\n */\n override createVertex(\n key: VertexKey,\n value?: V,\n lat: number = this.originCoord[0],\n long: number = this.originCoord[1]\n ): VO {\n return new MapVertex(key, value, lat, long) as VO;\n }\n\n /**\n * The function creates a new instance of a MapEdge with the given source, destination, weight, and value.\n * @param {VertexKey} src - The source vertex ID of the edge. It represents the starting point of the edge.\n * @param {VertexKey} dest - The `dest` parameter is the identifier of the destination vertex for the edge being\n * created.\n * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the edge. It\n * is used to assign a numerical value to the edge, which can be used in algorithms such as shortest path algorithms.\n * If the weight is not provided, it can be set to a default value or left undefined.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the edge. It can be of any type,\n * depending on the specific implementation of the `MapEdge` class.\n * @returns a new instance of the `MapEdge` class, cast as type `EO`.\n */\n override createEdge(src: VertexKey, dest: VertexKey, weight?: number, value?: E): EO {\n return new MapEdge(src, dest, weight, value) as EO;\n }\n\n /**\n * The override function is used to override the default behavior of a function.\n * In this case, we are overriding the clone() function from Graph&lt;V, E&gt;.\n * The clone() function returns a new graph that is an exact copy of the original graph.\n *\n * @return A mapgraph&lt;v, e, vo, eo&gt;\n */\n override clone(): MapGraph<V, E, VO, EO> {\n const cloned = new MapGraph<V, E, VO, EO>(this.originCoord, this.bottomRight);\n cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);\n cloned.inEdgeMap = new Map<VO, EO[]>(this.inEdgeMap);\n cloned.outEdgeMap = new Map<VO, EO[]>(this.outEdgeMap);\n return cloned;\n }\n}\n","export enum DFSOperation {\n VISIT = 0,\n PROCESS = 1\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type {\n BinaryTreeDeleteResult,\n BinaryTreeNested,\n BinaryTreeNodeNested,\n BinaryTreeOptions,\n BinaryTreePrintOptions,\n BTNCallback,\n BTNEntry,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n DFSOrderPattern,\n DFSStackItem,\n EntryCallback,\n FamilyPosition,\n IterationType,\n NodeDisplayLayout,\n OptBTNOrNull\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { isComparable, trampoline } from '../../utils';\nimport { Queue } from '../queue';\nimport { IterableEntryBase } from '../base';\nimport { DFSOperation } from '../../constants';\n\n/**\n * Represents a node in a binary tree.\n * @template V - The type of data stored in the node.\n * @template NODE - The type of the family relationship in the binary tree.\n */\nexport class BinaryTreeNode<\n K = any,\n V = any,\n NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>\n> {\n key: K;\n\n value?: V;\n\n parent?: NODE;\n\n constructor(key: K, value?: V) {\n this.key = key;\n this.value = value;\n }\n\n protected _left?: OptBTNOrNull<NODE>;\n\n get left(): OptBTNOrNull<NODE> {\n return this._left;\n }\n\n set left(v: OptBTNOrNull<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._left = v;\n }\n\n protected _right?: OptBTNOrNull<NODE>;\n\n get right(): OptBTNOrNull<NODE> {\n return this._right;\n }\n\n set right(v: OptBTNOrNull<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._right = v;\n }\n\n get familyPosition(): FamilyPosition {\n const that = this as unknown as NODE;\n if (!this.parent) {\n return this.left || this.right ? 'ROOT' : 'ISOLATED';\n }\n\n if (this.parent.left === that) {\n return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';\n } else if (this.parent.right === that) {\n return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';\n }\n\n return 'MAL_NODE';\n }\n}\n\n/**\n * 1. Two Children Maximum: Each node has at most two children.\n * 2. Left and Right Children: Nodes have distinct left and right children.\n * 3. Depth and Height: Depth is the number of edges from the root to a node; height is the maximum depth in the tree.\n * 4. Subtrees: Each child of a node forms the root of a subtree.\n * 5. Leaf Nodes: Nodes without children are leaves.\n */\nexport class BinaryTree<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,\n TREE extends BinaryTree<K, V, R, NODE, TREE> = BinaryTree<K, V, R, NODE, BinaryTreeNested<K, V, R, NODE>>\n >\n extends IterableEntryBase<K, V | undefined>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n iterationType: IterationType = 'ITERATIVE';\n\n /**\n * The constructor initializes a binary tree with optional options and adds keys, nodes, entries, or\n * raw data if provided.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter in the constructor\n * is an iterable that can contain elements of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. It is\n * initialized with an empty array `[]` by default.\n * @param [options] - The `options` parameter in the constructor is an object that can contain the\n * following properties:\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE> | R> = [],\n options?: BinaryTreeOptions<K, V, R>\n ) {\n super();\n if (options) {\n const { iterationType, toEntryFn } = options;\n if (iterationType) this.iterationType = iterationType;\n if (typeof toEntryFn === 'function') this._toEntryFn = toEntryFn;\n else if (toEntryFn) throw TypeError('toEntryFn must be a function type');\n }\n\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected _root?: OptBTNOrNull<NODE>;\n\n get root(): OptBTNOrNull<NODE> {\n return this._root;\n }\n\n protected _size: number = 0;\n\n get size(): number {\n return this._size;\n }\n\n protected _NIL: NODE = new BinaryTreeNode<K, V>(NaN as K) as unknown as NODE;\n\n get NIL(): NODE {\n return this._NIL;\n }\n\n protected _toEntryFn?: (rawElement: R) => BTNEntry<K, V>;\n\n get toEntryFn() {\n return this._toEntryFn;\n }\n\n /**\n * The function creates a new binary tree node with a specified key and optional value.\n * @param {K} key - The `key` parameter is the key of the node being created in the binary tree.\n * @param {V} [value] - The `value` parameter in the `createNode` function is optional, meaning it is\n * not required to be provided when calling the function. If a `value` is provided, it should be of\n * type `V`, which is the type of the value associated with the node.\n * @returns A new BinaryTreeNode instance with the provided key and value is being returned, casted\n * as NODE.\n */\n createNode(key: K, value?: V): NODE {\n return new BinaryTreeNode<K, V, NODE>(key, value) as NODE;\n }\n\n /**\n * The function creates a binary tree with the specified options.\n * @param [options] - The `options` parameter in the `createTree` function is an optional parameter\n * that allows you to provide partial configuration options for creating a binary tree. It is of type\n * `Partial<BinaryTreeOptions<K, V, R>>`, which means you can pass in an object containing a subset\n * of properties\n * @returns A new instance of a binary tree with the specified options is being returned.\n */\n createTree(options?: BinaryTreeOptions<K, V, R>): TREE {\n return new BinaryTree<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function `keyValueOrEntryOrRawElementToNode` converts various input types into a node object\n * or returns null.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyValueOrEntryOrRawElementToNode` function takes in a parameter `keyOrNodeOrEntryOrRaw`, which\n * can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. This parameter represents either a key, a\n * node, an entry\n * @param {V} [value] - The `value` parameter in the `keyValueOrEntryOrRawElementToNode` function is\n * an optional parameter of type `V`. It represents the value associated with the key in the node\n * being created. If a `value` is provided, it will be used when creating the node. If\n * @returns The `keyValueOrEntryOrRawElementToNode` function returns an optional node\n * (`OptBTNOrNull<NODE>`) based on the input parameters provided. The function checks the type of the\n * input parameter (`keyOrNodeOrEntryOrRaw`) and processes it accordingly to return a node or null\n * value.\n */\n keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V\n ): OptBTNOrNull<NODE> {\n if (keyOrNodeOrEntryOrRaw === undefined) return;\n if (keyOrNodeOrEntryOrRaw === null) return null;\n\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const [key, entryValue] = keyOrNodeOrEntryOrRaw;\n if (key === undefined) return;\n else if (key === null) return null;\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue);\n }\n\n if (this._toEntryFn) {\n const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue);\n else return;\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value);\n\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `ensureNode` in TypeScript checks if a given input is a node, entry, key, or raw\n * value and returns the corresponding node or null.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `ensureNode` function can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. It\n * is used to determine whether the input is a key, node, entry, or raw data. The\n * @param {IterationType} iterationType - The `iterationType` parameter in the `ensureNode` function\n * is used to specify the type of iteration to be performed. It has a default value of\n * `this.iterationType` if not explicitly provided.\n * @returns The `ensureNode` function returns either a node, `null`, or `undefined` based on the\n * conditions specified in the code snippet.\n */\n ensureNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType: IterationType = this.iterationType\n ): OptBTNOrNull<NODE> {\n if (keyOrNodeOrEntryOrRaw === null) return null;\n if (keyOrNodeOrEntryOrRaw === undefined) return;\n if (keyOrNodeOrEntryOrRaw === this._NIL) return;\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const key = keyOrNodeOrEntryOrRaw[0];\n if (key === null) return null;\n if (key === undefined) return;\n return this.getNodeByKey(key, iterationType);\n }\n\n if (this._toEntryFn) {\n const [key] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.getNodeByKey(key);\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.getNodeByKey(keyOrNodeOrEntryOrRaw, iterationType);\n return;\n }\n\n /**\n * The function isNode checks if the input is an instance of BinaryTreeNode.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be either a key, a node, an entry, or raw data. The function is\n * checking if the input is an instance of a `BinaryTreeNode` and returning a boolean value\n * accordingly.\n * @returns The function `isNode` is checking if the input `keyOrNodeOrEntryOrRaw` is an instance of\n * `BinaryTreeNode`. If it is, the function returns `true`, indicating that the input is a node. If\n * it is not an instance of `BinaryTreeNode`, the function returns `false`, indicating that the input\n * is not a node.\n */\n isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof BinaryTreeNode;\n }\n\n /**\n * The function `isRealNode` checks if a given input is a valid node in a binary tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `isRealNode` function can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`.\n * The function checks if the input parameter is a `NODE` type by verifying if it is not equal\n * @returns The function `isRealNode` is checking if the input `keyOrNodeOrEntryOrRaw` is a valid\n * node by comparing it to `this._NIL`, `null`, and `undefined`. If the input is not one of these\n * values, it then calls the `isNode` method to further determine if the input is a node. The\n * function will return a boolean value indicating whether the\n */\n isRealNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n if (keyOrNodeOrEntryOrRaw === this._NIL || keyOrNodeOrEntryOrRaw === null || keyOrNodeOrEntryOrRaw === undefined)\n return false;\n return this.isNode(keyOrNodeOrEntryOrRaw);\n }\n\n /**\n * The function checks if a given input is a valid node or null.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` in the `isRealNodeOrNull` function can be of type `BTNKeyOrNodeOrEntry<K,\n * V, NODE>` or `R`. It is a union type that can either be a key, a node, an entry, or\n * @returns The function `isRealNodeOrNull` is returning a boolean value. It checks if the input\n * `keyOrNodeOrEntryOrRaw` is either `null` or a real node, and returns `true` if it is a node or\n * `null`, and `false` otherwise.\n */\n isRealNodeOrNull(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE | null {\n return keyOrNodeOrEntryOrRaw === null || this.isRealNode(keyOrNodeOrEntryOrRaw);\n }\n\n /**\n * The function isNIL checks if a given key, node, entry, or raw value is equal to the _NIL value.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - BTNKeyOrNodeOrEntry<K, V,\n * NODE> | R\n * @returns The function is checking if the `keyOrNodeOrEntryOrRaw` parameter is equal to the `_NIL`\n * property of the current object and returning a boolean value based on that comparison.\n */\n isNIL(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): boolean {\n return keyOrNodeOrEntryOrRaw === this._NIL;\n }\n\n /**\n * The function determines whether a given key, node, entry, or raw data is a leaf node in a binary\n * tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. It represents a\n * key, node, entry, or raw data in a binary tree structure. The function `isLeaf` checks whether the\n * provided\n * @returns The function `isLeaf` returns a boolean value indicating whether the input\n * `keyOrNodeOrEntryOrRaw` is a leaf node in a binary tree.\n */\n isLeaf(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): boolean {\n keyOrNodeOrEntryOrRaw = this.ensureNode(keyOrNodeOrEntryOrRaw);\n if (keyOrNodeOrEntryOrRaw === undefined) return false;\n if (keyOrNodeOrEntryOrRaw === null) return true;\n return !this.isRealNode(keyOrNodeOrEntryOrRaw.left) && !this.isRealNode(keyOrNodeOrEntryOrRaw.right);\n }\n\n /**\n * The function `isEntry` checks if the input is a BTNEntry object by verifying if it is an array\n * with a length of 2.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `isEntry` function can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or type `R`.\n * The function checks if the provided `keyOrNodeOrEntryOrRaw` is of type `BTN\n * @returns The `isEntry` function is checking if the `keyOrNodeOrEntryOrRaw` parameter is an array\n * with a length of 2. If it is, then it returns `true`, indicating that the parameter is of type\n * `BTNEntry<K, V>`. If the condition is not met, it returns `false`.\n */\n isEntry(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is BTNEntry<K, V> {\n return Array.isArray(keyOrNodeOrEntryOrRaw) && keyOrNodeOrEntryOrRaw.length === 2;\n }\n\n /**\n * Time Complexity O(1)\n * Space Complexity O(1)\n *\n * The function `isKey` checks if a given key is comparable.\n * @param {any} key - The `key` parameter is of type `any`, which means it can be any data type in\n * TypeScript.\n * @returns The function `isKey` is checking if the `key` parameter is `null` or if it is comparable.\n * If the `key` is `null`, the function returns `true`. Otherwise, it returns the result of the\n * `isComparable` function, which is not provided in the code snippet.\n */\n isKey(key: any): key is K {\n if (key === null) return true;\n return isComparable(key);\n }\n\n /**\n * Time Complexity O(n)\n * Space Complexity O(1)\n *\n * The `add` function in TypeScript adds a new node to a binary tree while handling duplicate keys\n * and finding the correct insertion position.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `add` method you provided\n * seems to be for adding a new node to a binary tree structure. The `keyOrNodeOrEntryOrRaw`\n * parameter in the method can accept different types of values:\n * @param {V} [value] - The `value` parameter in the `add` method represents the value associated\n * with the key that you want to add to the binary tree. When adding a key-value pair to the binary\n * tree, you provide the key and its corresponding value. The `add` method then creates a new node\n * with this\n * @returns The `add` method returns a boolean value. It returns `true` if the insertion of the new\n * node was successful, and `false` if the insertion position could not be found or if a duplicate\n * key was found and the node was replaced instead of inserted.\n */\n add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);\n if (newNode === undefined) return false;\n\n // If the tree is empty, directly set the new node as the root node\n if (!this._root) {\n this._setRoot(newNode);\n this._size = 1;\n return true;\n }\n\n const queue = new Queue<NODE>([this._root]);\n let potentialParent: NODE | undefined; // Record the parent node of the potential insertion location\n\n while (queue.size > 0) {\n const cur = queue.shift();\n\n if (!cur) continue;\n\n // Check for duplicate keys when newNode is not null\n if (newNode !== null && cur.key === newNode.key) {\n this._replaceNode(cur, newNode);\n return true; // If duplicate keys are found, no insertion is performed\n }\n\n // Record the first possible insertion location found\n if (potentialParent === undefined && (cur.left === undefined || cur.right === undefined)) {\n potentialParent = cur;\n }\n\n // Continue traversing the left and right subtrees\n if (cur.left !== null) {\n if (cur.left) queue.push(cur.left);\n }\n if (cur.right !== null) {\n if (cur.right) queue.push(cur.right);\n }\n }\n\n // At the end of the traversal, if the insertion position is found, insert\n if (potentialParent) {\n if (potentialParent.left === undefined) {\n potentialParent.left = newNode;\n } else if (potentialParent.right === undefined) {\n potentialParent.right = newNode;\n }\n this._size++;\n return true;\n }\n\n return false; // If the insertion position cannot be found, return undefined\n }\n\n /**\n * Time Complexity: O(k * n)\n * Space Complexity: O(1)\n *\n * The `addMany` function takes in multiple keys or nodes or entries or raw values along with\n * optional values, and adds them to a data structure while returning an array indicating whether\n * each insertion was successful.\n * @param keysOrNodesOrEntriesOrRaws - `keysOrNodesOrEntriesOrRaws` is an iterable that can contain a\n * mix of keys, nodes, entries, or raw values. Each element in this iterable can be of type\n * `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`.\n * @param [values] - The `values` parameter in the `addMany` function is an optional parameter that\n * accepts an iterable of values. These values correspond to the keys or nodes being added in the\n * `keysOrNodesOrEntriesOrRaws` parameter. If provided, the function will iterate over the values and\n * assign them\n * @returns The `addMany` method returns an array of boolean values indicating whether each key,\n * node, entry, or raw value was successfully added to the data structure. Each boolean value\n * corresponds to the success of adding the corresponding key or value in the input iterable.\n */\n addMany(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE> | R>,\n values?: Iterable<V | undefined>\n ): boolean[] {\n // TODO not sure addMany not be run multi times\n const inserted: boolean[] = [];\n\n let valuesIterator: Iterator<V | undefined> | undefined;\n if (values) {\n valuesIterator = values[Symbol.iterator]();\n }\n\n for (const keyOrNodeOrEntryOrRaw of keysOrNodesOrEntriesOrRaws) {\n let value: V | undefined | null = undefined;\n\n if (valuesIterator) {\n const valueResult = valuesIterator.next();\n if (!valueResult.done) {\n value = valueResult.value;\n }\n }\n\n inserted.push(this.add(keyOrNodeOrEntryOrRaw, value));\n }\n\n return inserted;\n }\n\n /**\n * Time Complexity: O(k * n)\n * Space Complexity: O(1)\n *\n * The `refill` function clears the existing data structure and then adds new key-value pairs based\n * on the provided input.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter in the `refill`\n * method can accept an iterable containing a mix of `BTNKeyOrNodeOrEntry<K, V, NODE>` objects or `R`\n * objects.\n * @param [values] - The `values` parameter in the `refill` method is an optional parameter that\n * accepts an iterable of values of type `V` or `undefined`.\n */\n refill(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE> | R>,\n values?: Iterable<V | undefined>\n ): void {\n this.clear();\n this.addMany(keysOrNodesOrEntriesOrRaws, values);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `delete` in TypeScript implements the deletion of a node in a binary tree and returns\n * the deleted node along with information for tree balancing.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `delete` method you provided is used to delete a node from a binary tree based on the key,\n * node, entry, raw data, or a custom predicate. The method returns an array of\n * `BinaryTreeDeleteResult` objects containing information about the deleted node and whether\n * balancing is needed.\n * @returns The `delete` method returns an array of `BinaryTreeDeleteResult` objects. Each object in\n * the array contains information about the node that was deleted (`deleted`) and the node that may\n * need to be balanced (`needBalanced`).\n */\n delete(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>\n ): BinaryTreeDeleteResult<NODE>[] {\n const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];\n if (!this._root) return deletedResult;\n\n const curr = this.getNode(keyOrNodeOrEntryOrRawOrPredicate);\n if (!curr) return deletedResult;\n\n const parent: NODE | undefined = curr?.parent;\n let needBalanced: NODE | undefined;\n let orgCurrent: NODE | undefined = curr;\n\n if (!curr.left && !curr.right && !parent) {\n this._setRoot(undefined);\n } else if (curr.left) {\n const leftSubTreeRightMost = this.getRightMost(node => node, curr.left);\n if (leftSubTreeRightMost) {\n const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;\n orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);\n if (parentOfLeftSubTreeMax) {\n if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)\n parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;\n else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;\n needBalanced = parentOfLeftSubTreeMax;\n }\n }\n } else if (parent) {\n const { familyPosition: fp } = curr;\n if (fp === 'LEFT' || fp === 'ROOT_LEFT') {\n parent.left = curr.right;\n } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {\n parent.right = curr.right;\n }\n needBalanced = parent;\n } else {\n this._setRoot(curr.right);\n curr.right = undefined;\n }\n\n this._size = this._size - 1;\n\n deletedResult.push({ deleted: orgCurrent, needBalanced });\n return deletedResult;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(k + log n)\n *\n * The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data,\n * or predicate, with options for recursive or iterative traversal.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `getNodes` function you provided takes several parameters:\n * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that\n * determines whether to return only the first node that matches the criteria specified by the\n * `keyOrNodeOrEntryOrRawOrPredicate` parameter. If `onlyOne` is set to `true`, the function will\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getNodes` function is used to specify the starting point for traversing the binary tree. It\n * represents the root node of the binary tree or the node from which the traversal should begin. If\n * not provided, the default value is set to `this._root\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` function\n * determines the type of iteration to be performed when traversing the nodes of a binary tree. It\n * can have two possible values:\n * @returns The `getNodes` function returns an array of nodes that satisfy the provided condition\n * based on the input parameters and the iteration type specified.\n */\n getNodes(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n onlyOne = false,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): NODE[] {\n if (keyOrNodeOrEntryOrRawOrPredicate === undefined) return [];\n if (keyOrNodeOrEntryOrRawOrPredicate === null) return [];\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const callback = this._ensurePredicate(keyOrNodeOrEntryOrRawOrPredicate);\n\n const ans: NODE[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return;\n }\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n };\n\n dfs(beginRoot);\n } else {\n const stack = [beginRoot];\n while (stack.length > 0) {\n const cur = stack.pop();\n if (this.isRealNode(cur)) {\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n if (this.isRealNode(cur.left)) stack.push(cur.left);\n if (this.isRealNode(cur.right)) stack.push(cur.right);\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n).\n *\n * The `getNode` function retrieves a node based on the provided key, node, entry, raw data, or\n * predicate.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `getNode` function can accept a key,\n * node, entry, raw data, or a predicate function.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getNode` function is used to specify the starting point for searching for a node in a binary\n * tree. If no specific starting point is provided, the default value is set to `this._root`, which\n * is typically the root node of the binary tree.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is\n * used to specify the type of iteration to be performed when searching for a node. It has a default\n * value of `this.iterationType`, which means it will use the iteration type defined in the current\n * context if no specific value is provided\n * @returns The `getNode` function is returning the first node that matches the specified criteria,\n * or `null` if no matching node is found.\n */\n getNode(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): OptBTNOrNull<NODE> {\n return this.getNodes(keyOrNodeOrEntryOrRawOrPredicate, true, beginRoot, iterationType)[0] ?? null;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getNodeByKey` retrieves a node by its key from a binary tree structure.\n * @param {K} key - The `key` parameter is the value used to search for a specific node in a data\n * structure.\n * @param {IterationType} iterationType - The `iterationType` parameter is a type of iteration that\n * specifies how the tree nodes should be traversed when searching for a node with the given key. It\n * is an optional parameter with a default value of `this.iterationType`.\n * @returns The `getNodeByKey` function is returning an optional binary tree node\n * (`OptBTNOrNull<NODE>`).\n */\n getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptBTNOrNull<NODE> {\n return this.getNode(key, this._root, iterationType);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * This function overrides the `get` method to retrieve the value associated with a specified key,\n * node, entry, raw data, or predicate in a data structure.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `get` method can accept one of the\n * following types:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `get`\n * method is used to specify the starting point for searching for a key or node in the binary tree.\n * If no specific starting point is provided, the default starting point is the root of the binary\n * tree (`this._root`).\n * @param {IterationType} iterationType - The `iterationType` parameter in the `get` method is used\n * to specify the type of iteration to be performed when searching for a key in the binary tree. It\n * is an optional parameter with a default value of `this.iterationType`, which means it will use the\n * iteration type defined in the\n * @returns The `get` method is returning the value associated with the specified key, node, entry,\n * raw data, or predicate in the binary tree map. If the specified key or node is found in the tree,\n * the method returns the corresponding value. If the key or node is not found, it returns\n * `undefined`.\n */\n override get(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): V | undefined {\n return this.getNode(keyOrNodeOrEntryOrRawOrPredicate, beginRoot, iterationType)?.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The `has` function in TypeScript checks if a specified key, node, entry, raw data, or predicate\n * exists in the data structure.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `override has` method can accept one of\n * the following types:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `override` method is used to specify the starting point for the search operation within the data\n * structure. It defaults to `this._root` if not provided explicitly.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `override has` method\n * is used to specify the type of iteration to be performed. It has a default value of\n * `this.iterationType`, which means it will use the iteration type defined in the current context if\n * no value is provided when calling the method.\n * @returns The `override has` method is returning a boolean value. It checks if there are any nodes\n * that match the provided key, node, entry, raw data, or predicate in the tree structure. If there\n * are matching nodes, it returns `true`, indicating that the tree contains the specified element.\n * Otherwise, it returns `false`.\n */\n override has(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): boolean {\n return this.getNodes(keyOrNodeOrEntryOrRawOrPredicate, true, beginRoot, iterationType).length > 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function resets the root node and size of a data structure to empty.\n */\n clear() {\n this._setRoot(undefined);\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `isEmpty` function in TypeScript checks if a data structure has no elements and returns a\n * boolean value.\n * @returns The `isEmpty()` method is returning a boolean value, specifically `true` if the `_size`\n * property is equal to 0, indicating that the data structure is empty, and `false` otherwise.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function checks if a binary tree is perfectly balanced by comparing its minimum height with\n * its height.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for checking if the binary tree is perfectly balanced. It represents the root node of the\n * binary tree or a specific node from which the balance check should begin.\n * @returns The method `isPerfectlyBalanced` is returning a boolean value, which indicates whether\n * the tree starting from the `beginRoot` node is perfectly balanced or not. The return value is\n * determined by comparing the minimum height of the tree with the height of the tree. If the minimum\n * height plus 1 is greater than or equal to the height of the tree, then it is considered perfectly\n * balanced and\n */\n isPerfectlyBalanced(beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root): boolean {\n return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `isBST` in TypeScript checks if a binary search tree is valid using either recursive\n * or iterative methods.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `isBST`\n * function represents the starting point for checking whether a binary search tree (BST) is valid.\n * It can be a node in the BST or a reference to the root of the BST. If no specific node is\n * provided, the function will default to\n * @param {IterationType} iterationType - The `iterationType` parameter in the `isBST` function\n * determines whether the function should use a recursive approach or an iterative approach to check\n * if the binary search tree (BST) is valid.\n * @returns The `isBST` method is returning a boolean value, which indicates whether the binary\n * search tree (BST) represented by the given root node is a valid BST or not. The method checks if\n * the tree satisfies the BST property, where for every node, all nodes in its left subtree have keys\n * less than the node's key, and all nodes in its right subtree have keys greater than the node's\n */\n isBST(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): boolean {\n // TODO there is a bug\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return true;\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: OptBTNOrNull<NODE>, min: number, max: number): boolean => {\n if (!this.isRealNode(cur)) return true;\n const numKey = Number(cur.key);\n if (numKey <= min || numKey >= max) return false;\n return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);\n };\n\n const isStandardBST = dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);\n const isInverseBST = dfs(beginRoot, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);\n return isStandardBST || isInverseBST;\n } else {\n const checkBST = (checkMax = false) => {\n const stack = [];\n let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;\n // @ts-ignore\n let curr: OptBTNOrNull<NODE> = beginRoot;\n while (this.isRealNode(curr) || stack.length > 0) {\n while (this.isRealNode(curr)) {\n stack.push(curr);\n curr = curr.left;\n }\n curr = stack.pop()!;\n const numKey = Number(curr.key);\n if (!this.isRealNode(curr) || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey)) return false;\n prev = numKey;\n curr = curr.right;\n }\n return true;\n };\n const isStandardBST = checkBST(false),\n isInverseBST = checkBST(true);\n return isStandardBST || isInverseBST;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `getDepth` function calculates the depth between two nodes in a binary tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} dist - The `dist` parameter in the `getDepth`\n * function represents the node or entry in a binary tree map, or a reference to a node in the tree.\n * It is the target node for which you want to calculate the depth from the `beginRoot` node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getDepth` function represents the starting point from which you want to calculate the depth of a\n * given node or entry in a binary tree. If no specific starting point is provided, the default value\n * for `beginRoot` is set to the root of the binary\n * @returns The `getDepth` method returns the depth of a given node `dist` relative to the\n * `beginRoot` node in a binary tree. If the `dist` node is not found in the path to the `beginRoot`\n * node, it returns the depth of the `dist` node from the root of the tree.\n */\n getDepth(\n dist: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root\n ): number {\n let distEnsured = this.ensureNode(dist);\n const beginRootEnsured = this.ensureNode(beginRoot);\n let depth = 0;\n while (distEnsured?.parent) {\n if (distEnsured === beginRootEnsured) {\n return depth;\n }\n depth++;\n distEnsured = distEnsured.parent;\n }\n return depth;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `getHeight` function calculates the maximum height of a binary tree using either a recursive\n * or iterative approach in TypeScript.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point from which the height of the binary tree will be calculated. It can be a node in the binary\n * tree or a reference to the root of the tree. If not provided, it defaults to the root of the\n * binary tree data structure.\n * @param {IterationType} iterationType - The `iterationType` parameter is used to determine the type\n * of iteration to be performed while calculating the height of the binary tree. It can have two\n * possible values:\n * @returns The `getHeight` method returns the height of the binary tree starting from the specified\n * root node. The height is calculated based on the maximum depth of the tree, considering either a\n * recursive approach or an iterative approach depending on the `iterationType` parameter.\n */\n getHeight(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!this.isRealNode(beginRoot)) return -1;\n\n if (iterationType === 'RECURSIVE') {\n const _getMaxHeight = (cur: OptBTNOrNull<NODE>): number => {\n if (!this.isRealNode(cur)) return -1;\n const leftHeight = _getMaxHeight(cur.left);\n const rightHeight = _getMaxHeight(cur.right);\n return Math.max(leftHeight, rightHeight) + 1;\n };\n\n return _getMaxHeight(beginRoot);\n } else {\n const stack: { node: NODE; depth: number }[] = [{ node: beginRoot, depth: 0 }];\n let maxHeight = 0;\n\n while (stack.length > 0) {\n const { node, depth } = stack.pop()!;\n\n if (this.isRealNode(node.left)) stack.push({ node: node.left, depth: depth + 1 });\n if (this.isRealNode(node.right)) stack.push({ node: node.right, depth: depth + 1 });\n\n maxHeight = Math.max(maxHeight, depth);\n }\n\n return maxHeight;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The `getMinHeight` function calculates the minimum height of a binary tree using either a\n * recursive or iterative approach in TypeScript.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getMinHeight` function represents the starting node from which the minimum height of the binary\n * tree will be calculated. It is either a node in the binary tree or a reference to the root of the\n * tree. If not provided, the default value is the root\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getMinHeight` method\n * specifies the type of iteration to use when calculating the minimum height of a binary tree. It\n * can have two possible values:\n * @returns The `getMinHeight` method returns the minimum height of the binary tree starting from the\n * specified root node. The height is calculated based on the shortest path from the root node to a\n * leaf node in the tree. The method uses either a recursive approach or an iterative approach (using\n * a stack) based on the `iterationType` parameter.\n */\n getMinHeight(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return -1;\n\n if (iterationType === 'RECURSIVE') {\n const _getMinHeight = (cur: OptBTNOrNull<NODE>): number => {\n if (!this.isRealNode(cur)) return 0;\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;\n const leftMinHeight = _getMinHeight(cur.left);\n const rightMinHeight = _getMinHeight(cur.right);\n return Math.min(leftMinHeight, rightMinHeight) + 1;\n };\n\n return _getMinHeight(beginRoot);\n } else {\n const stack: NODE[] = [];\n let node: OptBTNOrNull<NODE> = beginRoot,\n last: OptBTNOrNull<NODE> = null;\n const depths: Map<NODE, number> = new Map();\n\n while (stack.length > 0 || node) {\n if (this.isRealNode(node)) {\n stack.push(node);\n node = node.left;\n } else {\n node = stack[stack.length - 1];\n if (!this.isRealNode(node.right) || last === node.right) {\n node = stack.pop();\n if (this.isRealNode(node)) {\n const leftMinHeight = this.isRealNode(node.left) ? depths.get(node.left)! : -1;\n const rightMinHeight = this.isRealNode(node.right) ? depths.get(node.right)! : -1;\n depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));\n last = node;\n node = null;\n }\n } else node = node.right;\n }\n }\n\n return depths.get(beginRoot)!;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n *\n * The function `getPathToRoot` in TypeScript retrieves the path from a given node to the root of a\n * tree structure, applying a specified callback function along the way.\n * @param {C} callback - The `callback` parameter is a function that is used to process each node in\n * the path to the root. It is expected to be a function that takes a node as an argument and returns\n * a value based on that node. The return type of the callback function is determined by the generic\n * type `C\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginNode - The `beginNode` parameter in the\n * `getPathToRoot` function can be either a key, a node, an entry, or any other value of type `R`.\n * @param [isReverse=true] - The `isReverse` parameter in the `getPathToRoot` function determines\n * whether the resulting path from the given `beginNode` to the root should be in reverse order or\n * not. If `isReverse` is set to `true`, the path will be reversed before being returned. If `is\n * @returns The function `getPathToRoot` returns an array of the return values of the callback\n * function `callback` applied to each node in the path from the `beginNode` to the root node. The\n * array is either in reverse order or in the original order based on the value of the `isReverse`\n * parameter.\n */\n getPathToRoot<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n isReverse = true\n ): ReturnType<C>[] {\n const result: ReturnType<C>[] = [];\n let beginNodeEnsured = this.ensureNode(beginNode);\n\n if (!beginNodeEnsured) return result;\n\n while (beginNodeEnsured.parent) {\n // Array.push + Array.reverse is more efficient than Array.unshift\n result.push(callback(beginNodeEnsured));\n beginNodeEnsured = beginNodeEnsured.parent;\n }\n result.push(callback(beginNodeEnsured));\n return isReverse ? result.reverse() : result;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getLeftMost` retrieves the leftmost node in a binary tree using either recursive or\n * tail-recursive iteration.\n * @param {C} callback - The `callback` parameter is a function that will be called with the leftmost\n * node of a binary tree or with `undefined` if the tree is empty. It is provided with a default\n * value of `_DEFAULT_BTN_CALLBACK` if not specified.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getLeftMost` function represents the starting point for finding the leftmost node in a binary\n * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific\n * starting point is provided, the function will default\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getLeftMost` function\n * specifies the type of iteration to be used when traversing the binary tree nodes. It can have two\n * possible values:\n * @returns The `getLeftMost` function returns the result of the callback function `C` applied to the\n * leftmost node in the binary tree starting from the `beginRoot` node. If the `beginRoot` node is\n * `NIL`, it returns the result of the callback function applied to `undefined`. If the `beginRoot`\n * node is not a real node, it returns the result of the callback\n */\n getLeftMost<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C> {\n if (this.isNIL(beginRoot)) return callback(undefined);\n beginRoot = this.ensureNode(beginRoot);\n\n if (!this.isRealNode(beginRoot)) return callback(beginRoot);\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE): NODE => {\n if (!this.isRealNode(cur.left)) return cur;\n return dfs(cur.left);\n };\n\n return callback(dfs(beginRoot));\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const dfs = trampoline((cur: NODE): NODE => {\n if (!this.isRealNode(cur.left)) return cur;\n return dfs.cont(cur.left);\n });\n\n return callback(dfs(beginRoot));\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive\n * or iterative traversal methods.\n * @param {C} callback - The `callback` parameter is a function that will be called with the result\n * of finding the rightmost node in a binary tree. It is of type `BTNCallback<OptBTNOrNull<NODE>>`,\n * which means it is a callback function that can accept either an optional binary tree node or null\n * as\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getRightMost` function represents the starting point for finding the rightmost node in a binary\n * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific\n * starting point is provided, the function will default\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getRightMost`\n * function specifies the type of iteration to be used when traversing the binary tree nodes. It can\n * have two possible values:\n * @returns The `getRightMost` function returns the result of the callback function `C`, which is\n * passed as a parameter to the function. The callback function is called with the rightmost node in\n * the binary tree structure, determined based on the specified iteration type ('RECURSIVE' or\n * other).\n */\n getRightMost<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C> {\n if (this.isNIL(beginRoot)) return callback(undefined);\n // TODO support get right most by passing key in\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return callback(beginRoot);\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE): NODE => {\n if (!this.isRealNode(cur.right)) return cur;\n return dfs(cur.right);\n };\n\n return callback(dfs(beginRoot));\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const dfs = trampoline((cur: NODE) => {\n if (!this.isRealNode(cur.right)) return cur;\n return dfs.cont(cur.right);\n });\n\n return callback(dfs(beginRoot));\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getPredecessor` in TypeScript returns the predecessor node of a given node in a\n * binary tree.\n * @param {NODE} node - The `getPredecessor` function you provided seems to be attempting to find the\n * predecessor of a given node in a binary tree. However, there seems to be a logical issue in the\n * while loop condition that might cause an infinite loop.\n * @returns The `getPredecessor` function returns the predecessor node of the input `NODE` parameter.\n * If the left child of the input node exists, it traverses to the rightmost node of the left subtree\n * to find the predecessor. If the left child does not exist, it returns the input node itself.\n */\n getPredecessor(node: NODE): NODE {\n if (this.isRealNode(node.left)) {\n let predecessor: OptBTNOrNull<NODE> = node.left;\n while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {\n if (this.isRealNode(predecessor)) {\n predecessor = predecessor.right;\n }\n }\n return predecessor;\n } else {\n return node;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getSuccessor` in TypeScript returns the next node in an in-order traversal of a\n * binary tree.\n * @param {K | NODE | null} [x] - The `getSuccessor` function takes a parameter `x`, which can be of\n * type `K`, `NODE`, or `null`.\n * @returns The `getSuccessor` function returns the successor node of the input node `x`. If `x` has\n * a right child, the function returns the leftmost node in the right subtree of `x`. If `x` does not\n * have a right child, the function traverses up the parent nodes until it finds a node that is not\n * the right child of its parent, and returns that node\n */\n getSuccessor(x?: K | NODE | null): OptBTNOrNull<NODE> {\n x = this.ensureNode(x);\n if (!this.isRealNode(x)) return undefined;\n\n if (this.isRealNode(x.right)) {\n return this.getLeftMost(node => node, x.right);\n }\n\n let y: OptBTNOrNull<NODE> = x.parent;\n while (this.isRealNode(y) && x === y.right) {\n x = y;\n y = y.parent;\n }\n return y;\n }\n\n dfs<C extends BTNCallback<NODE>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType\n ): ReturnType<C>[];\n\n dfs<C extends BTNCallback<NODE | null>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: boolean\n ): ReturnType<C>[];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function `dfs` performs a depth-first search traversal on a binary tree structure based on the\n * specified parameters.\n * @param {C} callback - The `callback` parameter is a generic type `C` that extends the\n * `BTNCallback` interface with a type parameter of `OptBTNOrNull<NODE>`. It has a default value of\n * `this._DEFAULT_BTN_CALLBACK as C`.\n * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `dfs` method specifies the\n * order in which the Depth-First Search (DFS) algorithm should traverse the nodes in the tree. The\n * possible values for the `pattern` parameter are:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `dfs`\n * method is used to specify the starting point for the Depth-First Search traversal. It can be\n * either a `BTNKeyOrNodeOrEntry` object representing a key, node, or entry in the binary tree map,\n * or it can be a\n * @param {IterationType} iterationType - The `iterationType` parameter in the `dfs` method specifies\n * the type of iteration to be performed during the depth-first search traversal. It is used to\n * determine the order in which nodes are visited during the traversal.\n * @param [includeNull=false] - The `includeNull` parameter in the `dfs` method is a boolean flag\n * that determines whether null values should be included in the traversal or not. If `includeNull`\n * is set to `true`, then null values will be included in the traversal process. If it is set to\n * `false`,\n * @returns The `dfs` method is returning an array of the return type specified by the generic type\n * parameter `C`. The return type is determined by the callback function provided to the method.\n */\n dfs<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n return this._dfs(callback, pattern, beginRoot, iterationType, includeNull);\n }\n\n bfs<C extends BTNCallback<NODE>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n bfs<C extends BTNCallback<NODE | null>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: true\n ): ReturnType<C>[];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `bfs` function performs a breadth-first search traversal on a binary tree or binary search\n * tree, executing a specified callback function on each node visited.\n * @param {C} callback - The `callback` parameter in the `bfs` function is a function that will be\n * called on each node visited during the breadth-first search traversal. It is a generic type `C`\n * that extends the `BTNCallback` type, which takes a parameter of type `NODE` or `null`.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `bfs`\n * function represents the starting point for the breadth-first search traversal in a binary tree. It\n * can be specified as a key, node, or entry in the binary tree structure. If not provided, the\n * default value is the root node of the binary\n * @param {IterationType} iterationType - The `iterationType` parameter in the `bfs` function\n * determines the type of iteration to be performed on the binary tree nodes. It can have two\n * possible values:\n * @param [includeNull=false] - The `includeNull` parameter in the `bfs` function determines whether\n * to include `null` values in the breadth-first search traversal of a binary tree. If `includeNull`\n * is set to `true`, the traversal will include `null` values for nodes that do not have children\n * (left\n * @returns The `bfs` function returns an array of values that are the result of applying the\n * provided callback function to each node in the binary tree in a breadth-first search manner.\n */\n bfs<C extends BTNCallback<NODE | null>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n\n const ans: ReturnType<BTNCallback<NODE>>[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const queue: Queue<OptBTNOrNull<NODE>> = new Queue<OptBTNOrNull<NODE>>([beginRoot]);\n\n const dfs = (level: number) => {\n if (queue.size === 0) return;\n\n const current = queue.shift()!;\n ans.push(callback(current));\n\n if (includeNull) {\n if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (this.isRealNode(current.left)) queue.push(current.left);\n if (this.isRealNode(current.right)) queue.push(current.right);\n }\n\n dfs(level + 1);\n };\n\n dfs(0);\n } else {\n const queue = new Queue<OptBTNOrNull<NODE>>([beginRoot]);\n while (queue.size > 0) {\n const levelSize = queue.size;\n\n for (let i = 0; i < levelSize; i++) {\n const current = queue.shift()!;\n ans.push(callback(current));\n\n if (includeNull) {\n if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (this.isRealNode(current.left)) queue.push(current.left);\n if (this.isRealNode(current.right)) queue.push(current.right);\n }\n }\n }\n }\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `leaves` function in TypeScript returns an array of values from leaf nodes in a binary tree\n * structure based on a specified callback and iteration type.\n * @param {C} callback - The `callback` parameter is a function that will be called on each leaf node\n * in the binary tree. It is optional and defaults to a default callback function if not provided.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `leaves`\n * method is used to specify the starting point for finding and processing the leaves of a binary\n * tree. It can be provided as either a key, a node, or an entry in the binary tree structure. If not\n * explicitly provided, the default value\n * @param {IterationType} iterationType - The `iterationType` parameter in the `leaves` method\n * specifies the type of iteration to be performed when collecting the leaves of a binary tree. It\n * can have two possible values:\n * @returns The `leaves` method returns an array of values that are the result of applying the\n * provided callback function to each leaf node in the binary tree.\n */\n leaves<C extends BTNCallback<NODE | null>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n const leaves: ReturnType<BTNCallback<NODE>>[] = [];\n if (!this.isRealNode(beginRoot)) return [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n if (this.isLeaf(cur)) {\n leaves.push(callback(cur));\n }\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n };\n\n dfs(beginRoot);\n } else {\n const queue = new Queue([beginRoot]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (this.isRealNode(cur)) {\n if (this.isLeaf(cur)) {\n leaves.push(callback(cur));\n }\n if (this.isRealNode(cur.left)) queue.push(cur.left);\n if (this.isRealNode(cur.right)) queue.push(cur.right);\n }\n }\n }\n\n return leaves;\n }\n\n listLevels<C extends BTNCallback<NODE>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[][];\n\n listLevels<C extends BTNCallback<NODE | null>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: true\n ): ReturnType<C>[][];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `listLevels` function in TypeScript generates a list of nodes at each level of a binary tree,\n * using either recursive or iterative traversal based on the specified iteration type.\n * @param {C} callback - The `callback` parameter is a function that will be applied to each node in\n * the binary tree during the traversal. It is used to process each node and determine what\n * information to include in the output for each level of the tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `listLevels` function represents the starting point for traversing the binary tree. It can be\n * either a key, a node, or an entry in the binary tree. If not provided, the default value is the\n * root of the binary tree.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `listLevels` function\n * determines the type of iteration to be performed on the binary tree nodes. It can have two\n * possible values:\n * @param [includeNull=false] - The `includeNull` parameter in the `listLevels` method determines\n * whether or not to include null nodes in the traversal of the binary tree. If `includeNull` is set\n * to `true`, the traversal will include null nodes in the levels of the tree. If set to `false`,\n * null\n * @returns The `listLevels` method returns an array of arrays, where each inner array represents a\n * level in a binary tree. Each inner array contains the return value of the provided callback\n * function applied to the nodes at that level.\n */\n listLevels<C extends BTNCallback<NODE | null>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[][] {\n beginRoot = this.ensureNode(beginRoot);\n const levelsNodes: ReturnType<C>[][] = [];\n if (!beginRoot) return levelsNodes;\n\n if (iterationType === 'RECURSIVE') {\n const _recursive = (node: NODE | null, level: number) => {\n if (!levelsNodes[level]) levelsNodes[level] = [];\n levelsNodes[level].push(callback(node));\n if (includeNull) {\n if (node && this.isRealNodeOrNull(node.left)) _recursive(node.left, level + 1);\n if (node && this.isRealNodeOrNull(node.right)) _recursive(node.right, level + 1);\n } else {\n if (node && node.left) _recursive(node.left, level + 1);\n if (node && node.right) _recursive(node.right, level + 1);\n }\n };\n\n _recursive(beginRoot, 0);\n } else {\n const stack: [NODE | null, number][] = [[beginRoot, 0]];\n\n while (stack.length > 0) {\n const head = stack.pop()!;\n const [node, level] = head;\n\n if (!levelsNodes[level]) levelsNodes[level] = [];\n levelsNodes[level].push(callback(node));\n\n if (includeNull) {\n if (node && this.isRealNodeOrNull(node.right)) stack.push([node.right, level + 1]);\n if (node && this.isRealNodeOrNull(node.left)) stack.push([node.left, level + 1]);\n } else {\n if (node && node.right) stack.push([node.right, level + 1]);\n if (node && node.left) stack.push([node.left, level + 1]);\n }\n }\n }\n\n return levelsNodes;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `morris` function in TypeScript performs a Depth-First Search traversal on a binary tree using\n * Morris Traversal algorithm with different order patterns.\n * @param {C} callback - The `callback` parameter in the `morris` function is a function that will be\n * called on each node in the binary tree during the traversal. It is of type `C`, which extends the\n * `BTNCallback<NODE>` type. The default value for `callback` is `this._DEFAULT\n * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function specifies\n * the type of Depth-First Search (DFS) order pattern to traverse the binary tree. The possible\n * values for the `pattern` parameter are:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `morris`\n * function is the starting point for the Morris traversal algorithm. It represents the root node of\n * the binary tree or the node from which the traversal should begin. It can be provided as either a\n * key, a node, an entry, or a reference\n * @returns The `morris` function is returning an array of values that are the result of applying the\n * provided callback function to each node in the binary tree in the specified order pattern (IN,\n * PRE, or POST).\n */\n morris<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: ReturnType<BTNCallback<NODE>>[] = [];\n\n let cur: OptBTNOrNull<NODE> = beginRoot;\n const _reverseEdge = (node: OptBTNOrNull<NODE>) => {\n let pre: OptBTNOrNull<NODE> = null;\n let next: OptBTNOrNull<NODE> = null;\n while (node) {\n next = node.right;\n node.right = pre;\n pre = node;\n node = next;\n }\n return pre;\n };\n const _printEdge = (node: OptBTNOrNull<NODE>) => {\n const tail: OptBTNOrNull<NODE> = _reverseEdge(node);\n let cur: OptBTNOrNull<NODE> = tail;\n while (cur) {\n ans.push(callback(cur));\n cur = cur.right;\n }\n _reverseEdge(tail);\n };\n switch (pattern) {\n case 'IN':\n while (cur) {\n if (cur.left) {\n const predecessor = this.getPredecessor(cur);\n if (!predecessor.right) {\n predecessor.right = cur;\n cur = cur.left;\n continue;\n } else {\n predecessor.right = null;\n }\n }\n ans.push(callback(cur));\n cur = cur.right;\n }\n break;\n case 'PRE':\n while (cur) {\n if (cur.left) {\n const predecessor = this.getPredecessor(cur);\n if (!predecessor.right) {\n predecessor.right = cur;\n ans.push(callback(cur));\n cur = cur.left;\n continue;\n } else {\n predecessor.right = null;\n }\n } else {\n ans.push(callback(cur));\n }\n cur = cur.right;\n }\n break;\n case 'POST':\n while (cur) {\n if (cur.left) {\n const predecessor = this.getPredecessor(cur);\n if (predecessor.right === null) {\n predecessor.right = cur;\n cur = cur.left;\n continue;\n } else {\n predecessor.right = null;\n _printEdge(cur.left);\n }\n }\n cur = cur.right;\n }\n _printEdge(beginRoot);\n break;\n }\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `clone` function creates a deep copy of a tree structure by traversing it using breadth-first\n * search.\n * @returns The `clone()` method is returning a cloned copy of the tree with the same structure and\n * values as the original tree. The method creates a new tree, iterates over the nodes of the\n * original tree using breadth-first search (bfs), and adds the nodes to the new tree. If a node in\n * the original tree is null, a null node is added to the cloned tree. If a node\n */\n clone(): TREE {\n const cloned = this.createTree();\n this.bfs(\n node => {\n if (node === null) cloned.add(null);\n else cloned.add([node.key, node.value]);\n },\n this._root,\n this.iterationType,\n true\n );\n return cloned;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function iterates over key-value pairs in a tree data structure and creates a new\n * tree with elements that satisfy a given predicate.\n * @param predicate - The `predicate` parameter in the `filter` method is a function that will be\n * called with four arguments: the `value` of the current entry, the `key` of the current entry, the\n * `index` of the current entry in the iteration, and the reference to the tree itself (`\n * @param {any} [thisArg] - The `thisArg` parameter in the `filter` method allows you to specify the\n * value of `this` that should be used when executing the `predicate` function. This is useful when\n * the `predicate` function relies on the context of a specific object or value. By providing a\n * `thisArg\n * @returns The `filter` method is returning a new tree that contains entries that pass the provided\n * predicate function.\n */\n filter(predicate: EntryCallback<K, V | undefined, boolean>, thisArg?: any) {\n const newTree = this.createTree();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index++, this)) {\n newTree.add([key, value]);\n }\n }\n return newTree;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function iterates over key-value pairs in a tree data structure, applies a callback\n * function to each value, and returns a new tree with the updated values.\n * @param callback - The `callback` parameter in the `map` method is a function that will be called\n * on each entry in the tree. It takes four arguments:\n * @param {any} [thisArg] - The `thisArg` parameter in the `map` function is an optional parameter\n * that specifies the value to be passed as `this` when executing the callback function. If provided,\n * the `thisArg` value will be used as the `this` value within the callback function. If `thisArg\n * @returns The `map` method is returning a new tree with the entries modified by the provided\n * callback function. Each entry in the original tree is passed to the callback function, and the\n * result of the callback function is added to the new tree.\n */\n map(callback: EntryCallback<K, V | undefined, V>, thisArg?: any) {\n const newTree = this.createTree();\n let index = 0;\n for (const [key, value] of this) {\n newTree.add([key, callback.call(thisArg, value, key, index++, this)]);\n }\n return newTree;\n }\n\n // // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.\n // // map<NV>(callback: (entry: [K, V | undefined], tree: this) => NV) {\n // // const newTree = this.createTree();\n // // for (const [key, value] of this) {\n // // newTree.add(key, callback([key, value], this));\n // // }\n // // return newTree;\n // // }\n //\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `toVisual` in TypeScript overrides the visual representation of a binary tree with\n * customizable options for displaying undefined, null, and sentinel nodes.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `toVisual` method is used to specify the starting point for visualizing the binary tree structure.\n * It can be a node, key, entry, or the root of the tree. If no specific starting point is provided,\n * the default is set to the root\n * @param {BinaryTreePrintOptions} [options] - The `options` parameter in the `toVisual` method is an\n * object that contains the following properties:\n * @returns The `override toVisual` method returns a string that represents the visual display of the\n * binary tree based on the provided options for showing undefined, null, and Red-Black NIL nodes.\n * The method constructs the visual representation by calling the `_displayAux` method and appending\n * the lines to the output string. The final output string contains the visual representation of the\n * binary tree with the specified options.\n */\n override toVisual(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n options?: BinaryTreePrintOptions\n ): string {\n const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };\n beginRoot = this.ensureNode(beginRoot);\n let output = '';\n if (!beginRoot) return output;\n\n if (opts.isShowUndefined)\n output += `U for undefined\n `;\n if (opts.isShowNull)\n output += `N for null\n `;\n if (opts.isShowRedBlackNIL)\n output += `S for Sentinel Node(NIL)\n `;\n\n const display = (root: OptBTNOrNull<NODE>): void => {\n const [lines, , ,] = this._displayAux(root, opts);\n let paragraph = '';\n for (const line of lines) {\n paragraph += line + '\\n';\n }\n output += paragraph;\n };\n\n display(beginRoot);\n return output;\n }\n\n protected _dfs<C extends BTNCallback<NODE>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType\n ): ReturnType<C>[];\n\n protected _dfs<C extends BTNCallback<NODE | null>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: boolean\n ): ReturnType<C>[];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `_dfs` function performs a depth-first search traversal on a binary tree structure based on\n * the specified order pattern and callback function.\n * @param {C} callback - The `callback` parameter in the `_dfs` method is a function that will be\n * called on each node visited during the depth-first search traversal. It is of type `C`, which\n * extends `BTNCallback<OptBTNOrNull<NODE>>`. The default value for this parameter is `this._DEFAULT\n * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the\n * order in which the nodes are visited during the Depth-First Search traversal. It can have one of\n * the following values:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `_dfs`\n * method is used to specify the starting point for the depth-first search traversal in a binary\n * tree. It can be provided as either a `BTNKeyOrNodeOrEntry` object or a reference to the root node\n * of the tree. If no specific\n * @param {IterationType} iterationType - The `iterationType` parameter in the `_dfs` method\n * specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal of a\n * binary tree. It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter in the `_dfs` method is a boolean flag\n * that determines whether null nodes should be included in the depth-first search traversal. If\n * `includeNull` is set to `true`, null nodes will be considered during the traversal process. If it\n * is set to `false`,\n * @param shouldVisitLeft - The `shouldVisitLeft` parameter is a function that takes a node as input\n * and returns a boolean value. It is used to determine whether the left child of a node should be\n * visited during the depth-first search traversal. By default, it checks if the node is truthy (not\n * null or undefined\n * @param shouldVisitRight - The `shouldVisitRight` parameter is a function that takes a node as an\n * argument and returns a boolean value. It is used to determine whether the right child of a node\n * should be visited during the depth-first search traversal. The default implementation checks if\n * the node is truthy before visiting the right child\n * @param shouldVisitRoot - The `shouldVisitRoot` parameter is a function that takes a node as an\n * argument and returns a boolean value. It is used to determine whether the root node should be\n * visited during the depth-first search traversal based on certain conditions. The default\n * implementation checks if the node is a real node or null based\n * @param shouldProcessRoot - The `shouldProcessRoot` parameter is a function that takes a node as an\n * argument and returns a boolean value indicating whether the node should be processed during the\n * depth-first search traversal. The default implementation checks if the node is a real node or null\n * based on the `includeNull` flag. If `\n * @returns The function `_dfs` returns an array of the return type of the callback function provided\n * as input.\n */\n protected _dfs<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false,\n shouldVisitLeft: (node: OptBTNOrNull<NODE>) => boolean = node => !!node,\n shouldVisitRight: (node: OptBTNOrNull<NODE>) => boolean = node => !!node,\n shouldVisitRoot: (node: OptBTNOrNull<NODE>) => boolean = node => {\n if (includeNull) return this.isRealNodeOrNull(node);\n return this.isRealNode(node);\n },\n shouldProcessRoot: (node: OptBTNOrNull<NODE>) => boolean = node => this.isRealNodeOrNull(node)\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: ReturnType<C>[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (node: OptBTNOrNull<NODE>) => {\n if (!shouldVisitRoot(node)) return;\n\n const visitLeft = () => {\n if (shouldVisitLeft(node)) dfs(node?.left);\n };\n const visitRight = () => {\n if (shouldVisitRight(node)) dfs(node?.right);\n };\n\n switch (pattern) {\n case 'IN':\n visitLeft();\n if (shouldProcessRoot(node)) ans.push(callback(node));\n visitRight();\n break;\n case 'PRE':\n if (shouldProcessRoot(node)) ans.push(callback(node));\n visitLeft();\n visitRight();\n break;\n case 'POST':\n visitLeft();\n visitRight();\n if (shouldProcessRoot(node)) ans.push(callback(node));\n break;\n }\n };\n\n dfs(beginRoot);\n } else {\n const stack: DFSStackItem<NODE>[] = [{ opt: DFSOperation.VISIT, node: beginRoot }];\n\n const pushLeft = (cur: DFSStackItem<NODE>) => {\n if (shouldVisitLeft(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.left });\n };\n const pushRight = (cur: DFSStackItem<NODE>) => {\n if (shouldVisitRight(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.right });\n };\n const pushRoot = (cur: DFSStackItem<NODE>) => {\n if (shouldVisitRoot(cur.node)) stack.push({ opt: DFSOperation.PROCESS, node: cur.node });\n };\n\n while (stack.length > 0) {\n const cur = stack.pop();\n if (cur === undefined) continue;\n if (!shouldVisitRoot(cur.node)) continue;\n if (cur.opt === DFSOperation.PROCESS) {\n if (shouldProcessRoot(cur.node)) ans.push(callback(cur.node));\n } else {\n switch (pattern) {\n case 'IN':\n pushRight(cur);\n pushRoot(cur);\n pushLeft(cur);\n break;\n case 'PRE':\n pushRight(cur);\n pushLeft(cur);\n pushRoot(cur);\n break;\n case 'POST':\n pushRoot(cur);\n pushRight(cur);\n pushLeft(cur);\n break;\n }\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_getIterator` returns an iterable iterator for a binary tree data structure, either\n * using an iterative approach or a recursive approach based on the specified iteration type.\n * @param node - The `node` parameter in the `_getIterator` method represents the current node being\n * processed during iteration. It is initially set to the root node of the data structure (or the\n * node passed as an argument), and then it is traversed through the data structure based on the\n * iteration type specified (`ITER\n * @returns The `_getIterator` method returns an IterableIterator containing key-value pairs of nodes\n * in a binary tree structure. The method uses an iterative approach to traverse the tree based on\n * the `iterationType` property. If the `iterationType` is set to 'ITERATIVE', the method uses a\n * stack to perform an in-order traversal of the tree. If the `iterationType` is not 'ITERATIVE\n */\n protected *_getIterator(node = this._root): IterableIterator<[K, V | undefined]> {\n if (!node) return;\n\n if (this.iterationType === 'ITERATIVE') {\n const stack: OptBTNOrNull<NODE>[] = [];\n let current: OptBTNOrNull<NODE> = node;\n\n while (current || stack.length > 0) {\n while (this.isRealNode(current)) {\n stack.push(current);\n current = current.left;\n }\n\n current = stack.pop();\n\n if (this.isRealNode(current)) {\n yield [current.key, current.value];\n current = current.right;\n }\n }\n } else {\n if (node.left && this.isRealNode(node)) {\n yield* this[Symbol.iterator](node.left);\n }\n yield [node.key, node.value];\n if (node.right && this.isRealNode(node)) {\n yield* this[Symbol.iterator](node.right);\n }\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `_displayAux` in TypeScript is responsible for generating the display layout of nodes\n * in a binary tree based on specified options.\n * @param node - The `node` parameter in the `_displayAux` function represents a node in a binary\n * tree. It can be either a valid node containing a key or a special type of node like null,\n * undefined, or a Red-Black tree NIL node. The function checks the type of the node and its\n * @param {BinaryTreePrintOptions} options - The `options` parameter in the `_displayAux` function\n * contains the following properties:\n * @returns The `_displayAux` function returns a `NodeDisplayLayout`, which is an array containing\n * information about how to display a node in a binary tree. The `NodeDisplayLayout` consists of four\n * elements:\n */\n protected _displayAux(node: OptBTNOrNull<NODE>, options: BinaryTreePrintOptions): NodeDisplayLayout {\n const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;\n const emptyDisplayLayout = <NodeDisplayLayout>[['─'], 1, 0, 0];\n\n // Check if node is null or undefined or key is NaN\n if (node === null && !isShowNull) {\n return emptyDisplayLayout;\n } else if (node === undefined && !isShowUndefined) {\n return emptyDisplayLayout;\n } else if (this.isNIL(node) && !isShowRedBlackNIL) {\n return emptyDisplayLayout;\n } else if (node !== null && node !== undefined) {\n // Display logic of normal nodes\n\n const key = node.key,\n line = this.isNIL(node) ? 'S' : String(key),\n width = line.length;\n\n return _buildNodeDisplay(\n line,\n width,\n this._displayAux(node.left, options),\n this._displayAux(node.right, options)\n );\n } else {\n // For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed\n const line = node === undefined ? 'U' : 'N',\n width = line.length;\n\n return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);\n }\n\n function _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {\n const [leftLines, leftWidth, leftHeight, leftMiddle] = left;\n const [rightLines, rightWidth, rightHeight, rightMiddle] = right;\n const firstLine =\n ' '.repeat(Math.max(0, leftMiddle + 1)) +\n '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1)) +\n line +\n '_'.repeat(Math.max(0, rightMiddle)) +\n ' '.repeat(Math.max(0, rightWidth - rightMiddle));\n\n const secondLine =\n (leftHeight > 0\n ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1)\n : ' '.repeat(leftWidth)) +\n ' '.repeat(width) +\n (rightHeight > 0\n ? ' '.repeat(rightMiddle) + '\\\\' + ' '.repeat(rightWidth - rightMiddle - 1)\n : ' '.repeat(rightWidth));\n\n const mergedLines = [firstLine, secondLine];\n\n for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {\n const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);\n const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);\n mergedLines.push(leftLine + ' '.repeat(width) + rightLine);\n }\n\n return <NodeDisplayLayout>[\n mergedLines,\n leftWidth + width + rightWidth,\n Math.max(leftHeight, rightHeight) + 2,\n leftWidth + Math.floor(width / 2)\n ];\n }\n }\n\n protected _DEFAULT_BTN_CALLBACK = (node: OptBTNOrNull<NODE>) => (node ? node.key : undefined);\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The _swapProperties function swaps key and value properties between two nodes in a binary tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} srcNode - The `srcNode` parameter in the\n * `_swapProperties` method can be either a BTNKeyOrNodeOrEntry object containing key and value\n * properties, or it can be of type R.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} destNode - The `destNode` parameter in the\n * `_swapProperties` method represents the node or entry where the properties will be swapped with\n * the `srcNode`. It can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. The method ensures that\n * both `srcNode\n * @returns The `_swapProperties` method returns either the `destNode` with its key and value swapped\n * with the `srcNode`, or `undefined` if either `srcNode` or `destNode` is falsy.\n */\n protected _swapProperties(\n srcNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n destNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R\n ): NODE | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n\n if (srcNode && destNode) {\n const { key, value } = destNode;\n const tempNode = this.createNode(key, value);\n\n if (tempNode) {\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The _replaceNode function replaces an old node with a new node in a binary tree structure.\n * @param {NODE} oldNode - The `oldNode` parameter represents the node that you want to replace in a\n * tree data structure.\n * @param {NODE} newNode - The `newNode` parameter in the `_replaceNode` function represents the node\n * that will replace the `oldNode` in a tree data structure. This function is responsible for\n * updating the parent, left child, right child, and root (if necessary) references when replacing a\n * node in the tree.\n * @returns The method `_replaceNode` is returning the `newNode` that was passed as a parameter after\n * replacing the `oldNode` with it in the binary tree structure.\n */\n protected _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n if (oldNode.parent) {\n if (oldNode.parent.left === oldNode) {\n oldNode.parent.left = newNode;\n } else if (oldNode.parent.right === oldNode) {\n oldNode.parent.right = newNode;\n }\n }\n newNode.left = oldNode.left;\n newNode.right = oldNode.right;\n newNode.parent = oldNode.parent;\n if (this._root === oldNode) {\n this._setRoot(newNode);\n }\n\n return newNode;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function _setRoot sets the root node of a data structure while updating the parent reference\n * of the previous root node.\n * @param v - The parameter `v` in the `_setRoot` method is of type `OptBTNOrNull<NODE>`, which means\n * it can either be an optional `NODE` type or `null`.\n */\n protected _setRoot(v: OptBTNOrNull<NODE>) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_ensurePredicate` in TypeScript ensures that the input is converted into a valid\n * predicate function for a binary tree node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrEntryOrRawOrPredicate - The\n * `_ensurePredicate` method in the provided code snippet is responsible for ensuring that the input\n * parameter `keyOrEntryOrRawOrPredicate` is transformed into a valid predicate function that can be\n * used for filtering nodes in a binary tree.\n * @returns A BTNPredicate<NODE> function is being returned.\n */\n protected _ensurePredicate(\n keyOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>\n ): BTNPredicate<NODE> {\n if (keyOrEntryOrRawOrPredicate === null || keyOrEntryOrRawOrPredicate === undefined)\n return (node: NODE) => (node ? false : false);\n\n if (this._isPredicated(keyOrEntryOrRawOrPredicate)) return keyOrEntryOrRawOrPredicate;\n\n if (this.isRealNode(keyOrEntryOrRawOrPredicate)) return (node: NODE) => node === keyOrEntryOrRawOrPredicate;\n\n if (this.isEntry(keyOrEntryOrRawOrPredicate)) {\n const [key] = keyOrEntryOrRawOrPredicate;\n return (node: NODE) => node.key === key;\n }\n\n if (this.isKey(keyOrEntryOrRawOrPredicate)) return (node: NODE) => node.key === keyOrEntryOrRawOrPredicate;\n\n if (this._toEntryFn) {\n const [key] = this._toEntryFn(keyOrEntryOrRawOrPredicate);\n return (node: NODE) => node.key === key;\n }\n return (node: NODE) => node.key === keyOrEntryOrRawOrPredicate;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_isPredicated` checks if a given parameter is a function.\n * @param {any} p - The parameter `p` is a variable of type `any`, which means it can hold any type\n * of value. In this context, the function `_isPredicated` is checking if `p` is a function that\n * satisfies the type `BTNPredicate<NODE>`.\n * @returns The function is checking if the input `p` is a function and returning a boolean value\n * based on that check. If `p` is a function, it will return `true`, indicating that `p` is a\n * predicate function for a binary tree node. If `p` is not a function, it will return `false`.\n */\n protected _isPredicated(p: any): p is BTNPredicate<NODE> {\n return typeof p === 'function';\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n BSTNested,\n BSTNKeyOrNode,\n BSTNodeNested,\n BSTOptions,\n BTNCallback,\n BTNEntry,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n BTNPureKeyOrNodeOrEntry,\n Comparator,\n CP,\n DFSOrderPattern,\n IterationType,\n OptBSTN\n} from '../../types';\nimport { BinaryTree, BinaryTreeNode } from './binary-tree';\nimport { IBinaryTree } from '../../interfaces';\nimport { Queue } from '../queue';\nimport { isComparable } from '../../utils';\n\nexport class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>> extends BinaryTreeNode<\n K,\n V,\n NODE\n> {\n override parent?: NODE;\n\n constructor(key: K, value?: V) {\n super(key, value);\n this.parent = undefined;\n this._left = undefined;\n this._right = undefined;\n }\n\n protected override _left?: NODE;\n\n /**\n * The function returns the value of the `_left` property.\n * @returns The `_left` property of the current object is being returned.\n */\n override get left(): OptBSTN<NODE> {\n return this._left;\n }\n\n /**\n * The function sets the left child of a node and updates the parent reference of the child.\n * @param {OptBSTN<NODE>} v - The parameter `v` is of type `OptBSTN<NODE>`. It can either be an\n * instance of the `NODE` class or `undefined`.\n */\n override set left(v: OptBSTN<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._left = v;\n }\n\n protected override _right?: NODE;\n\n /**\n * The function returns the right node of a binary tree or undefined if there is no right node.\n * @returns The method is returning the value of the `_right` property, which is of type `NODE` or\n * `undefined`.\n */\n override get right(): OptBSTN<NODE> {\n return this._right;\n }\n\n /**\n * The function sets the right child of a node and updates the parent reference of the child.\n * @param {OptBSTN<NODE>} v - The parameter `v` is of type `OptBSTN<NODE>`. It can either be a\n * `NODE` object or `undefined`.\n */\n override set right(v: OptBSTN<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._right = v;\n }\n}\n\n/**\n * 1. Node Order: Each node's left child has a lesser value, and the right child has a greater value.\n * 2. Unique Keys: No duplicate keys in a standard BST.\n * 3. Efficient Search: Enables quick search, minimum, and maximum operations.\n * 4. Inorder Traversal: Yields nodes in ascending order.\n * 5. Logarithmic Operations: Ideal operations like insertion, deletion, and searching are O(log n) time-efficient.\n * 6. Balance Variability: Can become unbalanced; special types maintain balance.\n * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.\n */\nexport class BST<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,\n TREE extends BST<K, V, R, NODE, TREE> = BST<K, V, R, NODE, BSTNested<K, V, R, NODE>>\n >\n extends BinaryTree<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * This is the constructor function for a Binary Search Tree class in TypeScript.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable that can contain either keys, nodes, entries, or raw elements. These elements will be\n * added to the binary search tree during the construction of the object.\n * @param [options] - An optional object that contains additional options for the Binary Search Tree.\n * It can include a comparator function that defines the order of the elements in the tree.\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: BSTOptions<K, V, R>\n ) {\n super([], options);\n\n if (options) {\n const { comparator } = options;\n if (comparator) this._comparator = comparator;\n }\n\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected override _root?: NODE = undefined;\n\n /**\n * The function returns the root node of a tree structure.\n * @returns The `_root` property of the object, which is of type `NODE` or `undefined`.\n */\n override get root(): OptBSTN<NODE> {\n return this._root;\n }\n\n /**\n * The function creates a new BSTNode with the given key and value and returns it.\n * @param {K} key - The key parameter is of type K, which represents the type of the key for the node\n * being created.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It represents the\n * value associated with the key in the node being created.\n * @returns The method is returning a new instance of the BSTNode class, casted as the NODE type.\n */\n override createNode(key: K, value?: V): NODE {\n return new BSTNode<K, V, NODE>(key, value) as NODE;\n }\n\n /**\n * The function creates a new binary search tree with the specified options.\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the\n * following properties:\n * @returns a new instance of the BST class with the provided options.\n */\n override createTree(options?: BSTOptions<K, V, R>): TREE {\n return new BST<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function overrides a method and converts a key, value pair or entry or raw element to a node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - A variable that can be of\n * type R or BTNKeyOrNodeOrEntry<K, V, NODE>. It represents either a key, a node, an entry, or a raw\n * element.\n * @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the\n * value associated with a key in a key-value pair.\n * @returns either a NODE object or undefined.\n */\n override keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V\n ): OptBSTN<NODE> {\n return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value) ?? undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n *\n * The function ensures the existence of a node in a data structure and returns it, or undefined if\n * it doesn't exist.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept a value of type `R`, which represents the key, node,\n * entry, or raw element that needs to be ensured in the tree.\n * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional\n * parameter that specifies the type of iteration to be used when ensuring a node. It has a default\n * value of `'ITERATIVE'`.\n * @returns The method is returning either the node that was ensured or `undefined` if the node could\n * not be ensured.\n */\n override ensureNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType: IterationType = this.iterationType\n ): OptBSTN<NODE> {\n return super.ensureNode(keyOrNodeOrEntryOrRaw, iterationType) ?? undefined;\n }\n\n /**\n * The function checks if the input is an instance of the BSTNode class.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `BSTNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof BSTNode;\n }\n\n /**\n * The function \"override isKey\" checks if a key is comparable based on a given comparator.\n * @param {any} key - The `key` parameter is a value that will be checked to determine if it is of\n * type `K`.\n * @returns The `override isKey(key: any): key is K` function is returning a boolean value based on\n * the result of the `isComparable` function with the condition `this.comparator !==\n * this._DEFAULT_COMPARATOR`.\n */\n override isKey(key: any): key is K {\n return isComparable(key, this.comparator !== this._DEFAULT_COMPARATOR);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `add` function in TypeScript adds a new node to a binary search tree based on the key value.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that can be associated with the\n * key in the binary search tree. If provided, it will be stored in the node along with the key.\n * @returns a boolean value.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);\n if (newNode === undefined) return false;\n\n if (this._root === undefined) {\n this._setRoot(newNode);\n this._size++;\n return true;\n }\n\n let current = this._root;\n while (current !== undefined) {\n if (this.comparator(current.key, newNode.key) === 0) {\n this._replaceNode(current, newNode);\n return true;\n } else if (this.comparator(current.key, newNode.key) > 0) {\n if (current.left === undefined) {\n current.left = newNode;\n this._size++;\n return true;\n }\n current = current.left;\n } else {\n if (current.right === undefined) {\n current.right = newNode;\n this._size++;\n return true;\n }\n current = current.right;\n }\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(k log n)\n * Space Complexity: O(k + log n)\n *\n * The `addMany` function in TypeScript adds multiple keys or nodes to a data structure and returns\n * an array indicating whether each key or node was successfully inserted.\n * @param keysOrNodesOrEntriesOrRaws - An iterable containing keys, nodes, entries, or raw\n * elements to be added to the data structure.\n * @param [values] - An optional iterable of values to be associated with the keys or nodes being\n * added. If provided, the values will be assigned to the corresponding keys or nodes in the same\n * order. If not provided, undefined will be assigned as the value for each key or node.\n * @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after\n * adding the elements. If set to true, the tree will be balanced using a binary search tree\n * algorithm. If set to false, the elements will be added without balancing the tree. The default\n * value is true.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when adding multiple keys or nodes to the binary search\n * tree. It can have two possible values:\n * @returns The function `addMany` returns an array of booleans indicating whether each element was\n * successfully inserted into the data structure.\n */\n override addMany(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>>,\n values?: Iterable<V | undefined>,\n isBalanceAdd = true,\n iterationType: IterationType = this.iterationType\n ): boolean[] {\n const inserted: boolean[] = [];\n\n let valuesIterator: Iterator<V | undefined> | undefined;\n\n if (values) {\n valuesIterator = values[Symbol.iterator]();\n }\n\n if (!isBalanceAdd) {\n for (const kve of keysOrNodesOrEntriesOrRaws) {\n const value = valuesIterator?.next().value;\n const nn = this.add(kve, value);\n inserted.push(nn);\n }\n return inserted;\n }\n\n const realBTNExemplars: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];\n\n const isRealBTNExemplar = (\n kve: BTNKeyOrNodeOrEntry<K, V, NODE> | R\n ): kve is BTNPureKeyOrNodeOrEntry<K, V, NODE> => {\n if (kve === undefined || kve === null) return false;\n return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));\n };\n\n for (const kve of keysOrNodesOrEntriesOrRaws) {\n if (isRealBTNExemplar(kve)) realBTNExemplars.push(kve);\n }\n\n let sorted: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];\n\n sorted = realBTNExemplars.sort((a, b) => {\n let keyA: K | undefined | null, keyB: K | undefined | null;\n if (this.isEntry(a)) keyA = a[0];\n else if (this.isRealNode(a)) keyA = a.key;\n else if (this._toEntryFn) {\n keyA = this._toEntryFn(a as R)[0];\n } else {\n keyA = a as K;\n }\n\n if (this.isEntry(b)) keyB = b[0];\n else if (this.isRealNode(b)) keyB = b.key;\n else if (this._toEntryFn) {\n keyB = this._toEntryFn(b as R)[0];\n } else {\n keyB = b as K;\n }\n\n if (keyA !== undefined && keyA !== null && keyB !== undefined && keyB !== null) {\n return this.comparator(keyA, keyB);\n }\n return 0;\n });\n\n const _dfs = (arr: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[]) => {\n if (arr.length === 0) return;\n\n const mid = Math.floor((arr.length - 1) / 2);\n const newNode = this.add(arr[mid]);\n inserted.push(newNode);\n _dfs(arr.slice(0, mid));\n _dfs(arr.slice(mid + 1));\n };\n\n const _iterate = () => {\n const n = sorted.length;\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const newNode = this.add(sorted[m]);\n inserted.push(newNode);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n };\n\n if (iterationType === 'RECURSIVE') {\n _dfs(sorted);\n } else {\n _iterate();\n }\n\n return inserted;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(k + log n)\n *\n * The function `getNodes` in TypeScript overrides the base class method to retrieve nodes based on a\n * given predicate and iteration type.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter in the `getNodes` method is used to filter the nodes that will be returned. It can be a\n * key, a node, an entry, or a custom predicate function that determines whether a node should be\n * included in the result.\n * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` method is a boolean flag that\n * determines whether to return only the first node that matches the predicate (`true`) or all nodes\n * that match the predicate (`false`). If `onlyOne` is set to `true`, the method will stop iterating\n * and\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getNodes` method is used to specify the starting point for traversing the tree when searching for\n * nodes that match a given predicate. It represents the root node of the subtree where the search\n * should begin. If not explicitly provided, the default value for `begin\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` method\n * specifies the type of iteration to be performed when traversing the nodes of a binary tree. It can\n * have two possible values:\n * @returns The `getNodes` method returns an array of nodes that satisfy the given predicate.\n */\n override getNodes(\n predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n onlyOne = false,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): NODE[] {\n if (predicate === undefined) return [];\n if (predicate === null) return [];\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const callback = this._ensurePredicate(predicate);\n const ans: NODE[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return;\n }\n\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;\n if (this.isKey(predicate)) {\n if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) dfs(cur.left);\n if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) dfs(cur.right);\n } else {\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n }\n };\n\n dfs(beginRoot);\n } else {\n const stack = [beginRoot];\n while (stack.length > 0) {\n const cur = stack.pop()!;\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n if (this.isKey(predicate)) {\n if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) stack.push(cur.right);\n if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) stack.push(cur.left);\n } else {\n if (this.isRealNode(cur.right)) stack.push(cur.right);\n if (this.isRealNode(cur.left)) stack.push(cur.left);\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * This function retrieves a node based on a given predicate within a binary search tree structure.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>`, `R`, or `BTNPredicate<NODE>`.\n * @param {R | BSTNKeyOrNode<K, NODE>} beginRoot - The `beginRoot` parameter in the `getNode` method\n * is used to specify the starting point for searching nodes in the binary search tree. If no\n * specific starting point is provided, the default value is set to `this._root`, which is the root\n * node of the binary search tree.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is a\n * parameter that specifies the type of iteration to be used. It has a default value of\n * `this.iterationType`, which means it will use the iteration type defined in the class instance if\n * no value is provided when calling the method.\n * @returns The `getNode` method is returning an optional binary search tree node (`OptBSTN<NODE>`).\n * It is using the `getNodes` method to find the node based on the provided predicate, beginning at\n * the specified root node (`beginRoot`) and using the specified iteration type. The method then\n * returns the first node found or `undefined` if no node is found.\n */\n override getNode(\n predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: R | BSTNKeyOrNode<K, NODE> = this._root,\n iterationType: IterationType = this.iterationType\n ): OptBSTN<NODE> {\n return this.getNodes(predicate, true, beginRoot, iterationType)[0] ?? undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getNodeByKey` returns a node with a specific key from a tree data structure.\n * @param {K} key - The key parameter is the value used to search for a specific node in the tree. It\n * is typically a unique identifier or a value that can be used to determine the position of the node\n * in the tree structure.\n * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional\n * parameter that specifies the type of iteration to be used when searching for a node in the tree.\n * It has a default value of `'ITERATIVE'`.\n * @returns The method is returning a NODE object or undefined.\n */\n override getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptBSTN<NODE> {\n return this.getNode(key, this._root, iterationType);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the depth-first search method and returns an array of the return types of\n * the callback function.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * during the depth-first search traversal. It is an optional parameter and defaults to\n * `this._DEFAULT_BTN_CALLBACK`. The type `C` represents the type of the callback function.\n * @param {DFSOrderPattern} [pattern=IN] - The \"pattern\" parameter in the code snippet refers to the\n * order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can\n * take one of the following values:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for the depth-first search traversal. It can be either a root node, a key-value pair, or a\n * node entry. If not specified, the default value is the root of the tree.\n * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the\n * type of iteration to be used during the Depth-First Search (DFS) traversal. It can have one of the\n * following values:\n * @returns The method is returning an array of the return type of the callback function.\n */\n override dfs<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n return super.dfs(callback, pattern, beginRoot, iterationType);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the breadth-first search method and returns an array of the return types of\n * the callback function.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * visited during the breadth-first search. It should take a single argument, which is the current\n * node being visited, and it can return a value of any type.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for the breadth-first search. It can be either a root node, a key-value pair, or an entry\n * object. If no value is provided, the default value is the root of the tree.\n * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type\n * of iteration to be performed during the breadth-first search (BFS) traversal. It can have one of\n * the following values:\n * @returns an array of the return type of the callback function.\n */\n override bfs<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n return super.bfs(callback, beginRoot, iterationType, false);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the listLevels method from the superclass and returns an array of arrays\n * containing the results of the callback function applied to each level of the tree.\n * @param {C} callback - The `callback` parameter is a generic type `C` that extends\n * `BTNCallback<NODE>`. It represents a callback function that will be called for each node in the\n * tree during the iteration process.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for listing the levels of the binary tree. It can be either a root node of the tree, a\n * key-value pair representing a node in the tree, or a key representing a node in the tree. If no\n * value is provided, the root of\n * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type\n * of iteration to be performed on the tree. It can have one of the following values:\n * @returns The method is returning a two-dimensional array of the return type of the callback\n * function.\n */\n override listLevels<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[][] {\n return super.listLevels(callback, beginRoot, iterationType, false);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `lesserOrGreaterTraverse` function traverses a binary tree and applies a callback function to\n * each node that meets a certain condition based on a target node and a comparison value.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * that meets the condition specified by the `lesserOrGreater` parameter. It takes a single argument,\n * which is the current node being traversed, and returns a value of any type.\n * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to\n * traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,\n * 0, or 1, where:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} targetNode - The `targetNode` parameter is the node in\n * the binary tree that you want to start traversing from. It can be specified either by providing\n * the key of the node, the node itself, or an entry containing the key and value of the node. If no\n * `targetNode` is provided,\n * @param {IterationType} iterationType - The `iterationType` parameter determines the type of\n * traversal to be performed on the binary tree. It can have two possible values:\n * @returns The function `lesserOrGreaterTraverse` returns an array of values of type\n * `ReturnType<C>`, which is the return type of the callback function passed as an argument.\n */\n lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n lesserOrGreater: CP = -1,\n targetNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n const targetNodeEnsured = this.ensureNode(targetNode);\n const ans: ReturnType<BTNCallback<NODE>>[] = [];\n if (!this._root) return ans;\n if (!targetNodeEnsured) return ans;\n\n const targetKey = targetNodeEnsured.key;\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n const compared = this.comparator(cur.key, targetKey);\n if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));\n\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n };\n\n dfs(this._root);\n return ans;\n } else {\n const queue = new Queue<NODE>([this._root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (this.isRealNode(cur)) {\n const compared = this.comparator(cur.key, targetKey);\n if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));\n\n if (this.isRealNode(cur.left)) queue.push(cur.left);\n if (this.isRealNode(cur.right)) queue.push(cur.right);\n }\n }\n return ans;\n }\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `perfectlyBalance` function takes an optional `iterationType` parameter and returns `true` if\n * the binary search tree is perfectly balanced, otherwise it returns `false`.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when building a balanced binary search tree. It has a\n * default value of `this.iterationType`, which means it will use the iteration type specified in the\n * current instance of the class.\n * @returns The function `perfectlyBalance` returns a boolean value.\n */\n perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {\n const sorted = this.dfs(node => node, 'IN'),\n n = sorted.length;\n this.clear();\n\n if (sorted.length < 1) return false;\n if (iterationType === 'RECURSIVE') {\n const buildBalanceBST = (l: number, r: number) => {\n if (l > r) return;\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add([midNode.key, midNode.value]);\n buildBalanceBST(l, m - 1);\n buildBalanceBST(m + 1, r);\n };\n\n buildBalanceBST(0, n - 1);\n return true;\n } else {\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add([midNode.key, midNode.value]);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n return true;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `isAVLBalanced` checks if a binary tree is AVL balanced using either a recursive or\n * iterative approach.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when checking if the AVL tree is balanced. It has a default\n * value of `this.iterationType`, which means it will use the iteration type specified in the current\n * instance of the AVL tree.\n * @returns a boolean value.\n */\n isAVLBalanced(iterationType: IterationType = this.iterationType): boolean {\n if (!this._root) return true;\n\n let balanced = true;\n\n if (iterationType === 'RECURSIVE') {\n const _height = (cur: OptBSTN<NODE>): number => {\n if (!cur) return 0;\n const leftHeight = _height(cur.left),\n rightHeight = _height(cur.right);\n if (Math.abs(leftHeight - rightHeight) > 1) balanced = false;\n return Math.max(leftHeight, rightHeight) + 1;\n };\n _height(this._root);\n } else {\n const stack: NODE[] = [];\n let node: OptBSTN<NODE> = this._root,\n last: OptBSTN<NODE> = undefined;\n const depths: Map<NODE, number> = new Map();\n\n while (stack.length > 0 || node) {\n if (node) {\n stack.push(node);\n node = node.left;\n } else {\n node = stack[stack.length - 1];\n if (!node.right || last === node.right) {\n node = stack.pop();\n if (node) {\n const left = node.left ? depths.get(node.left)! : -1;\n const right = node.right ? depths.get(node.right)! : -1;\n if (Math.abs(left - right) > 1) return false;\n depths.set(node, 1 + Math.max(left, right));\n last = node;\n node = undefined;\n }\n } else node = node.right;\n }\n }\n }\n\n return balanced;\n }\n\n protected _DEFAULT_COMPARATOR = (a: K, b: K): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a > b) return 1;\n if (a < b) return -1;\n return 0;\n };\n\n protected _comparator: Comparator<K> = this._DEFAULT_COMPARATOR;\n\n /**\n * The function returns the value of the _comparator property.\n * @returns The `_comparator` property is being returned.\n */\n get comparator() {\n return this._comparator;\n }\n\n /**\n * The function sets the root of a tree-like structure and updates the parent property of the new\n * root.\n * @param {OptBSTN<NODE>} v - v is a parameter of type NODE or undefined.\n */\n protected override _setRoot(v: OptBSTN<NODE>) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport { getMSB } from '../../utils';\n\nexport class BinaryIndexedTree {\n protected readonly _freq: number;\n protected readonly _max: number;\n\n /**\n * The constructor initializes the properties of an object, including default frequency, maximum\n * value, a freqMap data structure, the most significant bit, and the count of negative frequencies.\n * @param - - `frequency`: The default frequency value. It is optional and has a default\n * value of 0.\n */\n constructor({ frequency = 0, max }: { frequency?: number; max: number }) {\n this._freq = frequency;\n this._max = max;\n this._freqMap = { 0: 0 };\n this._msb = getMSB(max);\n this._negativeCount = frequency < 0 ? max : 0;\n }\n\n protected _freqMap: Record<number, number>;\n\n /**\n * The function returns the frequency map of numbers.\n * @returns The `_freqMap` property, which is a record with number keys and number values, is being\n * returned.\n */\n get freqMap(): Record<number, number> {\n return this._freqMap;\n }\n\n protected _msb: number;\n\n /**\n * The function returns the value of the _msb property.\n * @returns The `_msb` property of the object.\n */\n get msb(): number {\n return this._msb;\n }\n\n protected _negativeCount: number;\n\n /**\n * The function returns the value of the _negativeCount property.\n * @returns The method is returning the value of the variable `_negativeCount`, which is of type\n * `number`.\n */\n get negativeCount(): number {\n return this._negativeCount;\n }\n\n /**\n * The above function returns the value of the protected variable `_freq`.\n * @returns The frequency value stored in the protected variable `_freq`.\n */\n get freq(): number {\n return this._freq;\n }\n\n /**\n * The above function returns the maximum value.\n * @returns The maximum value stored in the variable `_max`.\n */\n get max(): number {\n return this._max;\n }\n\n /**\n * The function \"readSingle\" reads a single number from a specified index.\n * @param {number} index - The `index` parameter is a number that represents the index of an element in a\n * collection or array.\n * @returns a number.\n */\n readSingle(index: number): number {\n this._checkIndex(index);\n return this._readSingle(index);\n }\n\n /**\n * The \"update\" function updates the value at a given index by adding a delta and triggers a callback\n * to notify of the change.\n * @param {number} position - The `index` parameter represents the index of the element that needs to be\n * updated in the data structure.\n * @param {number} change - The \"delta\" parameter represents the change in value that needs to be\n * applied to the frequency at the specified index.\n */\n update(position: number, change: number): void {\n this._checkIndex(position);\n const freqCur = this._readSingle(position);\n\n this._update(position, change);\n this._updateNegativeCount(freqCur, freqCur + change);\n }\n\n /**\n * The function \"writeSingle\" checks the index and writes a single value with a given frequency.\n * @param {number} index - The `index` parameter is a number that represents the index of an element. It\n * is used to identify the specific element that needs to be written.\n * @param {number} freq - The `freq` parameter represents the frequency value that needs to be\n * written.\n */\n writeSingle(index: number, freq: number): void {\n this._checkIndex(index);\n this._writeSingle(index, freq);\n }\n\n /**\n * The read function takes a count parameter, checks if it is an integer, and returns the result of\n * calling the _read function with the count parameter clamped between 0 and the maximum value.\n * @param {number} count - The `count` parameter is a number that represents the number of items to\n * read.\n * @returns a number.\n */\n read(count: number): number {\n if (!Number.isInteger(count)) {\n throw new Error('Invalid count');\n }\n return this._read(Math.max(Math.min(count, this.max), 0));\n }\n\n /**\n * The function returns the lower bound of a non-descending sequence that sums up to a given number.\n * @param {number} sum - The `sum` parameter is a number that represents the target sum that we want\n * to find in the sequence.\n * @returns The lowerBound function is returning a number.\n */\n lowerBound(sum: number): number {\n if (this.negativeCount > 0) {\n throw new Error('Sequence is not non-descending');\n }\n return this._binarySearch(sum, (x, y) => x < y);\n }\n\n /**\n * The upperBound function returns the index of the first element in a sequence that is greater than\n * or equal to a given sum.\n * @param {number} sum - The \"sum\" parameter is a number that represents the target sum that we want\n * to find in the sequence.\n * @returns The upperBound function is returning a number.\n */\n upperBound(sum: number): number {\n if (this.negativeCount > 0) {\n throw new Error('Must not be descending');\n }\n return this._binarySearch(sum, (x, y) => x <= y);\n }\n\n /**\n * The function calculates the prefix sum of an array using a binary indexed tree.\n * @param {number} i - The parameter \"i\" in the function \"getPrefixSum\" represents the index of the element in the\n * array for which we want to calculate the prefix sum.\n * @returns The function `getPrefixSum` returns the prefix sum of the elements in the binary indexed tree up to index\n * `i`.\n */\n getPrefixSum(i: number): number {\n this._checkIndex(i);\n i++; // Convert to 1-based index\n\n let sum = 0;\n while (i > 0) {\n sum += this._getFrequency(i);\n i -= i & -i;\n }\n\n return sum;\n }\n\n /**\n * The function returns the value of a specific index in a freqMap data structure, or a default value if\n * the index is not found.\n * @param {number} index - The `index` parameter is a number that represents the index of a node in a\n * freqMap data structure.\n * @returns a number.\n */\n protected _getFrequency(index: number): number {\n if (index in this.freqMap) {\n return this.freqMap[index];\n }\n\n return this.freq * (index & -index);\n }\n\n /**\n * The function _updateFrequency adds a delta value to the element at the specified index in the freqMap array.\n * @param {number} index - The index parameter is a number that represents the index of the freqMap\n * element that needs to be updated.\n * @param {number} delta - The `delta` parameter represents the change in value that needs to be\n * added to the freqMap at the specified `index`.\n */\n protected _updateFrequency(index: number, delta: number): void {\n this.freqMap[index] = this._getFrequency(index) + delta;\n }\n\n /**\n * The function checks if the given index is valid and within the range.\n * @param {number} index - The parameter \"index\" is of type number and represents the index value\n * that needs to be checked.\n */\n protected _checkIndex(index: number): void {\n if (!Number.isInteger(index)) {\n throw new Error('Invalid index: Index must be an integer.');\n }\n if (index < 0 || index >= this.max) {\n throw new Error('Index out of range: Index must be within the range [0, this.max).');\n }\n }\n\n /**\n * The function calculates the sum of elements in an array up to a given index using a binary indexed\n * freqMap.\n * @param {number} index - The `index` parameter is a number that represents the index of an element in a\n * data structure.\n * @returns a number.\n */\n protected _readSingle(index: number): number {\n index = index + 1;\n let sum = this._getFrequency(index);\n const z = index - (index & -index);\n\n index--;\n\n while (index !== z) {\n sum -= this._getFrequency(index);\n index -= index & -index;\n }\n\n return sum;\n }\n\n /**\n * The function `_updateNegativeCount` updates a counter based on changes in frequency values.\n * @param {number} freqCur - The current frequency value.\n * @param {number} freqNew - The freqNew parameter represents the new frequency value.\n */\n protected _updateNegativeCount(freqCur: number, freqNew: number): void {\n if (freqCur < 0 && freqNew >= 0) {\n this._negativeCount--;\n } else if (freqCur >= 0 && freqNew < 0) {\n this._negativeCount++;\n }\n }\n\n /**\n * The `_update` function updates the values in a binary indexed freqMap starting from a given index and\n * propagating the changes to its parent nodes.\n * @param {number} index - The `index` parameter is a number that represents the index of the element in\n * the data structure that needs to be updated.\n * @param {number} delta - The `delta` parameter represents the change in value that needs to be\n * applied to the elements in the data structure.\n */\n protected _update(index: number, delta: number): void {\n index = index + 1;\n\n while (index <= this.max) {\n this._updateFrequency(index, delta);\n index += index & -index;\n }\n }\n\n /**\n * The `_writeSingle` function updates the frequency at a specific index and triggers a callback if\n * the frequency has changed.\n * @param {number} index - The `index` parameter is a number that represents the index of the element\n * being modified or accessed.\n * @param {number} freq - The `freq` parameter represents the new frequency value that needs to be\n * written to the specified index `index`.\n */\n protected _writeSingle(index: number, freq: number): void {\n const freqCur = this._readSingle(index);\n\n this._update(index, freq - freqCur);\n this._updateNegativeCount(freqCur, freq);\n }\n\n /**\n * The `_read` function calculates the sum of values in a binary freqMap up to a given count.\n * @param {number} count - The `count` parameter is a number that represents the number of elements\n * to read from the freqMap.\n * @returns the sum of the values obtained from calling the `_getFrequency` method for each index in the\n * range from `count` to 1.\n */\n protected _read(count: number): number {\n let index = count;\n let sum = 0;\n while (index) {\n sum += this._getFrequency(index);\n index -= index & -index;\n }\n\n return sum;\n }\n\n /**\n * The function `_binarySearch` performs a binary search to find the largest number that satisfies a given\n * condition.\n * @param {number} sum - The sum parameter is a number that represents the target sum value.\n * @param before - The `before` parameter is a function that takes two numbers `x` and `y` as\n * arguments and returns a boolean value. It is used to determine if `x` is less than or equal to\n * `y`. The purpose of this function is to compare two numbers and determine their order.\n * @returns the value of the variable \"left\".\n */\n protected _binarySearch(sum: number, before: (x: number, y: number) => boolean): number {\n let left = 0;\n let right = this.msb << 1;\n let sumT = sum;\n\n while (right > left + 1) {\n const middle = (left + right) >> 1;\n const sumM = this._getFrequency(middle);\n\n if (middle <= this.max && before(sumM, sumT)) {\n sumT -= sumM;\n left = middle;\n } else {\n right = middle;\n }\n }\n return left;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type { SegmentTreeNodeVal } from '../../types';\n\nexport class SegmentTreeNode {\n /**\n * The constructor initializes the properties of a SegmentTreeNode object.\n * @param {number} start - The `start` parameter represents the starting index of the segment covered\n * by this node in a segment tree.\n * @param {number} end - The `end` parameter represents the end index of the segment covered by this\n * node in a segment tree.\n * @param {number} sum - The `sum` parameter represents the sum of the values in the range covered by\n * the segment tree node.\n * @param {SegmentTreeNodeVal | undefined} [value] - The `value` parameter is an optional parameter\n * of type `SegmentTreeNodeVal`. It represents the value associated with the segment tree node.\n */\n constructor(start: number, end: number, sum: number, value?: SegmentTreeNodeVal | undefined) {\n this._start = start;\n this._end = end;\n this._sum = sum;\n this._value = value || undefined;\n }\n\n protected _start = 0;\n\n /**\n * The function returns the value of the protected variable _start.\n * @returns The start value, which is of type number.\n */\n get start(): number {\n return this._start;\n }\n\n /**\n * The above function sets the value of the \"start\" property.\n * @param {number} value - The value parameter is of type number.\n */\n set start(value: number) {\n this._start = value;\n }\n\n protected _end = 0;\n\n /**\n * The function returns the value of the protected variable `_end`.\n * @returns The value of the protected property `_end`.\n */\n get end(): number {\n return this._end;\n }\n\n /**\n * The above function sets the value of the \"end\" property.\n * @param {number} value - The value parameter is a number that represents the new value for the end\n * property.\n */\n set end(value: number) {\n this._end = value;\n }\n\n protected _value: SegmentTreeNodeVal | undefined = undefined;\n\n /**\n * The function returns the value of a segment tree node.\n * @returns The value being returned is either a `SegmentTreeNodeVal` object or `undefined`.\n */\n get value(): SegmentTreeNodeVal | undefined {\n return this._value;\n }\n\n /**\n * The function sets the value of a segment tree node.\n * @param {SegmentTreeNodeVal | undefined} value - The `value` parameter is of type\n * `SegmentTreeNodeVal` or `undefined`.\n */\n set value(value: SegmentTreeNodeVal | undefined) {\n this._value = value;\n }\n\n protected _sum = 0;\n\n /**\n * The function returns the value of the sum property.\n * @returns The method is returning the value of the variable `_sum`.\n */\n get sum(): number {\n return this._sum;\n }\n\n /**\n * The above function sets the value of the sum property.\n * @param {number} value - The parameter \"value\" is of type \"number\".\n */\n set sum(value: number) {\n this._sum = value;\n }\n\n protected _left: SegmentTreeNode | undefined = undefined;\n\n /**\n * The function returns the left child of a segment tree node.\n * @returns The `left` property of the `SegmentTreeNode` object is being returned. It is of type\n * `SegmentTreeNode` or `undefined`.\n */\n get left(): SegmentTreeNode | undefined {\n return this._left;\n }\n\n /**\n * The function sets the value of the left property of a SegmentTreeNode object.\n * @param {SegmentTreeNode | undefined} value - The value parameter is of type SegmentTreeNode or\n * undefined.\n */\n set left(value: SegmentTreeNode | undefined) {\n this._left = value;\n }\n\n protected _right: SegmentTreeNode | undefined = undefined;\n\n /**\n * The function returns the right child of a segment tree node.\n * @returns The `getRight()` method is returning a value of type `SegmentTreeNode` or `undefined`.\n */\n get right(): SegmentTreeNode | undefined {\n return this._right;\n }\n\n /**\n * The function sets the right child of a segment tree node.\n * @param {SegmentTreeNode | undefined} value - The `value` parameter is of type `SegmentTreeNode |\n * undefined`. This means that it can accept either a `SegmentTreeNode` object or `undefined` as its\n * value.\n */\n set right(value: SegmentTreeNode | undefined) {\n this._right = value;\n }\n}\n\nexport class SegmentTree {\n /**\n * The constructor initializes the values, start, end, and root properties of an object.\n * @param {number[]} values - An array of numbers that will be used to build a binary search tree.\n * @param {number} [start] - The `start` parameter is the index of the first element in the `values` array that should\n * be included in the range. If no value is provided for `start`, it defaults to 0, which means the range starts from\n * the beginning of the array.\n * @param {number} [end] - The \"end\" parameter is the index of the last element in the \"values\" array that should be\n * included in the range. If not provided, it defaults to the index of the last element in the \"values\" array.\n */\n constructor(values: number[], start?: number, end?: number) {\n start = start || 0;\n end = end || values.length - 1;\n this._values = values;\n this._start = start;\n this._end = end;\n\n if (values.length > 0) {\n this._root = this.build(start, end);\n } else {\n this._root = undefined;\n this._values = [];\n }\n }\n\n protected _values: number[] = [];\n\n /**\n * The function returns an array of numbers.\n * @returns An array of numbers is being returned.\n */\n get values(): number[] {\n return this._values;\n }\n\n protected _start = 0;\n\n /**\n * The function returns the value of the protected variable _start.\n * @returns The start value, which is of type number.\n */\n get start(): number {\n return this._start;\n }\n\n protected _end: number;\n\n /**\n * The function returns the value of the protected variable `_end`.\n * @returns The value of the protected property `_end`.\n */\n get end(): number {\n return this._end;\n }\n\n protected _root: SegmentTreeNode | undefined;\n\n /**\n * The function returns the root node of a segment tree.\n * @returns The `root` property of the class `SegmentTreeNode` or `undefined` if it is not defined.\n */\n get root(): SegmentTreeNode | undefined {\n return this._root;\n }\n\n /**\n * The build function creates a segment tree by recursively dividing the given range into smaller segments and assigning\n * the sum of values to each segment.\n * @param {number} start - The `start` parameter represents the starting index of the segment or range for which we are\n * building the segment tree.\n * @param {number} end - The \"end\" parameter represents the ending index of the segment or range for which we want to\n * build a segment tree.\n * @returns a SegmentTreeNode object.\n */\n build(start: number, end: number): SegmentTreeNode {\n if (start > end) {\n return new SegmentTreeNode(start, end, 0);\n }\n if (start === end) return new SegmentTreeNode(start, end, this._values[start]);\n\n const mid = start + Math.floor((end - start) / 2);\n const left = this.build(start, mid);\n const right = this.build(mid + 1, end);\n const cur = new SegmentTreeNode(start, end, left.sum + right.sum);\n cur.left = left;\n cur.right = right;\n return cur;\n }\n\n /**\n * The function updates the value of a node in a segment tree and recalculates the sum of its children if they exist.\n * @param {number} index - The index parameter represents the index of the node in the segment tree that needs to be\n * updated.\n * @param {number} sum - The `sum` parameter represents the new value that should be assigned to the `sum` property of\n * the `SegmentTreeNode` at the specified `index`.\n * @param {SegmentTreeNodeVal} [value] - The `value` parameter is an optional value that can be assigned to the `value`\n * property of the `SegmentTreeNode` object. It is not currently used in the code, but you can uncomment the line `//\n * cur.value = value;` and pass a value for `value` in the\n * @returns The function does not return anything.\n */\n updateNode(index: number, sum: number, value?: SegmentTreeNodeVal) {\n const root = this.root || undefined;\n if (!root) {\n return;\n }\n const dfs = (cur: SegmentTreeNode, index: number, sum: number, value?: SegmentTreeNodeVal) => {\n if (cur.start === cur.end && cur.start === index) {\n cur.sum = sum;\n if (value !== undefined) cur.value = value;\n return;\n }\n const mid = cur.start + Math.floor((cur.end - cur.start) / 2);\n if (index <= mid) {\n if (cur.left) {\n dfs(cur.left, index, sum, value);\n }\n } else {\n if (cur.right) {\n dfs(cur.right, index, sum, value);\n }\n }\n if (cur.left && cur.right) {\n cur.sum = cur.left.sum + cur.right.sum;\n }\n };\n\n dfs(root, index, sum, value);\n }\n\n /**\n * The function `querySumByRange` calculates the sum of values within a given range in a segment tree.\n * @param {number} indexA - The starting index of the range for which you want to calculate the sum.\n * @param {number} indexB - The parameter `indexB` represents the ending index of the range for which you want to\n * calculate the sum.\n * @returns The function `querySumByRange` returns a number.\n */\n querySumByRange(indexA: number, indexB: number): number {\n const root = this.root || undefined;\n if (!root) {\n return 0;\n }\n\n if (indexA < 0 || indexB >= this.values.length || indexA > indexB) {\n return NaN;\n }\n\n const dfs = (cur: SegmentTreeNode, i: number, j: number): number => {\n if (i <= cur.start && j >= cur.end) {\n // The range [i, j] completely covers the current node's range [cur.start, cur.end]\n return cur.sum;\n }\n const mid = cur.start + Math.floor((cur.end - cur.start) / 2);\n if (j <= mid) {\n if (cur.left) {\n return dfs(cur.left, i, j);\n } else {\n return NaN;\n }\n } else if (i > mid) {\n if (cur.right) {\n return dfs(cur.right, i, j);\n } else {\n return NaN;\n }\n } else {\n // Query both left and right subtrees\n let leftSum = 0;\n let rightSum = 0;\n if (cur.left) {\n leftSum = dfs(cur.left, i, mid);\n }\n if (cur.right) {\n rightSum = dfs(cur.right, mid + 1, j);\n }\n return leftSum + rightSum;\n }\n };\n return dfs(root, indexA, indexB);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport { BST, BSTNode } from './bst';\nimport type {\n AVLTreeNested,\n AVLTreeNodeNested,\n AVLTreeOptions,\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n BTNEntry\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class AVLTreeNode<\n K = any,\n V = any,\n NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNodeNested<K, V>\n> extends BSTNode<K, V, NODE> {\n /**\n * The constructor function initializes a new instance of a class with a key and an optional value,\n * and sets the height property to 0.\n * @param {K} key - The \"key\" parameter is of type K, which represents the type of the key for the\n * constructor. It is used to initialize the key property of the object being created.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It represents the\n * value associated with the key in the constructor.\n */\n constructor(key: K, value?: V) {\n super(key, value);\n this._height = 0;\n }\n\n protected _height: number;\n\n /**\n * The function returns the value of the height property.\n * @returns The height of the object.\n */\n get height(): number {\n return this._height;\n }\n\n /**\n * The above function sets the value of the height property.\n * @param {number} value - The value parameter is a number that represents the new height value to be\n * set.\n */\n set height(value: number) {\n this._height = value;\n }\n}\n\n/**\n * 1. Height-Balanced: Each node's left and right subtrees differ in height by no more than one.\n * 2. Automatic Rebalancing: AVL trees rebalance themselves automatically during insertions and deletions.\n * 3. Rotations for Balancing: Utilizes rotations (single or double) to maintain balance after updates.\n * 4. Order Preservation: Maintains the binary search tree property where left child values are less than the parent, and right child values are greater.\n * 5. Efficient Lookups: Offers O(log n) search time, where 'n' is the number of nodes, due to its balanced nature.\n * 6. Complex Insertions and Deletions: Due to rebalancing, these operations are more complex than in a regular BST.\n * 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.\n */\nexport class AVLTree<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>,\n TREE extends AVLTree<K, V, R, NODE, TREE> = AVLTree<K, V, R, NODE, AVLTreeNested<K, V, R, NODE>>\n >\n extends BST<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * This is a constructor function for an AVLTree class that initializes the tree with keys, nodes,\n * entries, or raw elements.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable object that can contain either keys, nodes, entries, or raw elements. These elements will\n * be used to initialize the AVLTree.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the AVLTree. It can include properties such as `compareFn` (a function used to compare\n * keys), `allowDuplicates` (a boolean indicating whether duplicate keys are allowed), and\n * `nodeBuilder` (\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: AVLTreeOptions<K, V, R>\n ) {\n super([], options);\n if (keysOrNodesOrEntriesOrRaws) super.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n /**\n * The function creates a new AVL tree node with the given key and value.\n * @param {K} key - The key parameter is of type K, which represents the key of the node being\n * created.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It represents the\n * value associated with the key in the node being created.\n * @returns The method is returning a new instance of the AVLTreeNode class, casted as the generic\n * type NODE.\n */\n override createNode(key: K, value?: V): NODE {\n return new AVLTreeNode<K, V, NODE>(key, value) as NODE;\n }\n\n /**\n * The function creates a new AVL tree with the specified options and returns it.\n * @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be\n * passed to the `createTree` function. It is used to customize the behavior of the AVL tree that is\n * being created.\n * @returns a new AVLTree object.\n */\n override createTree(options?: AVLTreeOptions<K, V, R>): TREE {\n return new AVLTree<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function checks if the input is an instance of AVLTreeNode.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `AVLTreeNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof AVLTreeNode;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the add method of a class and inserts a key-value pair into a data\n * structure, then balances the path.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept values of type `R`, `BTNKeyOrNodeOrEntry<K, V, NODE>`, or\n * `RawElement`.\n * @param {V} [value] - The `value` parameter is an optional value that you want to associate with\n * the key or node being added to the data structure.\n * @returns The method is returning a boolean value.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n if (keyOrNodeOrEntryOrRaw === null) return false;\n const inserted = super.add(keyOrNodeOrEntryOrRaw, value);\n if (inserted) this._balancePath(keyOrNodeOrEntryOrRaw);\n return inserted;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the delete method in a TypeScript class, performs deletion, and then\n * balances the tree if necessary.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter in the `override delete` method can be one of the following types:\n * @returns The `delete` method is being overridden in this code snippet. It first calls the `delete`\n * method from the superclass (presumably a parent class) with the provided `predicate`, which could\n * be a key, node, entry, or a custom predicate. The result of this deletion operation is stored in\n * `deletedResults`, which is an array of `BinaryTreeDeleteResult` objects.\n */\n override delete(predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>): BinaryTreeDeleteResult<NODE>[] {\n const deletedResults = super.delete(predicate);\n for (const { needBalanced } of deletedResults) {\n if (needBalanced) {\n this._balancePath(needBalanced);\n }\n }\n return deletedResults;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_swapProperties` function swaps the key, value, and height properties between two nodes in a\n * binary search tree.\n * @param {R | BSTNKeyOrNode<K, NODE>} srcNode - The `srcNode` parameter represents either a node\n * object (`NODE`) or a key-value pair (`R`) that is being swapped with another node.\n * @param {R | BSTNKeyOrNode<K, NODE>} destNode - The `destNode` parameter is either an instance of\n * `R` or an instance of `BSTNKeyOrNode<K, NODE>`.\n * @returns The method is returning the `destNodeEnsured` object if both `srcNodeEnsured` and\n * `destNodeEnsured` are truthy. Otherwise, it returns `undefined`.\n */\n protected override _swapProperties(\n srcNode: R | BSTNKeyOrNode<K, NODE>,\n destNode: R | BSTNKeyOrNode<K, NODE>\n ): NODE | undefined {\n const srcNodeEnsured = this.ensureNode(srcNode);\n const destNodeEnsured = this.ensureNode(destNode);\n\n if (srcNodeEnsured && destNodeEnsured) {\n const { key, value, height } = destNodeEnsured;\n const tempNode = this.createNode(key, value);\n\n if (tempNode) {\n tempNode.height = height;\n\n destNodeEnsured.key = srcNodeEnsured.key;\n destNodeEnsured.value = srcNodeEnsured.value;\n destNodeEnsured.height = srcNodeEnsured.height;\n\n srcNodeEnsured.key = tempNode.key;\n srcNodeEnsured.value = tempNode.value;\n srcNodeEnsured.height = tempNode.height;\n }\n\n return destNodeEnsured;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function calculates the balance factor of a node in a binary tree.\n * @param {NODE} node - The parameter \"node\" is of type \"NODE\", which likely represents a node in a\n * binary tree data structure.\n * @returns the balance factor of a given node. The balance factor is calculated by subtracting the\n * height of the left subtree from the height of the right subtree.\n */\n protected _balanceFactor(node: NODE): number {\n if (!node.right)\n // node has no right subtree\n return -node.height;\n else if (!node.left)\n // node has no left subtree\n return +node.height;\n else return node.right.height - node.left.height;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function updates the height of a node in a binary tree based on the heights of its left and\n * right children.\n * @param {NODE} node - The parameter \"node\" represents a node in a binary tree data structure.\n */\n protected _updateHeight(node: NODE): void {\n if (!node.left && !node.right) node.height = 0;\n else if (!node.left) {\n const rightHeight = node.right ? node.right.height : 0;\n node.height = 1 + rightHeight;\n } else if (!node.right) node.height = 1 + node.left.height;\n else node.height = 1 + Math.max(node.right.height, node.left.height);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_balanceLL` function performs a left-left rotation to balance a binary search tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceLL(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.left;\n A.parent = B;\n if (B && B.right) {\n B.right.parent = A;\n }\n if (B) B.parent = parentOfA;\n if (A === this.root) {\n if (B) this._setRoot(B);\n } else {\n if (parentOfA?.left === A) {\n parentOfA.left = B;\n } else {\n if (parentOfA) parentOfA.right = B;\n }\n }\n\n if (B) {\n A.left = B.right;\n B.right = A;\n }\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_balanceLR` function performs a left-right rotation to balance a binary tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceLR(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.left;\n let C = undefined;\n if (B) {\n C = B.right;\n }\n if (A) A.parent = C;\n if (B) B.parent = C;\n\n if (C) {\n if (C.left) {\n C.left.parent = B;\n }\n if (C.right) {\n C.right.parent = A;\n }\n C.parent = parentOfA;\n }\n\n if (A === this.root) {\n if (C) this._setRoot(C);\n } else {\n if (parentOfA) {\n if (parentOfA.left === A) {\n parentOfA.left = C;\n } else {\n parentOfA.right = C;\n }\n }\n }\n\n if (C) {\n A.left = C.right;\n if (B) B.right = C.left;\n C.left = B;\n C.right = A;\n }\n\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n if (C) this._updateHeight(C);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_balanceRR` performs a right-right rotation to balance a binary tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceRR(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.right;\n A.parent = B;\n if (B) {\n if (B.left) {\n B.left.parent = A;\n }\n B.parent = parentOfA;\n }\n\n if (A === this.root) {\n if (B) this._setRoot(B);\n } else {\n if (parentOfA) {\n if (parentOfA.left === A) {\n parentOfA.left = B;\n } else {\n parentOfA.right = B;\n }\n }\n }\n\n if (B) {\n A.right = B.left;\n B.left = A;\n }\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_balanceRL` performs a right-left rotation to balance a binary tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceRL(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.right;\n let C = undefined;\n if (B) {\n C = B.left;\n }\n\n A.parent = C;\n if (B) B.parent = C;\n\n if (C) {\n if (C.left) {\n C.left.parent = A;\n }\n if (C.right) {\n C.right.parent = B;\n }\n C.parent = parentOfA;\n }\n\n if (A === this.root) {\n if (C) this._setRoot(C);\n } else {\n if (parentOfA) {\n if (parentOfA.left === A) {\n parentOfA.left = C;\n } else {\n parentOfA.right = C;\n }\n }\n }\n\n if (C) A.right = C.left;\n if (B && C) B.left = C.right;\n if (C) C.left = A;\n if (C) C.right = B;\n\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n if (C) this._updateHeight(C);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_balancePath` function is used to update the heights of nodes and perform rotation operations\n * to restore balance in an AVL tree after inserting a node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} node - The `node` parameter can be of type `R` or\n * `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n */\n protected _balancePath(node: BTNKeyOrNodeOrEntry<K, V, NODE> | R): void {\n node = this.ensureNode(node);\n const path = this.getPathToRoot(node => node, node, false); // first O(log n) + O(log n)\n for (let i = 0; i < path.length; i++) {\n // second O(log n)\n const A = path[i];\n if (A) {\n // Update Heights: After inserting a node, backtrack from the insertion point to the root node, updating the height of each node along the way.\n this._updateHeight(A); // first O(1)\n // Check Balance: Simultaneously with height updates, check if each node violates the balance property of an AVL tree.\n // Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:\n switch (\n this._balanceFactor(A) // second O(1)\n ) {\n case -2:\n if (A && A.left) {\n if (this._balanceFactor(A.left) <= 0) {\n // second O(1)\n // Left Rotation (LL Rotation): When the inserted node is in the left subtree of the left subtree, causing an imbalance.\n this._balanceLL(A);\n } else {\n // Left-Right Rotation (LR Rotation): When the inserted node is in the right subtree of the left subtree, causing an imbalance.\n this._balanceLR(A);\n }\n }\n break;\n case +2:\n if (A && A.right) {\n if (this._balanceFactor(A.right) >= 0) {\n // Right Rotation (RR Rotation): When the inserted node is in the right subtree of the right subtree, causing an imbalance.\n this._balanceRR(A);\n } else {\n // Right-Left Rotation (RL Rotation): When the inserted node is in the left subtree of the right subtree, causing an imbalance.\n this._balanceRL(A);\n }\n }\n }\n // TODO So far, no sure if this is necessary that Recursive Repair: Once rotation operations are executed, it may cause imbalance issues at higher levels of the tree. Therefore, you need to recursively check and repair imbalance problems upwards until you reach the root node.\n }\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node and sets the height of the new node to be the\n * same as the old node.\n * @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in\n * the data structure.\n * @param {NODE} newNode - The `newNode` parameter is the new node that will replace the `oldNode` in\n * the data structure.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, with the `oldNode` and `newNode` as arguments.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.height = oldNode.height;\n\n return super._replaceNode(oldNode, newNode);\n }\n}\n","import type {\n BinaryTreeDeleteResult,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n CRUD,\n OptBSTN,\n RBTNColor,\n RBTreeOptions,\n RedBlackTreeNested,\n RedBlackTreeNodeNested,\n BTNEntry\n} from '../../types';\nimport { BST, BSTNode } from './bst';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class RedBlackTreeNode<\n K = any,\n V = any,\n NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNodeNested<K, V>\n> extends BSTNode<K, V, NODE> {\n /**\n * The constructor function initializes a Red-Black Tree Node with a key, an optional value, and a\n * color.\n * @param {K} key - The key parameter is of type K and represents the key of the node in the\n * Red-Black Tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the Red-Black Tree Node. It is not required and can be omitted when\n * creating a new instance of the Red-Black Tree Node.\n * @param {RBTNColor} color - The `color` parameter is used to specify the color of the Red-Black\n * Tree Node. It is an optional parameter with a default value of `'BLACK'`.\n */\n constructor(key: K, value?: V, color: RBTNColor = 'BLACK') {\n super(key, value);\n this._color = color;\n }\n\n protected _color: RBTNColor;\n\n /**\n * The function returns the color value of a variable.\n * @returns The color value stored in the private variable `_color`.\n */\n get color(): RBTNColor {\n return this._color;\n }\n\n /**\n * The function sets the color property to the specified value.\n * @param {RBTNColor} value - The value parameter is of type RBTNColor.\n */\n set color(value: RBTNColor) {\n this._color = value;\n }\n}\n\nexport class RedBlackTree<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,\n TREE extends RedBlackTree<K, V, R, NODE, TREE> = RedBlackTree<K, V, R, NODE, RedBlackTreeNested<K, V, R, NODE>>\n >\n extends BST<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * This is the constructor function for a Red-Black Tree data structure in TypeScript.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable object that can contain either keys, nodes, entries, or raw elements. It is used to\n * initialize the RBTree with the provided elements.\n * @param [options] - The `options` parameter is an optional object that can be passed to the\n * constructor. It is of type `RBTreeOptions<K, V, R>`. This object can contain various options for\n * configuring the behavior of the Red-Black Tree. The specific properties and their meanings would\n * depend on the implementation\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: RBTreeOptions<K, V, R>\n ) {\n super([], options);\n\n this._root = this.NIL;\n\n if (keysOrNodesOrEntriesOrRaws) {\n this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n }\n\n protected override _root: NODE | undefined;\n\n /**\n * The function returns the root node of a tree or undefined if there is no root.\n * @returns The root node of the tree structure, or undefined if there is no root node.\n */\n override get root(): NODE | undefined {\n return this._root;\n }\n\n /**\n * The function creates a new Red-Black Tree node with the specified key, value, and color.\n * @param {K} key - The key parameter represents the key value of the node being created. It is of\n * type K, which is a generic type that can be replaced with any specific type when using the\n * function.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the node. It is not required and can be omitted if you only need to\n * create a node with a key.\n * @param {RBTNColor} [color=BLACK] - The \"color\" parameter is used to specify the color of the node\n * in a Red-Black Tree. It can have two possible values: \"RED\" or \"BLACK\". By default, the color is\n * set to \"BLACK\" if not specified.\n * @returns A new instance of a RedBlackTreeNode with the specified key, value, and color is being\n * returned.\n */\n override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): NODE {\n return new RedBlackTreeNode<K, V, NODE>(key, value, color) as NODE;\n }\n\n /**\n * The function creates a new Red-Black Tree with the specified options.\n * @param [options] - The `options` parameter is an optional object that contains additional\n * configuration options for creating the Red-Black Tree. It has the following properties:\n * @returns a new instance of a RedBlackTree object.\n */\n override createTree(options?: RBTreeOptions<K, V, R>): TREE {\n return new RedBlackTree<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if the input is an instance of the RedBlackTreeNode class.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `RedBlackTreeNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof RedBlackTreeNode;\n }\n\n // /**\n // * Time Complexity: O(1)\n // * Space Complexity: O(1)\n // */\n //\n // /**\n // * Time Complexity: O(1)\n // * Space Complexity: O(1)\n // *\n // * The function `keyValueOrEntryOrRawElementToNode` takes a key, value, or entry and returns a node if it is\n // * valid, otherwise it returns undefined.\n // * @param {BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRaw - The key, value, or entry to convert.\n // * @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntryOrRaw` is a key).\n // * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.\n // */\n // override keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): NODE | undefined {\n //\n // if (keyOrNodeOrEntryOrRaw === null || keyOrNodeOrEntryOrRaw === undefined) return;\n // if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n //\n // if (this._toEntryFn) {\n // const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n // if (this.isKey(key)) return this.createNode(key, entryValue ?? value, 'RED');\n // }\n //\n // if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n // const [key, value] = keyOrNodeOrEntryOrRaw;\n // if (key === undefined || key === null) return;\n // else return this.createNode(key, value, 'RED');\n // }\n //\n // if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'RED');\n //\n // return ;\n // }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The \"clear\" function sets the root node of a data structure to a sentinel value and resets the\n * size counter to zero.\n */\n override clear() {\n super.clear();\n this._root = this.NIL;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function adds a new node to a binary search tree and returns true if the node was successfully\n * added.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that you want to associate with\n * the key in the data structure. It represents the value that you want to add or update in the data\n * structure.\n * @returns The method is returning a boolean value. If a new node is successfully added to the tree,\n * the method returns true. If the node already exists and its value is updated, the method also\n * returns true. If the node cannot be added or updated, the method returns false.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);\n if (!this.isRealNode(newNode)) return false;\n\n const insertStatus = this._insert(newNode);\n\n if (insertStatus === 'CREATED') {\n // Ensure the root is black\n if (this.isRealNode(this._root)) {\n this._root.color = 'BLACK';\n } else {\n return false;\n }\n this._size++;\n return true;\n } else return insertStatus === 'UPDATED';\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the delete method in a binary tree data structure to remove a node based on\n * a given predicate and maintain the binary search tree properties.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter in the `override delete` method is used to specify the condition or key based on which a\n * node should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate\n * function that determines which node(s) should be deleted.\n * @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<NODE>`\n * objects. Each object in the array contains information about the deleted node and whether\n * balancing is needed.\n */\n override delete(predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>): BinaryTreeDeleteResult<NODE>[] {\n if (predicate === null) return [];\n\n const results: BinaryTreeDeleteResult<NODE>[] = [];\n let nodeToDelete: OptBSTN<NODE>;\n if (this._isPredicated(predicate)) nodeToDelete = this.getNode(predicate);\n else nodeToDelete = this.isRealNode(predicate) ? predicate : this.getNode(predicate);\n\n if (!nodeToDelete) {\n return results;\n }\n\n let originalColor = nodeToDelete.color;\n let replacementNode: NODE | undefined;\n\n if (!this.isRealNode(nodeToDelete.left)) {\n replacementNode = nodeToDelete.right;\n this._transplant(nodeToDelete, nodeToDelete.right);\n } else if (!this.isRealNode(nodeToDelete.right)) {\n replacementNode = nodeToDelete.left;\n this._transplant(nodeToDelete, nodeToDelete.left);\n } else {\n const successor = this.getLeftMost(node => node, nodeToDelete.right);\n if (successor) {\n originalColor = successor.color;\n replacementNode = successor.right;\n\n if (successor.parent === nodeToDelete) {\n if (this.isRealNode(replacementNode)) {\n replacementNode.parent = successor;\n }\n } else {\n this._transplant(successor, successor.right);\n successor.right = nodeToDelete.right;\n if (this.isRealNode(successor.right)) {\n successor.right.parent = successor;\n }\n }\n\n this._transplant(nodeToDelete, successor);\n successor.left = nodeToDelete.left;\n if (this.isRealNode(successor.left)) {\n successor.left.parent = successor;\n }\n successor.color = nodeToDelete.color;\n }\n }\n this._size--;\n\n // If the original color was black, fix the tree\n if (originalColor === 'BLACK') {\n this._deleteFixup(replacementNode);\n }\n\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n\n return results;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function sets the root of a tree-like structure and updates the parent property of the new\n * root.\n * @param {NODE | undefined} v - v is a parameter of type NODE or undefined.\n */\n protected override _setRoot(v: NODE | undefined) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node while preserving the color of the old node.\n * @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in\n * the data structure.\n * @param {NODE} newNode - The `newNode` parameter is of type `NODE`, which represents a node in a\n * data structure.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, with the `oldNode` and `newNode` parameters.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.color = oldNode.color;\n\n return super._replaceNode(oldNode, newNode);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_insert` function inserts a node into a binary search tree and performs necessary fix-ups to\n * maintain the red-black tree properties.\n * @param {NODE} node - The `node` parameter represents the node that needs to be inserted into the\n * binary search tree.\n * @returns a string value indicating the result of the insertion operation. It can return either\n * 'UPDATED' if the node with the same key already exists and was updated, or 'CREATED' if a new node\n * was created and inserted into the tree.\n */\n protected _insert(node: NODE): CRUD {\n let current = this.root;\n let parent: NODE | undefined = undefined;\n\n while (this.isRealNode(current)) {\n parent = current;\n const compared = this.comparator(node.key, current.key);\n if (compared < 0) {\n current = current.left ?? this.NIL;\n } else if (compared > 0) {\n current = current.right ?? this.NIL;\n } else {\n this._replaceNode(current, node);\n return 'UPDATED';\n }\n }\n\n node.parent = parent;\n\n if (!parent) {\n this._setRoot(node);\n } else if (node.key < parent.key) {\n parent.left = node;\n } else {\n parent.right = node;\n }\n\n node.left = this.NIL;\n node.right = this.NIL;\n node.color = 'RED';\n\n this._insertFixup(node);\n return 'CREATED';\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_transplant` is used to replace a node `u` with another node `v` in a binary tree.\n * @param {NODE} u - The parameter \"u\" represents a node in a binary tree.\n * @param {NODE | undefined} v - The parameter `v` is of type `NODE | undefined`, which means it can\n * either be a `NODE` object or `undefined`.\n */\n protected _transplant(u: NODE, v: NODE | undefined): void {\n if (!u.parent) {\n this._setRoot(v);\n } else if (u === u.parent.left) {\n u.parent.left = v;\n } else {\n u.parent.right = v;\n }\n\n if (v) {\n v.parent = u.parent;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_insertFixup` function is used to fix the Red-Black Tree after inserting a new node.\n * @param {NODE | undefined} z - The parameter `z` represents a node in the Red-Black Tree data\n * structure. It can either be a valid node or `undefined`.\n */\n protected _insertFixup(z: NODE | undefined): void {\n // Continue fixing the tree as long as the parent of z is red\n while (z?.parent?.color === 'RED') {\n // Check if the parent of z is the left child of its parent\n if (z.parent === z.parent.parent?.left) {\n // Case 1: The uncle (y) of z is red\n const y = z.parent.parent.right;\n if (y?.color === 'RED') {\n // Set colors to restore properties of Red-Black Tree\n z.parent.color = 'BLACK';\n y.color = 'BLACK';\n z.parent.parent.color = 'RED';\n // Move up the tree to continue fixing\n z = z.parent.parent;\n } else {\n // Case 2: The uncle (y) of z is black, and z is a right child\n if (z === z.parent.right) {\n // Perform a left rotation to transform the case into Case 3\n z = z.parent;\n this._leftRotate(z);\n }\n\n // Case 3: The uncle (y) of z is black, and z is a left child\n // Adjust colors and perform a right rotation\n if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {\n z.parent.color = 'BLACK';\n z.parent.parent.color = 'RED';\n this._rightRotate(z.parent.parent);\n }\n }\n } else {\n // Symmetric case for the right child (left and right exchanged)\n // Follow the same logic as above with left and right exchanged\n const y: NODE | undefined = z?.parent?.parent?.left;\n if (y?.color === 'RED') {\n z.parent.color = 'BLACK';\n y.color = 'BLACK';\n z.parent.parent!.color = 'RED';\n z = z.parent.parent;\n } else {\n if (z === z.parent.left) {\n z = z.parent;\n this._rightRotate(z);\n }\n\n if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {\n z.parent.color = 'BLACK';\n z.parent.parent.color = 'RED';\n this._leftRotate(z.parent.parent);\n }\n }\n }\n }\n\n // Ensure that the root is black after fixing\n if (this.isRealNode(this._root)) this._root.color = 'BLACK';\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_deleteFixup` function is used to fix the red-black tree after a node deletion by adjusting\n * the colors and performing rotations.\n * @param {NODE | undefined} node - The `node` parameter represents a node in a binary tree. It can\n * be either a valid node object or `undefined`.\n * @returns The function does not return any value. It has a return type of `void`, which means it\n * does not return anything.\n */\n protected _deleteFixup(node: NODE | undefined): void {\n // Early exit condition\n if (!node || node === this.root || node.color === 'BLACK') {\n if (node) {\n node.color = 'BLACK'; // Ensure the final node is black\n }\n return;\n }\n\n while (node && node !== this.root && node.color === 'BLACK') {\n const parent: NODE | undefined = node.parent;\n\n if (!parent) {\n break; // Ensure the loop terminates if there's an issue with the tree structure\n }\n\n if (node === parent.left) {\n let sibling = parent.right;\n\n // Cases 1 and 2: Sibling is red or both children of sibling are black\n if (sibling?.color === 'RED') {\n sibling.color = 'BLACK';\n parent.color = 'RED';\n this._leftRotate(parent);\n sibling = parent.right;\n }\n\n // Case 3: Sibling's left child is black\n if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {\n if (sibling) sibling.color = 'RED';\n node = parent;\n } else {\n // Case 4: Adjust colors and perform a right rotation\n if (sibling?.left) sibling.left.color = 'BLACK';\n if (sibling) sibling.color = parent.color;\n parent.color = 'BLACK';\n this._rightRotate(parent);\n node = this.root;\n }\n } else {\n // Symmetric case for the right child (left and right exchanged)\n let sibling = parent.left;\n\n // Cases 1 and 2: Sibling is red or both children of sibling are black\n if (sibling?.color === 'RED') {\n sibling.color = 'BLACK';\n if (parent) parent.color = 'RED';\n this._rightRotate(parent);\n if (parent) sibling = parent.left;\n }\n\n // Case 3: Sibling's left child is black\n if ((sibling?.right?.color ?? 'BLACK') === 'BLACK') {\n if (sibling) sibling.color = 'RED';\n node = parent;\n } else {\n // Case 4: Adjust colors and perform a left rotation\n if (sibling?.right) sibling.right.color = 'BLACK';\n if (sibling) sibling.color = parent.color;\n if (parent) parent.color = 'BLACK';\n this._leftRotate(parent);\n node = this.root;\n }\n }\n }\n\n // Ensure that the final node (possibly the root) is black\n if (node) {\n node.color = 'BLACK';\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_leftRotate` function performs a left rotation on a given node in a binary tree.\n * @param {NODE | undefined} x - The parameter `x` is of type `NODE | undefined`. It represents a\n * node in a binary tree or `undefined` if there is no node.\n * @returns void, which means it does not return any value.\n */\n protected _leftRotate(x: NODE | undefined): void {\n if (!x || !x.right) {\n return;\n }\n\n const y = x.right;\n x.right = y.left;\n\n if (this.isRealNode(y.left)) {\n y.left.parent = x;\n }\n\n y.parent = x.parent;\n\n if (!x.parent) {\n this._setRoot(y);\n } else if (x === x.parent.left) {\n x.parent.left = y;\n } else {\n x.parent.right = y;\n }\n\n y.left = x;\n x.parent = y;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_rightRotate` function performs a right rotation on a given node in a binary tree.\n * @param {NODE | undefined} y - The parameter `y` is of type `NODE | undefined`. It represents a\n * node in a binary tree or `undefined` if there is no node.\n * @returns void, which means it does not return any value.\n */\n protected _rightRotate(y: NODE | undefined): void {\n if (!y || !y.left) {\n return;\n }\n\n const x = y.left;\n y.left = x.right;\n\n if (this.isRealNode(x.right)) {\n x.right.parent = y;\n }\n\n x.parent = y.parent;\n\n if (!y.parent) {\n this._setRoot(x);\n } else if (y === y.parent.left) {\n y.parent.left = x;\n } else {\n y.parent.right = x;\n }\n\n x.right = y;\n y.parent = x;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n AVLTreeMultiMapNested,\n AVLTreeMultiMapNodeNested,\n AVLTreeMultiMapOptions,\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n IterationType,\n BTNEntry\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { AVLTree, AVLTreeNode } from './avl-tree';\n\nexport class AVLTreeMultiMapNode<\n K = any,\n V = any,\n NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNodeNested<K, V>\n> extends AVLTreeNode<K, V, NODE> {\n /**\n * The constructor function initializes a BinaryTreeNode object with a key, value, and count.\n * @param {K} key - The `key` parameter is of type `K` and represents the unique identifier\n * of the binary tree node.\n * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the value of the binary\n * tree node. If no value is provided, it will be `undefined`.\n * @param {number} [count=1] - The `count` parameter is a number that represents the number of times a particular value\n * occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`\n * parameter when creating a new instance of the `BinaryTreeNode` class.\n */\n constructor(key: K, value?: V, count = 1) {\n super(key, value);\n this.count = count;\n }\n\n protected _count: number = 1;\n\n /**\n * The function returns the value of the protected variable _count.\n * @returns The count property of the object, which is of type number.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * The above function sets the value of the count property.\n * @param {number} value - The value parameter is of type number, which means it can accept any\n * numeric value.\n */\n set count(value: number) {\n this._count = value;\n }\n}\n\n/**\n * The only distinction between a AVLTreeMultiMap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.\n */\nexport class AVLTreeMultiMap<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNodeNested<K, V>>,\n TREE extends AVLTreeMultiMap<K, V, R, NODE, TREE> = AVLTreeMultiMap<\n K,\n V,\n R,\n NODE,\n AVLTreeMultiMapNested<K, V, R, NODE>\n >\n >\n extends AVLTree<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * The constructor initializes a new AVLTreeMultiMap object with optional initial elements.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable object that can contain either keys, nodes, entries, or raw elements.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the AVLTreeMultiMap. It can include properties such as `compareKeys` and\n * `compareValues` functions to define custom comparison logic for keys and values, respectively.\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: AVLTreeMultiMapOptions<K, V, R>\n ) {\n super([], options);\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected _count = 0;\n\n /**\n * The function calculates the sum of the count property of all nodes in a tree using depth-first\n * search.\n * @returns the sum of the count property of all nodes in the tree.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function calculates the sum of the count property of all nodes in a tree using depth-first\n * search.\n * @returns the sum of the count property of all nodes in the tree.\n */\n getComputedCount(): number {\n let sum = 0;\n this.dfs(node => (sum += node.count));\n return sum;\n }\n\n /**\n * The function creates a new AVLTreeMultiMapNode with the specified key, value, and count.\n * @param {K} key - The key parameter represents the key of the node being created. It is of type K,\n * which is a generic type that can be replaced with any specific type when using the function.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the node. It is of type `V`, which can be any data type.\n * @param {number} [count] - The `count` parameter represents the number of occurrences of a\n * key-value pair in the AVLTreeMultiMapNode. It is an optional parameter, so it can be omitted when\n * calling the `createNode` method. If provided, it specifies the initial count for the node.\n * @returns a new instance of the AVLTreeMultiMapNode class, casted as NODE.\n */\n override createNode(key: K, value?: V, count?: number): NODE {\n return new AVLTreeMultiMapNode(key, value, count) as NODE;\n }\n\n /**\n * The function creates a new AVLTreeMultiMap object with the specified options and returns it.\n * @param [options] - The `options` parameter is an optional object that contains additional\n * configuration options for creating the AVLTreeMultiMap. It can have the following properties:\n * @returns a new instance of the AVLTreeMultiMap class, with the specified options, as a TREE\n * object.\n */\n override createTree(options?: AVLTreeMultiMapOptions<K, V, R>): TREE {\n return new AVLTreeMultiMap<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function checks if the input is an instance of AVLTreeMultiMapNode.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `AVLTreeMultiMapNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof AVLTreeMultiMapNode;\n }\n\n /**\n * The function `keyValueOrEntryOrRawElementToNode` converts a key, value, entry, or raw element into\n * a node object.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyOrNodeOrEntryOrRaw` parameter can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `override` function. It represents the value associated with the key in the data structure. If no\n * value is provided, it will default to `undefined`.\n * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of\n * times the key-value pair should be added to the data structure. If not provided, it defaults to 1.\n * @returns either a NODE object or undefined.\n */\n override keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V,\n count = 1\n ): NODE | undefined {\n if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return;\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const [key, entryValue] = keyOrNodeOrEntryOrRaw;\n if (key === undefined || key === null) return;\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count);\n }\n\n if (this._toEntryFn) {\n const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count);\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, count);\n\n return;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the add method of a TypeScript class to add a new node to a data structure\n * and update the count.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyOrNodeOrEntryOrRaw` parameter can accept a value of type `R`, which can be any type. It\n * can also accept a value of type `BTNKeyOrNodeOrEntry<K, V, NODE>`, which represents a key, node,\n * entry, or raw element\n * @param {V} [value] - The `value` parameter represents the value associated with the key in the\n * data structure. It is an optional parameter, so it can be omitted if not needed.\n * @param [count=1] - The `count` parameter represents the number of times the key-value pair should\n * be added to the data structure. By default, it is set to 1, meaning that the key-value pair will\n * be added once. However, you can specify a different value for `count` if you want to add\n * @returns a boolean value.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V, count = 1): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count);\n if (newNode === undefined) return false;\n\n const orgNodeCount = newNode?.count || 0;\n const inserted = super.add(newNode);\n if (inserted) {\n this._count += orgNodeCount;\n }\n return true;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the delete method in a binary tree data structure, handling deletion of\n * nodes and maintaining balance in the tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter in the `delete` method is used to specify the condition for deleting a node from the\n * binary tree. It can be a key, node, entry, or a custom predicate function that determines which\n * node(s) should be deleted.\n * @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a\n * boolean flag that determines whether to ignore the count of the node being deleted. If\n * `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If\n * `ignoreCount` is set to\n * @returns The `delete` method overrides the default delete behavior in a binary tree data\n * structure. It takes a predicate or node to be deleted and an optional flag to ignore count. The\n * method returns an array of `BinaryTreeDeleteResult` objects, each containing information about the\n * deleted node and whether balancing is needed in the tree.\n */\n override delete(\n predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n ignoreCount = false\n ): BinaryTreeDeleteResult<NODE>[] {\n const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];\n if (!this.root) return deletedResult;\n\n const curr: NODE | undefined = this.getNode(predicate) ?? undefined;\n if (!curr) return deletedResult;\n\n const parent: NODE | undefined = curr?.parent ? curr.parent : undefined;\n let needBalanced: NODE | undefined = undefined,\n orgCurrent: NODE | undefined = curr;\n\n if (curr.count > 1 && !ignoreCount) {\n curr.count--;\n this._count--;\n } else {\n if (!curr.left) {\n if (!parent) {\n if (curr.right !== undefined) this._setRoot(curr.right);\n } else {\n const { familyPosition: fp } = curr;\n if (fp === 'LEFT' || fp === 'ROOT_LEFT') {\n parent.left = curr.right;\n } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {\n parent.right = curr.right;\n }\n needBalanced = parent;\n }\n } else {\n const leftSubTreeRightMost = curr.left ? this.getRightMost(node => node, curr.left) : undefined;\n if (leftSubTreeRightMost) {\n const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;\n orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);\n if (parentOfLeftSubTreeMax) {\n if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {\n parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;\n } else {\n parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;\n }\n needBalanced = parentOfLeftSubTreeMax;\n }\n }\n }\n this._size = this._size - 1;\n // TODO How to handle when the count of target node is lesser than current node's count\n if (orgCurrent) this._count -= orgCurrent.count;\n }\n\n deletedResult.push({ deleted: orgCurrent, needBalanced });\n\n if (needBalanced) {\n this._balancePath(needBalanced);\n }\n\n return deletedResult;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The \"clear\" function overrides the parent class's \"clear\" function and also resets the count to\n * zero.\n */\n override clear() {\n super.clear();\n this._count = 0;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(log n)\n * The `perfectlyBalance` function takes a sorted array of nodes and builds a balanced binary search\n * tree using either a recursive or iterative approach.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when building the balanced binary search tree. It has a\n * default value of `this.iterationType`, which means it will use the iteration type currently set in\n * the object.\n * @returns The function `perfectlyBalance` returns a boolean value. It returns `true` if the\n * balancing operation is successful, and `false` if there are no nodes to balance.\n */\n override perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {\n const sorted = this.dfs(node => node, 'IN'),\n n = sorted.length;\n if (sorted.length < 1) return false;\n\n this.clear();\n\n if (iterationType === 'RECURSIVE') {\n const buildBalanceBST = (l: number, r: number) => {\n if (l > r) return;\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n buildBalanceBST(l, m - 1);\n buildBalanceBST(m + 1, r);\n };\n\n buildBalanceBST(0, n - 1);\n return true;\n } else {\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n return true;\n }\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the clone method to create a deep copy of a tree object.\n * @returns The `clone()` method is returning a cloned instance of the `TREE` object.\n */\n override clone(): TREE {\n const cloned = this.createTree();\n this.bfs(node => cloned.add(node.key, node.value, node.count));\n return cloned;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_swapProperties` function swaps the properties (key, value, count, height) between two nodes\n * in a binary search tree.\n * @param {R | BSTNKeyOrNode<K, NODE>} srcNode - The `srcNode` parameter represents the source node\n * that will be swapped with the `destNode`.\n * @param {R | BSTNKeyOrNode<K, NODE>} destNode - The `destNode` parameter represents the destination\n * node where the properties will be swapped with the source node.\n * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.\n * If either `srcNode` or `destNode` is undefined, it returns `undefined`.\n */\n protected override _swapProperties(\n srcNode: R | BSTNKeyOrNode<K, NODE>,\n destNode: R | BSTNKeyOrNode<K, NODE>\n ): NODE | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n if (srcNode && destNode) {\n const { key, value, count, height } = destNode;\n const tempNode = this.createNode(key, value, count);\n if (tempNode) {\n tempNode.height = height;\n\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n destNode.count = srcNode.count;\n destNode.height = srcNode.height;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n srcNode.count = tempNode.count;\n srcNode.height = tempNode.height;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node and updates the count property of the new node.\n * @param {NODE} oldNode - The oldNode parameter represents the node that needs to be replaced in the\n * data structure. It is of type NODE.\n * @param {NODE} newNode - The `newNode` parameter is an instance of the `NODE` class.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, which is of type `NODE`.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.count = oldNode.count + newNode.count;\n return super._replaceNode(oldNode, newNode);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n IterationType,\n OptBSTN,\n RBTNColor,\n TreeMultiMapNested,\n TreeMultiMapNodeNested,\n TreeMultiMapOptions,\n BTNEntry\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { RedBlackTree, RedBlackTreeNode } from './rb-tree';\n\nexport class TreeMultiMapNode<\n K = any,\n V = any,\n NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNodeNested<K, V>\n> extends RedBlackTreeNode<K, V, NODE> {\n /**\n * The constructor function initializes a Red-Black Tree node with a key, value, count, and color.\n * @param {K} key - The key parameter represents the key of the node in the Red-Black Tree. It is\n * used to identify and locate the node within the tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the Red-Black Tree node. It is not required and can be omitted when\n * creating a new node.\n * @param [count=1] - The `count` parameter represents the number of occurrences of a particular key\n * in the Red-Black Tree. It is an optional parameter with a default value of 1.\n * @param {RBTNColor} [color=BLACK] - The `color` parameter is used to specify the color of the node\n * in a Red-Black Tree. It is optional and has a default value of `'BLACK'`.\n */\n constructor(key: K, value?: V, count = 1, color: RBTNColor = 'BLACK') {\n super(key, value, color);\n this.count = count;\n }\n\n protected _count: number = 1;\n\n /**\n * The function returns the value of the private variable _count.\n * @returns The count property of the object, which is of type number.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * The above function sets the value of the count property.\n * @param {number} value - The value parameter is of type number, which means it can accept any\n * numeric value.\n */\n set count(value: number) {\n this._count = value;\n }\n}\n\nexport class TreeMultiMap<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNode<K, V, TreeMultiMapNodeNested<K, V>>,\n TREE extends TreeMultiMap<K, V, R, NODE, TREE> = TreeMultiMap<K, V, R, NODE, TreeMultiMapNested<K, V, R, NODE>>\n >\n extends RedBlackTree<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * The constructor function initializes a TreeMultiMap object with optional initial data.\n * @param keysOrNodesOrEntriesOrRaws - The parameter `keysOrNodesOrEntriesOrRaws` is an\n * iterable that can contain keys, nodes, entries, or raw elements. It is used to initialize the\n * TreeMultiMap with initial data.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the `TreeMultiMap` constructor. It can include properties such as `compareKeys` and\n * `compareValues`, which are functions used to compare keys and values respectively.\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: TreeMultiMapOptions<K, V, R>\n ) {\n super([], options);\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected _count = 0;\n\n // TODO the _count is not accurate after nodes count modified\n /**\n * The function calculates the sum of the count property of all nodes in a tree structure.\n * @returns the sum of the count property of all nodes in the tree.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function calculates the sum of the count property of all nodes in a tree using depth-first\n * search.\n * @returns the sum of the count property of all nodes in the tree.\n */\n getComputedCount(): number {\n let sum = 0;\n this.dfs(node => (sum += node.count));\n return sum;\n }\n\n /**\n * The function creates a new TreeMultiMapNode with the specified key, value, color, and count.\n * @param {K} key - The key parameter represents the key of the node being created. It is of type K,\n * which is a generic type representing the type of keys in the tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the node. It is of type `V`, which can be any data type.\n * @param {RBTNColor} [color=BLACK] - The color parameter is used to specify the color of the node in\n * a Red-Black Tree. It can have two possible values: 'RED' or 'BLACK'. The default value is 'BLACK'.\n * @param {number} [count] - The `count` parameter represents the number of occurrences of a key in\n * the tree. It is an optional parameter and is used to keep track of the number of values associated\n * with a key in the tree.\n * @returns A new instance of the TreeMultiMapNode class, casted as NODE.\n */\n override createNode(key: K, value?: V, color: RBTNColor = 'BLACK', count?: number): NODE {\n return new TreeMultiMapNode(key, value, count, color) as NODE;\n }\n\n /**\n * The function creates a new instance of a TreeMultiMap with the specified options and returns it.\n * @param [options] - The `options` parameter is an optional object that contains additional\n * configuration options for creating the `TreeMultiMap`. It is of type `TreeMultiMapOptions<K, V,\n * R>`.\n * @returns a new instance of the `TreeMultiMap` class, with the provided options merged with the\n * existing `iterationType` property. The returned value is casted as `TREE`.\n */\n override createTree(options?: TreeMultiMapOptions<K, V, R>): TREE {\n return new TreeMultiMap<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function `keyValueOrEntryOrRawElementToNode` takes in a key, value, and count and returns a\n * node based on the input.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that represents the value\n * associated with the key in the node. It is used when creating a new node or updating the value of\n * an existing node.\n * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of\n * times the key-value pair should be added to the data structure. If not provided, it defaults to 1.\n * @returns either a NODE object or undefined.\n */\n override keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V,\n count = 1\n ): NODE | undefined {\n if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return;\n\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const [key, entryValue] = keyOrNodeOrEntryOrRaw;\n if (key === undefined || key === null) return;\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count);\n }\n\n if (this._toEntryFn) {\n const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count);\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'BLACK', count);\n\n return;\n }\n\n /**\n * The function checks if the input is an instance of the TreeMultiMapNode class.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `TreeMultiMapNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof TreeMultiMapNode;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the add method of a class and adds a new node to a data structure, updating\n * the count and returning a boolean indicating success.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyOrNodeOrEntryOrRaw` parameter can accept one of the following types:\n * @param {V} [value] - The `value` parameter represents the value associated with the key in the\n * data structure. It is an optional parameter, so it can be omitted if not needed.\n * @param [count=1] - The `count` parameter represents the number of times the key-value pair should\n * be added to the data structure. By default, it is set to 1, meaning that if no value is provided\n * for `count`, the key-value pair will be added once.\n * @returns The method is returning a boolean value. It returns true if the addition of the new node\n * was successful, and false otherwise.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V, count = 1): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count);\n const orgCount = newNode?.count || 0;\n const isSuccessAdded = super.add(newNode);\n\n if (isSuccessAdded) {\n this._count += orgCount;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `delete` in TypeScript overrides the deletion operation in a binary tree data\n * structure, handling cases where nodes have children and maintaining balance in the tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter in the `delete` method is used to specify the condition or key based on which a node\n * should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate\n * function.\n * @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a\n * boolean flag that determines whether to ignore the count of nodes when performing deletion. If\n * `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If\n * `ignoreCount` is `false\n * @returns The `override delete` method returns an array of `BinaryTreeDeleteResult<NODE>` objects.\n */\n override delete(\n predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n ignoreCount = false\n ): BinaryTreeDeleteResult<NODE>[] {\n if (predicate === null) return [];\n\n const results: BinaryTreeDeleteResult<NODE>[] = [];\n\n let nodeToDelete: OptBSTN<NODE>;\n if (this._isPredicated(predicate)) nodeToDelete = this.getNode(predicate);\n else nodeToDelete = this.isRealNode(predicate) ? predicate : this.getNode(predicate);\n\n if (!nodeToDelete) {\n return results;\n }\n\n let originalColor = nodeToDelete.color;\n let replacementNode: NODE | undefined;\n\n if (!this.isRealNode(nodeToDelete.left)) {\n replacementNode = nodeToDelete.right;\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(nodeToDelete, nodeToDelete.right);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n } else if (!this.isRealNode(nodeToDelete.right)) {\n replacementNode = nodeToDelete.left;\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(nodeToDelete, nodeToDelete.left);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n } else {\n const successor = this.getLeftMost(node => node, nodeToDelete.right);\n if (successor) {\n originalColor = successor.color;\n replacementNode = successor.right;\n\n if (successor.parent === nodeToDelete) {\n if (this.isRealNode(replacementNode)) {\n replacementNode.parent = successor;\n }\n } else {\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(successor, successor.right);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n successor.right = nodeToDelete.right;\n if (this.isRealNode(successor.right)) {\n successor.right.parent = successor;\n }\n }\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(nodeToDelete, successor);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n successor.left = nodeToDelete.left;\n if (this.isRealNode(successor.left)) {\n successor.left.parent = successor;\n }\n successor.color = nodeToDelete.color;\n }\n }\n this._size--;\n\n // If the original color was black, fix the tree\n if (originalColor === 'BLACK') {\n this._deleteFixup(replacementNode);\n }\n\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n\n return results;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The \"clear\" function overrides the parent class's \"clear\" function and also resets the count to\n * zero.\n */\n override clear() {\n super.clear();\n this._count = 0;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(log n)\n *\n * The `perfectlyBalance` function takes a sorted array of nodes and builds a balanced binary search\n * tree using either a recursive or iterative approach.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when building the balanced binary search tree. It has a\n * default value of `this.iterationType`, which means it will use the iteration type specified by the\n * `iterationType` property of the current object.\n * @returns The function `perfectlyBalance` returns a boolean value. It returns `true` if the\n * balancing operation is successful, and `false` if there are no nodes to balance.\n */\n override perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {\n const sorted = this.dfs(node => node, 'IN'),\n n = sorted.length;\n if (sorted.length < 1) return false;\n\n this.clear();\n\n if (iterationType === 'RECURSIVE') {\n const buildBalanceBST = (l: number, r: number) => {\n if (l > r) return;\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n buildBalanceBST(l, m - 1);\n buildBalanceBST(m + 1, r);\n };\n\n buildBalanceBST(0, n - 1);\n return true;\n } else {\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n return true;\n }\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the clone method to create a deep copy of a tree object.\n * @returns The `clone()` method is returning a cloned instance of the `TREE` object.\n */\n override clone(): TREE {\n const cloned = this.createTree();\n this.bfs(node => cloned.add(node.key, node.value, node.count));\n return cloned;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_swapProperties` function swaps the properties (key, value, count, color) between two nodes\n * in a binary search tree.\n * @param {R | BSTNKeyOrNode<K, NODE>} srcNode - The `srcNode` parameter represents the source node\n * that will be swapped with the `destNode`. It can be either an instance of the `R` class or an\n * instance of the `BSTNKeyOrNode<K, NODE>` class.\n * @param {R | BSTNKeyOrNode<K, NODE>} destNode - The `destNode` parameter represents the destination\n * node where the properties will be swapped with the source node.\n * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.\n * If either `srcNode` or `destNode` is undefined, it returns undefined.\n */\n protected override _swapProperties(\n srcNode: R | BSTNKeyOrNode<K, NODE>,\n destNode: R | BSTNKeyOrNode<K, NODE>\n ): NODE | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n if (srcNode && destNode) {\n const { key, value, count, color } = destNode;\n const tempNode = this.createNode(key, value, color, count);\n if (tempNode) {\n tempNode.color = color;\n\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n destNode.count = srcNode.count;\n destNode.color = srcNode.color;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n srcNode.count = tempNode.count;\n srcNode.color = tempNode.color;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node and updates the count property of the new node.\n * @param {NODE} oldNode - The `oldNode` parameter is the node that you want to replace in the data\n * structure.\n * @param {NODE} newNode - The `newNode` parameter is an instance of the `NODE` class.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, which is of type `NODE`.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.count = oldNode.count + newNode.count;\n return super._replaceNode(oldNode, newNode);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, PriorityQueueOptions } from '../../types';\nimport { Heap } from '../heap';\n\n/**\n * 1. Element Priority: In a PriorityQueue, elements are sorted according to their priority. Each dequeue (element removal) operation removes the element with the highest priority. The priority can be determined based on the natural ordering of the elements or through a provided comparator (Comparator).\n * 2. Heap-Based Implementation: PriorityQueue is typically implemented using a binary heap, allowing both insertion and removal operations to be completed in O(log n) time, where n is the number of elements in the queue.\n * 3. Task Scheduling: In systems where tasks need to be processed based on the urgency of tasks rather than the order of arrival.\n * 4. Dijkstra's Algorithm: In shortest path algorithms for graphs, used to select the next shortest edge to visit.\n * 5. Huffman Coding: Used to select the smallest node combination when constructing a Huffman tree.\n * 6. Kth Largest Element in a Data Stream: Used to maintain a min-heap of size K for quickly finding the Kth largest element in stream data\n */\nexport class PriorityQueue<E = any, R = any> extends Heap<E, R> {\n /**\n * The constructor initializes a priority queue with optional elements and options.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the priority queue. It is an optional parameter, and if not provided, the\n * priority queue will be initialized as empty.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the priority queue. It can contain the following properties:\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: PriorityQueueOptions<E, R>) {\n super(elements, options);\n }\n\n /**\n * The `clone` function returns a new instance of the `PriorityQueue` class with the same comparator\n * and toElementFn as the original instance.\n * @returns The method is returning a new instance of the `PriorityQueue` class with the same\n * elements and properties as the current instance.\n */\n override clone(): PriorityQueue<E, R> {\n return new PriorityQueue<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new PriorityQueue object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `PriorityQueue` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(callback: ElementCallback<E, R, boolean, PriorityQueue<E, R>>, thisArg?: any): PriorityQueue<E, R> {\n const filteredPriorityQueue = new PriorityQueue<E, R>([], {\n toElementFn: this.toElementFn,\n comparator: this.comparator\n });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredPriorityQueue.add(current);\n }\n index++;\n }\n return filteredPriorityQueue;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `PriorityQueue` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, PriorityQueue<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): PriorityQueue<EM, RM> {\n const mappedPriorityQueue: PriorityQueue<EM, RM> = new PriorityQueue<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedPriorityQueue.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedPriorityQueue;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MinPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {\n /**\n * The constructor initializes a PriorityQueue with optional elements and options, including a\n * comparator function.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the priority queue. It is optional and defaults to an empty array if not\n * provided.\n * @param options - The `options` parameter is an object that contains additional configuration\n * options for the priority queue. In this case, it has a property called `comparator,` which is a\n * function used to compare elements in the priority queue. The `comparator` function takes two\n * parameters `a` and `b`\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: PriorityQueueOptions<E, R>) {\n super(elements, options);\n }\n\n /**\n * The `clone` function returns a new instance of the `MinPriorityQueue` class with the same\n * comparator and toElementFn as the original instance.\n * @returns The method is returning a new instance of the `MinPriorityQueue` class with the same\n * properties as the current instance.\n */\n override clone(): MinPriorityQueue<E, R> {\n return new MinPriorityQueue<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MinPriorityQueue object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MinPriorityQueue` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(\n callback: ElementCallback<E, R, boolean, MinPriorityQueue<E, R>>,\n thisArg?: any\n ): MinPriorityQueue<E, R> {\n const filteredPriorityQueue = new MinPriorityQueue<E, R>([], {\n toElementFn: this.toElementFn,\n comparator: this.comparator\n });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredPriorityQueue.add(current);\n }\n index++;\n }\n return filteredPriorityQueue;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MinPriorityQueue` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MinPriorityQueue<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MinPriorityQueue<EM, RM> {\n const mappedPriorityQueue: MinPriorityQueue<EM, RM> = new MinPriorityQueue<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedPriorityQueue.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedPriorityQueue;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {\n /**\n * The constructor initializes a PriorityQueue with optional elements and options, including a\n * comparator function.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the priority queue. It is optional and defaults to an empty array if not\n * provided.\n * @param options - The `options` parameter is an object that contains additional configuration\n * options for the priority queue. In this case, it has a property called `comparator,` which is a\n * function used to compare elements in the priority queue.\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: PriorityQueueOptions<E, R>) {\n super(elements, {\n comparator: (a: E, b: E): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a < b) return 1;\n if (a > b) return -1;\n return 0;\n },\n ...options\n });\n }\n\n /**\n * The `clone` function returns a new instance of the `MaxPriorityQueue` class with the same\n * comparator and toElementFn as the current instance.\n * @returns The method is returning a new instance of the MaxPriorityQueue class with the same\n * comparator and toElementFn as the current instance.\n */\n override clone(): MaxPriorityQueue<E, R> {\n return new MaxPriorityQueue<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MaxPriorityQueue object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MaxPriorityQueue` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(\n callback: ElementCallback<E, R, boolean, MaxPriorityQueue<E, R>>,\n thisArg?: any\n ): MaxPriorityQueue<E, R> {\n const filteredPriorityQueue = new MaxPriorityQueue<E, R>([], {\n toElementFn: this.toElementFn,\n comparator: this.comparator\n });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredPriorityQueue.add(current);\n }\n index++;\n }\n return filteredPriorityQueue;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MaxPriorityQueue` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MaxPriorityQueue<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MaxPriorityQueue<EM, RM> {\n const mappedPriorityQueue = new MaxPriorityQueue<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedPriorityQueue.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedPriorityQueue;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { MatrixOptions } from '../../types';\n\nexport class Matrix {\n /**\n * The constructor function initializes a matrix object with the provided data and options, or with\n * default values if no options are provided.\n * @param {number[][]} data - A 2D array of numbers representing the data for the matrix.\n * @param [options] - The `options` parameter is an optional object that can contain the following\n * properties:\n */\n constructor(data: number[][], options?: MatrixOptions) {\n if (options) {\n const { rows, cols, addFn, subtractFn, multiplyFn } = options;\n if (typeof rows === 'number' && rows > 0) this._rows = rows;\n else this._rows = data.length;\n if (typeof cols === 'number' && cols > 0) this._cols = cols;\n else this._cols = data[0]?.length || 0;\n if (addFn) this._addFn = addFn;\n if (subtractFn) this._subtractFn = subtractFn;\n if (multiplyFn) this._multiplyFn = multiplyFn;\n } else {\n this._rows = data.length;\n this._cols = data[0]?.length ?? 0;\n }\n\n if (data.length > 0) {\n this._data = data;\n } else {\n this._data = [];\n for (let i = 0; i < this.rows; i++) {\n this._data[i] = new Array(this.cols).fill(0);\n }\n }\n }\n\n protected _rows: number = 0;\n\n /**\n * The function returns the number of rows.\n * @returns The number of rows.\n */\n get rows(): number {\n return this._rows;\n }\n\n protected _cols: number = 0;\n\n /**\n * The function returns the value of the protected variable _cols.\n * @returns The number of columns.\n */\n get cols(): number {\n return this._cols;\n }\n\n protected _data: number[][];\n\n /**\n * The function returns a two-dimensional array of numbers.\n * @returns The data property, which is a two-dimensional array of numbers.\n */\n get data(): number[][] {\n return this._data;\n }\n\n /**\n * The above function returns the value of the _addFn property.\n * @returns The value of the property `_addFn` is being returned.\n */\n get addFn() {\n return this._addFn;\n }\n\n /**\n * The function returns the value of the _subtractFn property.\n * @returns The `_subtractFn` property is being returned.\n */\n get subtractFn() {\n return this._subtractFn;\n }\n\n /**\n * The function returns the value of the _multiplyFn property.\n * @returns The `_multiplyFn` property is being returned.\n */\n get multiplyFn() {\n return this._multiplyFn;\n }\n\n /**\n * The `get` function returns the value at the specified row and column index if it is a valid index.\n * @param {number} row - The `row` parameter represents the row index of the element you want to\n * retrieve from the data array.\n * @param {number} col - The parameter \"col\" represents the column number of the element you want to\n * retrieve from the data array.\n * @returns The `get` function returns a number if the provided row and column indices are valid.\n * Otherwise, it returns `undefined`.\n */\n get(row: number, col: number): number | undefined {\n if (this.isValidIndex(row, col)) {\n return this.data[row][col];\n }\n }\n\n /**\n * The set function updates the value at a specified row and column in a two-dimensional array.\n * @param {number} row - The \"row\" parameter represents the row index of the element in a\n * two-dimensional array or matrix. It specifies the row where the value will be set.\n * @param {number} col - The \"col\" parameter represents the column index of the element in a\n * two-dimensional array.\n * @param {number} value - The value parameter represents the number that you want to set at the\n * specified row and column in the data array.\n * @returns a boolean value. It returns true if the index (row, col) is valid and the value is\n * successfully set in the data array. It returns false if the index is invalid and the value is not\n * set.\n */\n set(row: number, col: number, value: number): boolean {\n if (this.isValidIndex(row, col)) {\n this.data[row][col] = value;\n return true;\n }\n return false;\n }\n\n /**\n * The function checks if the dimensions of the given matrix match the dimensions of the current\n * matrix.\n * @param {Matrix} matrix - The parameter `matrix` is of type `Matrix`.\n * @returns a boolean value.\n */\n isMatchForCalculate(matrix: Matrix): boolean {\n return this.rows === matrix.rows && this.cols === matrix.cols;\n }\n\n /**\n * The `add` function adds two matrices together, returning a new matrix with the result.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.\n * @returns The `add` method returns a new `Matrix` object that represents the result of adding the\n * current matrix with the provided `matrix` parameter.\n */\n add(matrix: Matrix): Matrix | undefined {\n if (!this.isMatchForCalculate(matrix)) {\n throw new Error('Matrix dimensions must match for addition.');\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < this.cols; j++) {\n const a = this.get(i, j),\n b = matrix.get(i, j);\n if (a !== undefined && b !== undefined) {\n const added = this._addFn(a, b);\n if (added) {\n resultData[i][j] = added;\n }\n }\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The `subtract` function performs element-wise subtraction between two matrices and returns a new\n * matrix with the result.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class. It\n * represents the matrix that you want to subtract from the current matrix.\n * @returns a new Matrix object with the result of the subtraction operation.\n */\n subtract(matrix: Matrix): Matrix | undefined {\n if (!this.isMatchForCalculate(matrix)) {\n throw new Error('Matrix dimensions must match for subtraction.');\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < this.cols; j++) {\n const a = this.get(i, j),\n b = matrix.get(i, j);\n if (a !== undefined && b !== undefined) {\n const subtracted = this._subtractFn(a, b);\n if (subtracted) {\n resultData[i][j] = subtracted;\n }\n }\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The `multiply` function performs matrix multiplication between two matrices and returns the result\n * as a new matrix.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.\n * @returns a new Matrix object.\n */\n multiply(matrix: Matrix): Matrix | undefined {\n if (this.cols !== matrix.rows) {\n throw new Error('Matrix dimensions must be compatible for multiplication (A.cols = B.rows).');\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < matrix.cols; j++) {\n let sum: number | undefined;\n for (let k = 0; k < this.cols; k++) {\n const a = this.get(i, k),\n b = matrix.get(k, j);\n if (a !== undefined && b !== undefined) {\n const multiplied = this.multiplyFn(a, b);\n if (multiplied !== undefined) {\n sum = this.addFn(sum, multiplied);\n }\n }\n }\n if (sum !== undefined) resultData[i][j] = sum;\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: matrix.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The transpose function takes a matrix and returns a new matrix that is the transpose of the\n * original matrix.\n * @returns The transpose() function returns a new Matrix object with the transposed data.\n */\n transpose(): Matrix {\n if (this.data.some(row => row.length !== this.rows)) {\n throw new Error('Matrix must be rectangular for transposition.');\n }\n\n const resultData: number[][] = [];\n\n for (let j = 0; j < this.cols; j++) {\n resultData[j] = [];\n for (let i = 0; i < this.rows; i++) {\n const trans = this.get(i, j);\n if (trans !== undefined) resultData[j][i] = trans;\n }\n }\n\n return new Matrix(resultData, {\n rows: this.cols,\n cols: this.rows,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The `inverse` function calculates the inverse of a square matrix using Gaussian elimination.\n * @returns a Matrix object, which represents the inverse of the original matrix.\n */\n inverse(): Matrix | undefined {\n // Check if the matrix is square\n if (this.rows !== this.cols) {\n throw new Error('Matrix must be square for inversion.');\n }\n\n // Create an augmented matrix [this | I]\n const augmentedMatrixData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n augmentedMatrixData[i] = this.data[i].slice(); // Copy the original matrix\n for (let j = 0; j < this.cols; j++) {\n augmentedMatrixData[i][this.cols + j] = i === j ? 1 : 0; // Append the identity matrix\n }\n }\n\n const augmentedMatrix = new Matrix(augmentedMatrixData, {\n rows: this.rows,\n cols: this.cols * 2,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n\n // Apply Gaussian elimination to transform the left half into the identity matrix\n for (let i = 0; i < this.rows; i++) {\n // Find pivot\n let pivotRow = i;\n while (pivotRow < this.rows && augmentedMatrix.get(pivotRow, i) === 0) {\n pivotRow++;\n }\n\n if (pivotRow === this.rows) {\n // Matrix is singular, and its inverse does not exist\n throw new Error('Matrix is singular, and its inverse does not exist.');\n }\n\n // Swap rows to make the pivot the current row\n augmentedMatrix._swapRows(i, pivotRow);\n\n // Scale the pivot row to make the pivot element 1\n const pivotElement = augmentedMatrix.get(i, i) ?? 1;\n\n if (pivotElement === 0) {\n // Handle division by zero\n throw new Error('Matrix is singular, and its inverse does not exist (division by zero).');\n }\n\n augmentedMatrix._scaleRow(i, 1 / pivotElement);\n\n // Eliminate other rows to make elements in the current column zero\n for (let j = 0; j < this.rows; j++) {\n if (j !== i) {\n let factor = augmentedMatrix.get(j, i);\n if (factor === undefined) factor = 0;\n\n augmentedMatrix._addScaledRow(j, i, -factor);\n }\n }\n }\n\n // Extract the right half of the augmented matrix as the inverse\n const inverseData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n inverseData[i] = augmentedMatrix.data[i].slice(this.cols);\n }\n\n return new Matrix(inverseData, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The dot function calculates the dot product of two matrices and returns a new matrix.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.\n * @returns a new Matrix object.\n */\n dot(matrix: Matrix): Matrix | undefined {\n if (this.cols !== matrix.rows) {\n throw new Error(\n 'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.'\n );\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < matrix.cols; j++) {\n let sum: number | undefined;\n for (let k = 0; k < this.cols; k++) {\n const a = this.get(i, k),\n b = matrix.get(k, j);\n if (a !== undefined && b !== undefined) {\n const multiplied = this.multiplyFn(a, b);\n if (multiplied !== undefined) {\n sum = this.addFn(sum, multiplied);\n }\n }\n }\n if (sum !== undefined) resultData[i][j] = sum;\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: matrix.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The function checks if a given row and column index is valid within a specified range.\n * @param {number} row - The `row` parameter represents the row index of a two-dimensional array or\n * matrix. It is a number that indicates the specific row in the matrix.\n * @param {number} col - The \"col\" parameter represents the column index in a two-dimensional array\n * or grid. It is used to check if the given column index is valid within the bounds of the grid.\n * @returns A boolean value is being returned.\n */\n isValidIndex(row: number, col: number): boolean {\n return row >= 0 && row < this.rows && col >= 0 && col < this.cols;\n }\n\n /**\n * The `clone` function returns a new instance of the Matrix class with the same data and properties\n * as the original instance.\n * @returns The `clone()` method is returning a new instance of the `Matrix` class with the same data\n * and properties as the current instance.\n */\n clone(): Matrix {\n return new Matrix(this.data, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n protected _addFn(a: number | undefined, b: number): number | undefined {\n if (a === undefined) return b;\n return a + b;\n }\n\n protected _subtractFn(a: number, b: number) {\n return a - b;\n }\n\n protected _multiplyFn(a: number, b: number) {\n return a * b;\n }\n\n /**\n * The function `_swapRows` swaps the positions of two rows in an array.\n * @param {number} row1 - The `row1` parameter is the index of the first row that you want to swap.\n * @param {number} row2 - The `row2` parameter is the index of the second row that you want to swap\n * with the first row.\n */\n protected _swapRows(row1: number, row2: number): void {\n const temp = this.data[row1];\n this.data[row1] = this.data[row2];\n this.data[row2] = temp;\n }\n\n /**\n * The function scales a specific row in a matrix by a given scalar value.\n * @param {number} row - The `row` parameter represents the index of the row in the matrix that you\n * want to scale. It is a number that indicates the position of the row within the matrix.\n * @param {number} scalar - The scalar parameter is a number that is used to multiply each element in\n * a specific row of a matrix.\n */\n protected _scaleRow(row: number, scalar: number): void {\n for (let j = 0; j < this.cols; j++) {\n let multiplied = this.multiplyFn(this.data[row][j], scalar);\n if (multiplied === undefined) multiplied = 0;\n this.data[row][j] = multiplied;\n }\n }\n\n /**\n * The function `_addScaledRow` multiplies a row in a matrix by a scalar value and adds it to another\n * row.\n * @param {number} targetRow - The targetRow parameter represents the index of the row in which the\n * scaled values will be added.\n * @param {number} sourceRow - The sourceRow parameter represents the index of the row from which the\n * values will be scaled and added to the targetRow.\n * @param {number} scalar - The scalar parameter is a number that is used to scale the values in the\n * source row before adding them to the target row.\n */\n protected _addScaledRow(targetRow: number, sourceRow: number, scalar: number): void {\n for (let j = 0; j < this.cols; j++) {\n let multiplied = this.multiplyFn(this.data[sourceRow][j], scalar);\n if (multiplied === undefined) multiplied = 0;\n const scaledValue = multiplied;\n let added = this.addFn(this.data[targetRow][j], scaledValue);\n if (added === undefined) added = 0;\n this.data[targetRow][j] = added;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { Direction, NavigatorParams, Turning } from '../../types';\n\nexport class Character {\n direction: Direction;\n turn: () => Character;\n\n /**\n * The constructor function takes in a direction and turning object and sets the direction and turn properties of the\n * Character class.\n * @param {Direction} direction - The direction parameter is used to specify the current direction of the character. It\n * can be any value that represents a direction, such as \"north\", \"south\", \"east\", or \"west\".\n * @param {Turning} turning - The `turning` parameter is an object that maps each direction to the corresponding\n * turning direction. It is used to determine the new direction when the character turns.\n */\n constructor(direction: Direction, turning: Turning) {\n this.direction = direction;\n this.turn = () => new Character(turning[direction], turning);\n }\n}\n\nexport class Navigator<T = number> {\n onMove: (cur: [number, number]) => void;\n protected readonly _matrix: T[][];\n protected readonly _cur: [number, number];\n protected _character: Character;\n protected readonly _VISITED: T;\n\n /**\n * The constructor initializes the Navigator object with the given parameters and sets the current position as visited\n * in the matrix.\n * @param - - `matrix`: a 2D array representing the grid or map\n */\n constructor({ matrix, turning, onMove, init: { cur, charDir, VISITED } }: NavigatorParams<T>) {\n this._matrix = matrix;\n this._cur = cur;\n this._character = new Character(charDir, turning);\n this.onMove = onMove;\n if (this.onMove) this.onMove(this._cur);\n this._VISITED = VISITED;\n this._matrix[this._cur[0]][this._cur[1]] = this._VISITED;\n }\n\n /**\n * The \"start\" function moves the character in its current direction until it encounters an obstacle, then it turns the\n * character and repeats the process.\n */\n start() {\n while (this.check(this._character.direction) || this.check(this._character.turn().direction)) {\n const { direction } = this._character;\n if (this.check(direction)) {\n this.move(direction);\n } else if (this.check(this._character.turn().direction)) {\n this._character = this._character.turn();\n }\n }\n }\n\n /**\n * The function checks if there is a valid move in the specified direction in a matrix.\n * @param {Direction} direction - The direction parameter is a string that represents the direction in which to check.\n * It can be one of the following values: 'up', 'right', 'down', or 'left'.\n * @returns a boolean value.\n */\n check(direction: Direction) {\n let forward: T | undefined, row: T[] | undefined;\n const matrix = this._matrix;\n const [i, j] = this._cur;\n switch (direction) {\n case 'up':\n row = matrix[i - 1];\n if (!row) return false;\n forward = row[j];\n break;\n case 'right':\n forward = matrix[i][j + 1];\n break;\n case 'down':\n row = matrix[i + 1];\n if (!row) return false;\n forward = row[j];\n break;\n case 'left':\n forward = matrix[i][j - 1];\n break;\n }\n return forward !== undefined && forward !== this._VISITED;\n }\n\n /**\n * The `move` function updates the current position based on the given direction and updates the matrix accordingly.\n * @param {Direction} direction - The `direction` parameter is a string that represents the direction in which to move.\n * It can have one of the following values: 'up', 'right', 'down', or 'left'.\n */\n move(direction: Direction) {\n switch (direction) {\n case 'up':\n this._cur[0]--;\n break;\n case 'right':\n this._cur[1]++;\n break;\n case 'down':\n this._cur[0]++;\n break;\n case 'left':\n this._cur[1]--;\n break;\n }\n\n const [i, j] = this._cur;\n this._matrix[i][j] = this._VISITED;\n if (this.onMove) this.onMove(this._cur);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback, TrieOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\n/**\n * TrieNode represents a node in the Trie data structure. It holds a character key, a map of children nodes,\n * and a flag indicating whether it's the end of a word.\n */\nexport class TrieNode {\n constructor(key: string) {\n this._key = key;\n this._isEnd = false;\n this._children = new Map<string, TrieNode>();\n }\n\n protected _key: string;\n\n /**\n * The function returns the value of the protected variable _key.\n * @returns The value of the `_key` property, which is a string.\n */\n get key(): string {\n return this._key;\n }\n\n /**\n * The above function sets the value of a protected variable called \"key\".\n * @param {string} value - The value parameter is a string that represents the value to be assigned\n * to the key.\n */\n set key(value: string) {\n this._key = value;\n }\n\n protected _children: Map<string, TrieNode>;\n\n /**\n * The function returns the children of a TrieNode as a Map.\n * @returns The `children` property of the TrieNode object, which is a Map containing string keys and\n * TrieNode values.\n */\n get children(): Map<string, TrieNode> {\n return this._children;\n }\n\n /**\n * The function sets the value of the `_children` property of a TrieNode object.\n * @param value - The value parameter is a Map object that represents the children of a TrieNode. The\n * keys of the map are strings, which represent the characters that are associated with each child\n * TrieNode. The values of the map are TrieNode objects, which represent the child nodes of the\n * current TrieNode.\n */\n set children(value: Map<string, TrieNode>) {\n this._children = value;\n }\n\n protected _isEnd: boolean;\n\n /**\n * The function returns a boolean value indicating whether a certain condition is met.\n * @returns The method is returning a boolean value, specifically the value of the variable `_isEnd`.\n */\n get isEnd(): boolean {\n return this._isEnd;\n }\n\n /**\n * The function sets the value of the \"_isEnd\" property.\n * @param {boolean} value - The value parameter is a boolean value that indicates whether the current\n * state is the end state or not.\n */\n set isEnd(value: boolean) {\n this._isEnd = value;\n }\n}\n\n/**\n * 1. Node Structure: Each node in a Trie represents a string (or a part of a string). The root node typically represents an empty string.\n * 2. Child Node Relationship: Each node's children represent the strings that can be formed by adding one character to the string at the current node. For example, if a node represents the string 'ca', one of its children might represent 'cat'.\n * 3. Fast Retrieval: Trie allows retrieval in O(m) time complexity, where m is the length of the string to be searched.\n * 4. Space Efficiency: Trie can store a large number of strings very space-efficiently, especially when these strings share common prefixes.\n * 5. Autocomplete and Prediction: Trie can be used for implementing autocomplete and word prediction features, as it can quickly find all strings with a common prefix.\n * 6. Sorting: Trie can be used to sort a set of strings in alphabetical order.\n * 7. String Retrieval: For example, searching for a specific string in a large set of strings.\n * 8. Autocomplete: Providing recommended words or phrases as a user types.\n * 9. Spell Check: Checking the spelling of words.\n * 10. IP Routing: Used in certain types of IP routing algorithms.\n * 11. Text Word Frequency Count: Counting and storing the frequency of words in a large amount of text data.\n */\nexport class Trie<R = any> extends IterableElementBase<string, R, Trie<R>> {\n /**\n * The constructor function for the Trie class.\n * @param words: Iterable string Initialize the trie with a set of words\n * @param options?: TrieOptions Allow the user to pass in options for the trie\n * @return This\n */\n constructor(words: Iterable<string> | Iterable<R> = [], options?: TrieOptions<R>) {\n super(options);\n if (options) {\n const { caseSensitive } = options;\n if (caseSensitive !== undefined) this._caseSensitive = caseSensitive;\n }\n if (words) {\n for (const word of words) {\n if (this.toElementFn) {\n this.add(this.toElementFn(word as R));\n } else {\n this.add(word as string);\n }\n }\n }\n }\n\n protected _size: number = 0;\n\n /**\n * The size function returns the size of the stack.\n * @return The number of elements in the list\n */\n get size(): number {\n return this._size;\n }\n\n protected _caseSensitive: boolean = true;\n\n /**\n * The caseSensitive function is a getter that returns the value of the protected _caseSensitive property.\n * @return The value of the _caseSensitive protected variable\n */\n get caseSensitive(): boolean {\n return this._caseSensitive;\n }\n\n protected _root: TrieNode = new TrieNode('');\n\n /**\n * The root function returns the root node of the tree.\n * @return The root node\n */\n get root() {\n return this._root;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the word being added.\n * Space Complexity: O(l) - Each character in the word adds a TrieNode.\n *\n * Add a word to the Trie structure.\n * @param {string} word - The word to add.\n * @returns {boolean} True if the word was successfully added.\n */\n add(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n let isNewWord = false;\n for (const c of word) {\n let nodeC = cur.children.get(c);\n if (!nodeC) {\n nodeC = new TrieNode(c);\n cur.children.set(c, nodeC);\n }\n cur = nodeC;\n }\n if (!cur.isEnd) {\n isNewWord = true;\n cur.isEnd = true;\n this._size++;\n }\n return isNewWord;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input word.\n * Space Complexity: O(1) - Constant space.\n *\n * Check if the Trie contains a given word.\n * @param {string} word - The word to check for.\n * @returns {boolean} True if the word is present in the Trie.\n */\n override has(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n for (const c of word) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return cur.isEnd;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The isEmpty function checks if the size of the queue is 0.\n * @return True if the size of the queue is 0\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the size of the Trie to 0 and creates a new root TrieNode.\n */\n clear(): void {\n this._size = 0;\n this._root = new TrieNode('');\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the word being deleted.\n * Space Complexity: O(n) - Due to the recursive DFS approach.\n *\n * Remove a word from the Trie structure.\n * @param{string} word - The word to delete.\n * @returns {boolean} True if the word was successfully removed.\n */\n delete(word: string): boolean {\n word = this._caseProcess(word);\n let isDeleted = false;\n const dfs = (cur: TrieNode, i: number): boolean => {\n const char = word[i];\n const child = cur.children.get(char);\n if (child) {\n if (i === word.length - 1) {\n if (child.isEnd) {\n if (child.children.size > 0) {\n child.isEnd = false;\n } else {\n cur.children.delete(char);\n }\n isDeleted = true;\n return true;\n }\n return false;\n }\n const res = dfs(child, i + 1);\n if (res && !cur.isEnd && child.children.size === 0) {\n cur.children.delete(char);\n return true;\n }\n return false;\n }\n return false;\n };\n\n dfs(this.root, 0);\n if (isDeleted) {\n this._size--;\n }\n return isDeleted;\n }\n\n /**\n * Time Complexity: O(n), where n is the total number of nodes in the trie.\n * Space Complexity: O(1) - Constant space.\n *\n */\n getHeight(): number {\n const beginRoot = this.root;\n let maxDepth = 0;\n if (beginRoot) {\n const bfs = (node: TrieNode, level: number) => {\n if (level > maxDepth) {\n maxDepth = level;\n }\n const { children } = node;\n if (children) {\n for (const child of children.entries()) {\n bfs(child[1], level + 1);\n }\n }\n };\n bfs(beginRoot, 0);\n }\n return maxDepth;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n *\n * Check if a given input string has an absolute prefix in the Trie, meaning it's not a complete word.\n * @param {string} input - The input string to check.\n * @returns {boolean} True if it's an absolute prefix in the Trie.\n */\n hasPurePrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return !cur.isEnd;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n *\n * Check if a given input string is a prefix of any existing word in the Trie, whether as an absolute prefix or a complete word.\n * @param {string} input - The input string representing the prefix to check.\n * @returns {boolean} True if it's a prefix in the Trie.\n */\n hasPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n), where n is the total number of nodes in the trie.\n * Space Complexity: O(l), where l is the length of the input prefix.\n *\n * Check if the input string is a common prefix in the Trie, meaning it's a prefix shared by all words in the Trie.\n * @param {string} input - The input string representing the common prefix to check for.\n * @returns {boolean} True if it's a common prefix in the Trie.\n */\n hasCommonPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (commonPre === input) return;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre === input;\n }\n\n /**\n * Time Complexity: O(n), where n is the total number of nodes in the trie.\n * Space Complexity: O(l), where l is the length of the longest common prefix.\n *\n * Get the longest common prefix among all the words stored in the Trie.\n * @returns {string} The longest common prefix found in the Trie.\n */\n getLongestCommonPrefix(): string {\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre;\n }\n\n /**\n * Time Complexity: O(w * l), where w is the number of words retrieved, and l is the average length of the words.\n * Space Complexity: O(w * l) - The space required for the output array.\n *\n * The `getAll` function returns an array of all words in a Trie data structure that start with a given prefix.\n * @param {string} prefix - The `prefix` parameter is a string that represents the prefix that we want to search for in the\n * trie. It is an optional parameter, so if no prefix is provided, it will default to an empty string.\n * @param {number} max - The max count of words will be found\n * @param isAllWhenEmptyPrefix - If true, when the prefix provided as '', returns all the words in the trie.\n * @returns {string[]} an array of strings.\n */\n getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false): string[] {\n prefix = this._caseProcess(prefix);\n const words: string[] = [];\n let found = 0;\n\n function dfs(node: TrieNode, word: string) {\n for (const char of node.children.keys()) {\n const charNode = node.children.get(char);\n if (charNode !== undefined) {\n dfs(charNode, word.concat(char));\n }\n }\n if (node.isEnd) {\n if (found > max - 1) return;\n words.push(word);\n found++;\n }\n }\n\n let startNode = this.root;\n\n if (prefix) {\n for (const c of prefix) {\n const nodeC = startNode.children.get(c);\n if (nodeC) {\n startNode = nodeC;\n } else {\n // Early return if the whole prefix is not found\n return [];\n }\n }\n }\n\n if (isAllWhenEmptyPrefix || startNode !== this.root) dfs(startNode, prefix);\n\n return words;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function returns a new instance of the Trie class with the same values and case\n * sensitivity as the original Trie.\n * @returns A new instance of the Trie class is being returned.\n */\n clone(): Trie<R> {\n return new Trie<R>(this, { caseSensitive: this.caseSensitive, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function takes a predicate function and returns a new array containing all the\n * elements for which the predicate function returns true.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `word`, `index`, and `this`. It should return a boolean value indicating whether the current\n * element should be included in the filtered results or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the `predicate` function. It is used when you want to bind a\n * specific object as the context for the `predicate` function. If `thisArg` is provided, it will be\n * @returns The `filter` method is returning an array of strings (`string[]`).\n */\n filter(predicate: ElementCallback<string, R, boolean, Trie<R>>, thisArg?: any): Trie<R> {\n const results = new Trie<R>([], { toElementFn: this.toElementFn, caseSensitive: this.caseSensitive });\n let index = 0;\n for (const word of this) {\n if (predicate.call(thisArg, word, index, this)) {\n results.add(word);\n }\n index++;\n }\n return results;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new Trie by applying a callback function to each element in the\n * current Trie.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * Trie. It takes four arguments:\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * convert the raw element (`RM`) into a string representation. This can be useful if the raw element\n * is not already a string or if you want to customize how the element is converted into a string. If\n * this parameter is\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new Trie object.\n */\n map<RM>(\n callback: ElementCallback<string, R, string, Trie<R>>,\n toElementFn?: (rawElement: RM) => string,\n thisArg?: any\n ): Trie<RM> {\n const newTrie = new Trie<RM>([], { toElementFn, caseSensitive: this.caseSensitive });\n let index = 0;\n for (const word of this) {\n newTrie.add(callback.call(thisArg, word, index, this));\n index++;\n }\n return newTrie;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `_getIterator` returns an iterable iterator that performs a depth-first search on a\n * trie data structure and yields all the paths to the end nodes.\n */\n protected *_getIterator(): IterableIterator<string> {\n function* _dfs(node: TrieNode, path: string): IterableIterator<string> {\n if (node.isEnd) {\n yield path;\n }\n for (const [char, childNode] of node.children) {\n yield* _dfs(childNode, path + char);\n }\n }\n\n yield* _dfs(this.root, '');\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input string.\n * Space Complexity: O(1) - Constant space.\n *\n * @param str\n * @protected\n */\n protected _caseProcess(str: string) {\n if (!this._caseSensitive) {\n str = str.toLowerCase(); // Convert str to lowercase if case-insensitive\n }\n return str;\n }\n}\n","export class TreeNode<V = any> {\n /**\n * The constructor function initializes a TreeNode object with a key, optional value, and optional\n * children.\n * @param {string} key - A string representing the key of the tree node.\n * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the\n * value associated with the node. If no value is provided, it defaults to `undefined`.\n * @param {TreeNode<V>[]} [children] - The `children` parameter is an optional array of `TreeNode<V>`\n * objects. It represents the child nodes of the current node. If no children are provided, the\n * default value is an empty array.\n */\n constructor(key: string, value?: V, children?: TreeNode<V>[]) {\n this._key = key;\n this._value = value || undefined;\n if (children) this._children = children;\n }\n\n protected _key: string;\n\n /**\n * The function returns the value of the protected variable _key.\n * @returns The value of the `_key` property, which is a string.\n */\n get key(): string {\n return this._key;\n }\n\n /**\n * The above function sets the value of a protected variable called \"key\".\n * @param {string} value - The value parameter is a string that represents the value to be assigned\n * to the key.\n */\n set key(value: string) {\n this._key = value;\n }\n\n protected _value?: V | undefined;\n\n /**\n * The function returns the value stored in a variable, or undefined if the variable is empty.\n * @returns The value of the variable `_value` is being returned.\n */\n get value(): V | undefined {\n return this._value;\n }\n\n /**\n * The function sets the value of a variable.\n * @param {V | undefined} value - The parameter \"value\" is of type \"V | undefined\", which means it\n * can accept a value of type \"V\" or it can be undefined.\n */\n set value(value: V | undefined) {\n this._value = value;\n }\n\n protected _children?: TreeNode<V>[] | undefined;\n\n /**\n * The function returns an array of TreeNode objects or undefined.\n * @returns The `children` property is being returned. It is of type `TreeNode<V>[] | undefined`,\n * which means it can either be an array of `TreeNode<V>` objects or `undefined`.\n */\n get children(): TreeNode<V>[] | undefined {\n return this._children;\n }\n\n /**\n * The function sets the value of the children property of a TreeNode object.\n * @param {TreeNode<V>[] | undefined} value - The value parameter is of type TreeNode<V>[] |\n * undefined. This means that it can accept an array of TreeNode objects or undefined.\n */\n set children(value: TreeNode<V>[] | undefined) {\n this._children = value;\n }\n\n /**\n * The function `addChildren` adds one or more child nodes to the current node.\n * @param {TreeNode<V> | TreeNode<V>[]} children - The `children` parameter can be either a single\n * `TreeNode<V>` object or an array of `TreeNode<V>` objects.\n */\n addChildren(children: TreeNode<V> | TreeNode<V>[]) {\n if (!this._children) {\n this._children = [];\n }\n if (children instanceof TreeNode) {\n this._children.push(children);\n } else {\n this._children = this._children.concat(children);\n }\n }\n\n /**\n * The function `getHeight()` calculates the maximum depth of a tree structure by performing a\n * breadth-first search.\n * @returns the maximum depth or height of the tree.\n */\n getHeight() {\n let maxDepth = 0;\n if (this) {\n const bfs = (node: TreeNode<V>, level: number) => {\n if (level > maxDepth) {\n maxDepth = level;\n }\n const { _children } = node;\n if (_children) {\n for (let i = 0, len = _children.length; i < len; i++) {\n bfs(_children[i], level + 1);\n }\n }\n };\n bfs(this, 0);\n }\n return maxDepth;\n }\n}\n"],"mappings":"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","names":["src_exports","__export","AVLTree","AVLTreeMultiMap","AVLTreeMultiMapNode","AVLTreeNode","AbstractEdge","AbstractGraph","AbstractVertex","BST","BSTNode","BinaryIndexedTree","BinaryTree","BinaryTreeNode","Character","DFSOperation","Deque","DirectedEdge","DirectedGraph","DirectedVertex","DoublyLinkedList","DoublyLinkedListNode","FibonacciHeap","FibonacciHeapNode","HashMap","Heap","IterableElementBase","IterableEntryBase","LinkedHashMap","LinkedListQueue","MapEdge","MapGraph","MapVertex","Matrix","MaxHeap","MaxPriorityQueue","MinHeap","MinPriorityQueue","Navigator","PriorityQueue","Queue","RedBlackTree","RedBlackTreeNode","SegmentTree","SegmentTreeNode","SinglyLinkedList","SinglyLinkedListNode","SkipList","SkipListNode","Stack","THUNK_SYMBOL","TreeMultiMap","TreeMultiMapNode","TreeNode","Trie","TrieNode","UndirectedEdge","UndirectedGraph","UndirectedVertex","arrayRemove","calcMinUnitsRequired","getMSB","isComparable","isThunk","isWeakKey","rangeCheck","roundFixed","throwRangeError","toBinaryString","toThunk","trampoline","trampolineAsync","uuidV4","IterableEntryBase","args","__yieldStar","item","predicate","thisArg","index","callbackfn","key","value","itemKey","elementValue","initialValue","accumulator","IterableElementBase","options","__publicField","toElementFn","args","__yieldStar","item","predicate","thisArg","index","callbackfn","element","ele","initialValue","accumulator","uuidV4","c","r","arrayRemove","array","predicate","i","len","result","value","THUNK_SYMBOL","isThunk","fnOrValue","toThunk","fn","thunk","trampoline","args","trampolineAsync","__async","getMSB","rangeCheck","index","min","max","message","throwRangeError","isWeakKey","input","inputType","calcMinUnitsRequired","totalQuantity","unitSize","roundFixed","num","digit","multiplier","isPrimitiveComparable","valueType","tryObjectToPrimitive","obj","valueOfResult","stringResult","isComparable","isForceObjectComparable","comparableValue","toBinaryString","num","digit","binaryString","HashMap","_HashMap","IterableEntryBase","entryOrRawElements","options","__publicField","key","hashFn","toEntryFn","rawElement","value","strKey","results","rawEle","item","_a","callbackfn","thisArg","resultMap","index","predicate","filteredMap","node","keyType","LinkedHashMap","_LinkedHashMap","objHashFn","isNewKey","isWeakKey","hash","rangeCheck","cloned","entry","callback","mappedMap","newValue","prev","next","SinglyLinkedListNode","value","__publicField","SinglyLinkedList","_SinglyLinkedList","IterableElementBase","elements","options","el","_a","data","singlyLinkedList","item","element","newNode","current","removedNode","index","i","prevNode","valueOrNode","prev","array","next","existingValueOrNode","newValue","existingValue","existingNode","count","callback","thisArg","filteredList","toElementFn","mappedList","DoublyLinkedListNode","value","__publicField","DoublyLinkedList","_DoublyLinkedList","IterableElementBase","elements","options","el","_a","data","element","newNode","removedNode","index","current","i","prevNode","nextNode","existingValueOrNode","newValue","existingNode","valOrNode","node","callback","next","array","thisArg","filteredList","toElementFn","mappedList","SkipListNode","key","value","level","__publicField","SkipList","elements","options","maxLevel","probability","firstNode","current","i","newNode","update","nextNode","lastLess","Stack","_Stack","IterableElementBase","elements","options","__publicField","el","element","index","predicate","thisArg","newStack","callback","toElementFn","i","Queue","_Queue","IterableElementBase","elements","options","__publicField","autoCompactRatio","el","v","element","first","index","predicate","thisArg","newDeque","callback","toElementFn","item","LinkedListQueue","_LinkedListQueue","SinglyLinkedList","Deque","_Deque","IterableElementBase","elements","options","__publicField","bucketSize","maxLen","_size","calcMinUnitsRequired","i","needBucketNum","el","element","index","pos","rangeCheck","bucketIndex","indexInBucket","num","length","arr","isCutSelf","newDeque","curBucket","curPointer","nextBucket","nextPointer","size","oldElement","bucket","_bucketFirst","_bucketLast","_firstInBucket","_lastInBucket","prev","cur","comparator","newBuckets","predicate","thisArg","callback","toElementFn","addBucketNum","overallIndex","Heap","_Heap","IterableElementBase","elements","options","__publicField","a","b","comparator","el","_a","element","value","last","index","order","result","_dfs","left","right","visitedNode","cloned","top","results","i","callback","thisArg","filteredList","current","toElementFn","mappedHeap","parent","parentItem","halfLength","minItem","FibonacciHeapNode","degree","FibonacciHeap","node","head","flag","z","heapToMerge","thisRoot","otherRoot","thisRootRight","otherRootLeft","y","x","A","d","t","MaxHeap","_MaxHeap","Heap","elements","options","__spreadValues","a","b","callback","thisArg","filteredList","index","current","comparator","toElementFn","mappedHeap","el","MinHeap","_MinHeap","Heap","elements","options","callback","thisArg","filteredList","index","current","comparator","toElementFn","mappedHeap","el","AbstractVertex","key","value","__publicField","AbstractEdge","weight","uuidV4","AbstractGraph","IterableEntryBase","v","vertexKey","vertexOrKey","keyOrVertex","newVertex","potentialKey","potentialKeyType","vertexMap","removed","v1","v2","srcOrEdge","dest","newEdge","srcOrKey","destOrKey","edge","limit","paths","vertex1","vertex2","stack","vertex","path","neighbors","neighbor","newPath","_a","sum","isWeight","allPaths","min","visited","queue","Queue","cost","i","cur","isDFS","_b","minIndex","index","pathSumWeight","minPath","dfs","visiting","src","getMinDist","genPaths","minDist","minDest","distMap","seen","preMap","srcVertex","destVertex","getMinOfNoSeen","minV","getPaths","parent","reversed","curFromMap","neighborFromMap","d","heap","Heap","a","b","curHeapNode","dist","distSrcToNeighbor","scanNegativeCycle","getMin","genPath","hasNegativeCycle","numOfVertices","edgeMap","numOfEdges","j","ends","s","sWeight","dWeight","idAndVertices","n","costs","predecessor","k","isInclude2Cycle","cycles","currentPath","uniqueCycles","cycle","sorted","cycleString","predicate","thisArg","filtered","callback","mapped","DirectedVertex","AbstractVertex","key","value","DirectedEdge","AbstractEdge","src","dest","weight","__publicField","DirectedGraph","_DirectedGraph","AbstractGraph","v","srcOrKey","destOrKey","edgeMap","srcOutEdges","edge","removed","arrayRemove","destInEdges","edgeOrSrcVertexKey","destVertexKey","vertexOrKey","vertexKey","vertex","neighbors","neighbor","v1","v2","v1ToV2","v2ToV1","target","destinations","outgoingEdges","outEdge","child","propertyName","statusMap","entry","sorted","hasCycle","dfs","cur","children","childStatus","outEdges","cloned","dfnMap","lowMap","SCCs","time","stack","inStack","SCC","poppedVertex","srcVertex","destVertex","UndirectedVertex","AbstractVertex","key","value","UndirectedEdge","AbstractEdge","v1","v2","weight","__publicField","UndirectedGraph","_UndirectedGraph","AbstractGraph","v","_a","edgeMap","vertex1","vertex2","e","v1Edges","removed","arrayRemove","v2Edges","edgeOrOneSideVertexKey","otherSideVertexKey","oneSide","otherSide","vertexOrKey","vertexKey","vertex","neighbors","neighbor","neighborEdges","restEdges","edge","edgeSet","cloned","dfnMap","lowMap","bridges","cutVertices","time","dfs","parent","childCount","end","endVertex","MapVertex","DirectedVertex","key","value","lat","long","__publicField","MapEdge","DirectedEdge","src","dest","weight","MapGraph","_MapGraph","DirectedGraph","originCoord","bottomRight","cloned","DFSOperation","BinaryTreeNode","key","value","__publicField","v","that","BinaryTree","_BinaryTree","IterableEntryBase","keysOrNodesOrEntriesOrRaws","options","node","iterationType","toEntryFn","__spreadValues","keyOrNodeOrEntryOrRaw","entryValue","isComparable","newNode","queue","Queue","potentialParent","cur","values","inserted","valuesIterator","valueResult","keyOrNodeOrEntryOrRawOrPredicate","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","onlyOne","beginRoot","callback","ans","dfs","stack","_a","min","max","numKey","isStandardBST","isInverseBST","checkBST","checkMax","prev","dist","distEnsured","beginRootEnsured","depth","_getMaxHeight","leftHeight","rightHeight","maxHeight","_getMinHeight","leftMinHeight","rightMinHeight","last","depths","beginNode","isReverse","result","beginNodeEnsured","trampoline","predecessor","x","y","pattern","includeNull","level","current","levelSize","i","leaves","levelsNodes","_recursive","head","_reverseEdge","pre","next","_printEdge","tail","cloned","predicate","thisArg","newTree","index","opts","output","root","lines","paragraph","line","shouldVisitLeft","shouldVisitRight","shouldVisitRoot","shouldProcessRoot","visitLeft","visitRight","pushLeft","pushRight","pushRoot","__yieldStar","isShowNull","isShowUndefined","isShowRedBlackNIL","emptyDisplayLayout","width","_buildNodeDisplay","left","right","leftLines","leftWidth","leftMiddle","rightLines","rightWidth","rightMiddle","firstLine","secondLine","mergedLines","leftLine","rightLine","srcNode","destNode","tempNode","oldNode","keyOrEntryOrRawOrPredicate","p","BSTNode","BinaryTreeNode","key","value","__publicField","v","BST","_BST","BinaryTree","keysOrNodesOrEntriesOrRaws","options","a","b","comparator","__spreadValues","keyOrNodeOrEntryOrRaw","_a","iterationType","isComparable","newNode","current","values","isBalanceAdd","inserted","valuesIterator","kve","nn","realBTNExemplars","isRealBTNExemplar","sorted","keyA","keyB","_dfs","arr","mid","stack","popped","l","r","m","predicate","onlyOne","beginRoot","callback","ans","dfs","cur","pattern","lesserOrGreater","targetNode","targetNodeEnsured","targetKey","compared","queue","Queue","node","n","buildBalanceBST","midNode","balanced","_height","leftHeight","rightHeight","last","depths","left","right","BinaryIndexedTree","frequency","max","__publicField","getMSB","index","position","change","freqCur","freq","count","sum","x","y","i","delta","z","freqNew","before","left","right","sumT","middle","sumM","SegmentTreeNode","start","end","sum","value","__publicField","SegmentTree","values","mid","left","right","cur","index","root","dfs","indexA","indexB","i","j","leftSum","rightSum","AVLTreeNode","BSTNode","key","value","__publicField","AVLTree","_AVLTree","BST","keysOrNodesOrEntriesOrRaws","options","__spreadValues","keyOrNodeOrEntryOrRaw","inserted","predicate","deletedResults","needBalanced","srcNode","destNode","srcNodeEnsured","destNodeEnsured","height","tempNode","node","rightHeight","A","parentOfA","B","C","path","i","oldNode","newNode","RedBlackTreeNode","BSTNode","key","value","color","__publicField","RedBlackTree","_RedBlackTree","BST","keysOrNodesOrEntriesOrRaws","options","__spreadValues","keyOrNodeOrEntryOrRaw","newNode","insertStatus","predicate","results","nodeToDelete","originalColor","replacementNode","successor","node","v","oldNode","_a","_b","current","parent","compared","u","z","_c","_d","y","sibling","x","AVLTreeMultiMapNode","AVLTreeNode","key","value","count","__publicField","AVLTreeMultiMap","_AVLTreeMultiMap","AVLTree","keysOrNodesOrEntriesOrRaws","options","sum","node","__spreadValues","keyOrNodeOrEntryOrRaw","entryValue","newNode","orgNodeCount","predicate","ignoreCount","_a","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","iterationType","sorted","n","buildBalanceBST","l","r","m","midNode","stack","popped","cloned","srcNode","destNode","height","tempNode","oldNode","TreeMultiMapNode","RedBlackTreeNode","key","value","count","color","__publicField","TreeMultiMap","_TreeMultiMap","RedBlackTree","keysOrNodesOrEntriesOrRaws","options","sum","node","__spreadValues","keyOrNodeOrEntryOrRaw","entryValue","newNode","orgCount","predicate","ignoreCount","results","nodeToDelete","originalColor","replacementNode","successor","iterationType","sorted","n","buildBalanceBST","l","r","m","midNode","stack","popped","cloned","srcNode","destNode","tempNode","oldNode","PriorityQueue","_PriorityQueue","Heap","elements","options","callback","thisArg","filteredPriorityQueue","index","current","comparator","toElementFn","mappedPriorityQueue","el","MinPriorityQueue","_MinPriorityQueue","PriorityQueue","elements","options","callback","thisArg","filteredPriorityQueue","index","current","comparator","toElementFn","mappedPriorityQueue","el","MaxPriorityQueue","_MaxPriorityQueue","PriorityQueue","elements","options","__spreadValues","a","b","callback","thisArg","filteredPriorityQueue","index","current","comparator","toElementFn","mappedPriorityQueue","el","Matrix","_Matrix","data","options","__publicField","_a","_b","_c","rows","cols","addFn","subtractFn","multiplyFn","i","row","col","value","matrix","resultData","j","a","b","added","subtracted","sum","k","multiplied","trans","augmentedMatrixData","augmentedMatrix","pivotRow","pivotElement","factor","inverseData","row1","row2","temp","scalar","targetRow","sourceRow","scaledValue","Character","_Character","direction","turning","__publicField","Navigator","matrix","onMove","cur","charDir","VISITED","forward","row","j","i","TrieNode","key","__publicField","value","Trie","_Trie","IterableElementBase","words","options","caseSensitive","word","cur","isNewWord","c","nodeC","isDeleted","dfs","i","char","child","beginRoot","maxDepth","bfs","node","level","children","input","commonPre","prefix","max","isAllWhenEmptyPrefix","found","charNode","startNode","predicate","thisArg","results","index","callback","toElementFn","newTrie","_dfs","path","childNode","__yieldStar","str","TreeNode","_TreeNode","key","value","children","__publicField","maxDepth","bfs","node","level","_children","i","len"]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/data-structures/base/iterable-entry-base.ts","../../src/data-structures/base/iterable-element-base.ts","../../src/utils/utils.ts","../../src/utils/number.ts","../../src/data-structures/hash/hash-map.ts","../../src/data-structures/linked-list/singly-linked-list.ts","../../src/data-structures/linked-list/doubly-linked-list.ts","../../src/data-structures/linked-list/skip-linked-list.ts","../../src/data-structures/stack/stack.ts","../../src/data-structures/queue/queue.ts","../../src/data-structures/queue/deque.ts","../../src/data-structures/heap/heap.ts","../../src/data-structures/heap/max-heap.ts","../../src/data-structures/heap/min-heap.ts","../../src/data-structures/graph/abstract-graph.ts","../../src/data-structures/graph/directed-graph.ts","../../src/data-structures/graph/undirected-graph.ts","../../src/data-structures/graph/map-graph.ts","../../src/constants/index.ts","../../src/data-structures/binary-tree/binary-tree.ts","../../src/data-structures/binary-tree/bst.ts","../../src/data-structures/binary-tree/binary-indexed-tree.ts","../../src/data-structures/binary-tree/segment-tree.ts","../../src/data-structures/binary-tree/avl-tree.ts","../../src/data-structures/binary-tree/rb-tree.ts","../../src/data-structures/binary-tree/avl-tree-multi-map.ts","../../src/data-structures/binary-tree/tree-multi-map.ts","../../src/data-structures/priority-queue/priority-queue.ts","../../src/data-structures/priority-queue/min-priority-queue.ts","../../src/data-structures/priority-queue/max-priority-queue.ts","../../src/data-structures/matrix/matrix.ts","../../src/data-structures/matrix/navigator.ts","../../src/data-structures/trie/trie.ts","../../src/data-structures/tree/tree.ts"],"sourcesContent":["export * from './data-structures';\nexport * from './utils';\nexport * from './interfaces';\nexport * from './types';\nexport * from './constants';\n","import { EntryCallback, ReduceEntryCallback } from '../../types';\n\nexport abstract class IterableEntryBase<K = any, V = any> {\n abstract get size(): number;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function is an implementation of the Symbol.iterator method that returns an iterable iterator.\n * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It\n * allows the function to accept any number of arguments as an array. In this case, the `args`\n * parameter is used to pass any additional arguments to the `_getIterator` method.\n */\n *[Symbol.iterator](...args: any[]): IterableIterator<[K, V]> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields key-value pairs from the object, where the value can\n * be undefined.\n */\n *entries(): IterableIterator<[K, V | undefined]> {\n for (const item of this) {\n yield item;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields the keys of a data structure.\n */\n *keys(): IterableIterator<K> {\n for (const item of this) {\n yield item[0];\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields the values of a collection.\n */\n *values(): IterableIterator<V> {\n for (const item of this) {\n yield item[1];\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `every` function checks if every element in a collection satisfies a given condition.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is\n * met for the current element in the iteration.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the first argument to the `predicate` function. If `thisArg` is not provided\n * @returns The `every` method is returning a boolean value. It returns `true` if every element in\n * the collection satisfies the provided predicate function, and `false` otherwise.\n */\n every(predicate: EntryCallback<K, V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item[1], item[0], index++, this)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The \"some\" function iterates over a collection and returns true if at least one element satisfies\n * a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `key`, and `index`. It should return a boolean value indicating whether the condition is\n * met for the current element in the iteration.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided,\n * it will be passed as the first argument to the `predicate` function. If `thisArg` is\n * @returns a boolean value. It returns true if the predicate function returns true for any pair in\n * the collection, and false otherwise.\n */\n some(predicate: EntryCallback<K, V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item[1], item[0], index++, this)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `forEach` function iterates over each key-value pair in a collection and executes a callback\n * function for each pair.\n * @param callbackfn - The callback function that will be called for each element in the collection.\n * It takes four parameters: the value of the current element, the key of the current element, the\n * index of the current element, and the collection itself.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. If `thisArg` is provided, it will be\n * used as the `this` value when calling the callback function. If `thisArg` is not provided, `\n */\n forEach(callbackfn: EntryCallback<K, V, void>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n callbackfn.call(thisArg, value, key, index++, this);\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the entries of a collection and returns the first value for\n * which the callback function returns true.\n * @param callbackfn - The callback function that will be called for each entry in the collection. It\n * takes three arguments: the value of the entry, the key of the entry, and the index of the entry in\n * the collection. It should return a boolean value indicating whether the current entry matches the\n * desired condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The method `find` returns the value of the first element in the iterable that satisfies\n * the provided callback function. If no element satisfies the callback function, `undefined` is\n * returned.\n */\n find(callbackfn: EntryCallback<K, V, boolean>, thisArg?: any): [K, V] | undefined {\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n if (callbackfn.call(thisArg, value, key, index++, this)) return item;\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given key exists in a collection.\n * @param {K} key - The parameter \"key\" is of type K, which means it can be any type. It represents\n * the key that we want to check for existence in the data structure.\n * @returns a boolean value. It returns true if the key is found in the collection, and false\n * otherwise.\n */\n has(key: K): boolean {\n for (const item of this) {\n const [itemKey] = item;\n if (itemKey === key) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given value exists in a collection.\n * @param {V} value - The parameter \"value\" is the value that we want to check if it exists in the\n * collection.\n * @returns a boolean value, either true or false.\n */\n hasValue(value: V): boolean {\n for (const [, elementValue] of this) {\n if (elementValue === value) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `get` function retrieves the value associated with a given key from a collection.\n * @param {K} key - K (the type of the key) - This parameter represents the key that is being\n * searched for in the collection.\n * @returns The `get` method returns the value associated with the specified key if it exists in the\n * collection, otherwise it returns `undefined`.\n */\n get(key: K): V | undefined {\n for (const item of this) {\n const [itemKey, value] = item;\n if (itemKey === key) return value;\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reduce` function iterates over key-value pairs and applies a callback function to each pair,\n * accumulating a single value.\n * @param callbackfn - The callback function that will be called for each element in the collection.\n * It takes four arguments: the current accumulator value, the current value of the element, the key\n * of the element, and the index of the element in the collection. It should return the updated\n * accumulator value.\n * @param {U} initialValue - The `initialValue` parameter is the initial value of the accumulator. It\n * is the value that will be used as the first argument to the `callbackfn` function when reducing\n * the elements of the collection.\n * @returns The `reduce` method is returning the final value of the accumulator after iterating over\n * all the elements in the collection.\n */\n reduce<U>(callbackfn: ReduceEntryCallback<K, V, U>, initialValue: U): U {\n let accumulator = initialValue;\n let index = 0;\n for (const item of this) {\n const [key, value] = item;\n accumulator = callbackfn(accumulator, value, key, index++, this);\n }\n return accumulator;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n toVisual(): [K, V][] | string {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n abstract isEmpty(): boolean;\n\n abstract clear(): void;\n\n abstract clone(): any;\n\n abstract map(...args: any[]): any;\n\n abstract filter(...args: any[]): any;\n\n protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;\n}\n","import { ElementCallback, IterableElementBaseOptions, ReduceElementCallback } from '../../types';\n\nexport abstract class IterableElementBase<E, R, C> {\n /**\n * The protected constructor initializes the options for the IterableElementBase class, including the\n * toElementFn function.\n * @param [options] - An optional object that contains the following properties:\n */\n protected constructor(options?: IterableElementBaseOptions<E, R>) {\n if (options) {\n const { toElementFn } = options;\n if (typeof toElementFn === 'function') this._toElementFn = toElementFn;\n else if (toElementFn) throw new TypeError('toElementFn must be a function type');\n }\n }\n\n abstract get size(): number;\n\n protected _toElementFn?: (rawElement: R) => E;\n\n /**\n * The function returns the _toElementFn property, which is a function that converts a raw element to\n * a specific type.\n * @returns The function `get toElementFn()` is returning either a function that takes a raw element\n * `rawElement` of type `R` and returns an element `E`, or `undefined` if no function is assigned to\n * `_toElementFn`.\n */\n get toElementFn(): ((rawElement: R) => E) | undefined {\n return this._toElementFn;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function is an implementation of the Symbol.iterator method that returns an IterableIterator.\n * @param {any[]} args - The `args` parameter in the code snippet represents a rest parameter. It\n * allows the function to accept any number of arguments as an array. In this case, the `args`\n * parameter is used to pass any number of arguments to the `_getIterator` method.\n */\n *[Symbol.iterator](...args: any[]): IterableIterator<E> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function returns an iterator that yields all the values in the object.\n */\n *values(): IterableIterator<E> {\n for (const item of this) {\n yield item;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `every` function checks if every element in the array satisfies a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being processed, its index, and the array it belongs to. It should return a\n * boolean value indicating whether the element satisfies a certain condition or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `every` method is returning a boolean value. It returns `true` if every element in\n * the array satisfies the provided predicate function, and `false` otherwise.\n */\n every(predicate: ElementCallback<E, R, boolean, C>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item, index++, this)) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The \"some\" function checks if at least one element in a collection satisfies a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `value`, `index`, and `array`. It should return a boolean value indicating whether the current\n * element satisfies the condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as the `this` value when executing the `predicate` function. If `thisArg` is provided,\n * it will be passed as the `this` value to the `predicate` function. If `thisArg\n * @returns a boolean value. It returns true if the predicate function returns true for any element\n * in the collection, and false otherwise.\n */\n some(predicate: ElementCallback<E, R, boolean, C>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item, index++, this)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `forEach` function iterates over each element in an array-like object and calls a callback\n * function for each element.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes three arguments: the current element being processed, the index of the current\n * element, and the array that forEach was called upon.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n */\n forEach(callbackfn: ElementCallback<E, R, void, C>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n callbackfn.call(thisArg, item, index++, this);\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the elements of an array-like object and returns the first\n * element that satisfies the provided callback function.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes three arguments: the current element being processed, the index of the current\n * element, and the array itself. The function should return a boolean value indicating whether the\n * current element matches the desired condition.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The `find` method returns the first element in the array that satisfies the provided\n * callback function. If no element satisfies the callback function, `undefined` is returned.\n */\n find(callbackfn: ElementCallback<E, R, boolean, C>, thisArg?: any): E | undefined {\n let index = 0;\n for (const item of this) {\n if (callbackfn.call(thisArg, item, index++, this)) return item;\n }\n\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a given element exists in a collection.\n * @param {E} element - The parameter \"element\" is of type E, which means it can be any type. It\n * represents the element that we want to check for existence in the collection.\n * @returns a boolean value. It returns true if the element is found in the collection, and false\n * otherwise.\n */\n has(element: E): boolean {\n for (const ele of this) {\n if (ele === element) return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reduce` function iterates over the elements of an array-like object and applies a callback\n * function to reduce them into a single value.\n * @param callbackfn - The callbackfn parameter is a function that will be called for each element in\n * the array. It takes four arguments:\n * @param {U} initialValue - The initialValue parameter is the initial value of the accumulator. It\n * is the value that the accumulator starts with before the reduction operation begins.\n * @returns The `reduce` method is returning the final value of the accumulator after iterating over\n * all the elements in the array and applying the callback function to each element.\n */\n reduce<U>(callbackfn: ReduceElementCallback<E, R, U, C>, initialValue: U): U {\n let accumulator = initialValue;\n let index = 0;\n for (const item of this) {\n accumulator = callbackfn(accumulator, item as E, index++, this);\n }\n return accumulator;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n toVisual(): E[] {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The print function logs the elements of an array to the console.\n */\n print(): void {\n console.log(this.toVisual());\n }\n\n abstract isEmpty(): boolean;\n\n abstract clear(): void;\n\n abstract clone(): C;\n\n abstract map(...args: any[]): any;\n\n abstract filter(...args: any[]): any;\n\n protected abstract _getIterator(...args: any[]): IterableIterator<E>;\n}\n","/**\n * data-structure-typed\n *\n * @author Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { Comparable, ComparablePrimitive, Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';\n\n/**\n * The function generates a random UUID (Universally Unique Identifier) in TypeScript.\n * @returns A randomly generated UUID (Universally Unique Identifier) in the format\n * 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' where each 'x' is replaced with a random hexadecimal\n * character.\n */\nexport const uuidV4 = function () {\n return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {\n const r = (Math.random() * 16) | 0,\n v = c == 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n};\n\n/**\n * The `arrayRemove` function removes elements from an array based on a specified predicate function\n * and returns the removed elements.\n * @param {T[]} array - An array of elements that you want to filter based on the provided predicate\n * function.\n * @param predicate - The `predicate` parameter is a function that takes three arguments:\n * @returns The `arrayRemove` function returns an array containing the elements that satisfy the given\n * `predicate` function.\n */\nexport const arrayRemove = function <T>(array: T[], predicate: (item: T, index: number, array: T[]) => boolean): T[] {\n let i = -1,\n len = array ? array.length : 0;\n const result = [];\n\n while (++i < len) {\n const value = array[i];\n if (predicate(value, i, array)) {\n result.push(value);\n Array.prototype.splice.call(array, i--, 1);\n len--;\n }\n }\n\n return result;\n};\n\nexport const THUNK_SYMBOL = Symbol('thunk');\n\n/**\n * The function `isThunk` checks if a given value is a function with a specific symbol property.\n * @param {any} fnOrValue - The `fnOrValue` parameter in the `isThunk` function can be either a\n * function or a value that you want to check if it is a thunk. Thunks are functions that are wrapped\n * around a value or computation for lazy evaluation. The function checks if the `fnOrValue` is\n * @returns The function `isThunk` is checking if the input `fnOrValue` is a function and if it has a\n * property `__THUNK__` equal to `THUNK_SYMBOL`. The return value will be `true` if both conditions are\n * met, otherwise it will be `false`.\n */\nexport const isThunk = (fnOrValue: any) => {\n return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL;\n};\n\n/**\n * The `toThunk` function in TypeScript converts a function into a thunk by wrapping it in a closure.\n * @param {ToThunkFn} fn - `fn` is a function that will be converted into a thunk.\n * @returns A thunk function is being returned. Thunk functions are functions that delay the evaluation\n * of an expression or operation until it is explicitly called or invoked. In this case, the `toThunk`\n * function takes a function `fn` as an argument and returns a thunk function that, when called, will\n * execute the `fn` function provided as an argument.\n */\nexport const toThunk = (fn: ToThunkFn): Thunk => {\n const thunk = () => fn();\n thunk.__THUNK__ = THUNK_SYMBOL;\n return thunk;\n};\n\n/**\n * The `trampoline` function in TypeScript enables tail call optimization by using thunks to avoid\n * stack overflow.\n * @param {TrlFn} fn - The `fn` parameter in the `trampoline` function is a function that takes any\n * number of arguments and returns a value.\n * @returns The `trampoline` function returns an object with two properties:\n * 1. A function that executes the provided function `fn` and continues to execute any thunks returned\n * by `fn` until a non-thunk value is returned.\n * 2. A `cont` property that is a function which creates a thunk for the provided function `fn`.\n */\nexport const trampoline = (fn: TrlFn) => {\n const cont = (...args: [...Parameters<TrlFn>]): ReturnType<TrlFn> => toThunk(() => fn(...args));\n\n return Object.assign(\n (...args: [...Parameters<TrlFn>]) => {\n let result = fn(...args);\n\n while (isThunk(result) && typeof result === 'function') {\n result = result();\n }\n\n return result;\n },\n { cont }\n );\n};\n\n/**\n * The `trampolineAsync` function in TypeScript allows for asynchronous trampolining of a given\n * function.\n * @param {TrlAsyncFn} fn - The `fn` parameter in the `trampolineAsync` function is expected to be a\n * function that returns a Promise. This function will be called recursively until a non-thunk value is\n * returned.\n * @returns The `trampolineAsync` function returns an object with two properties:\n * 1. An async function that executes the provided `TrlAsyncFn` function and continues to execute any\n * thunks returned by the function until a non-thunk value is returned.\n * 2. A `cont` property that is a function which wraps the provided `TrlAsyncFn` function in a thunk\n * and returns it.\n */\nexport const trampolineAsync = (fn: TrlAsyncFn) => {\n const cont = (...args: [...Parameters<TrlAsyncFn>]): ReturnType<TrlAsyncFn> => toThunk(() => fn(...args));\n\n return Object.assign(\n async (...args: [...Parameters<TrlAsyncFn>]) => {\n let result = await fn(...args);\n\n while (isThunk(result) && typeof result === 'function') {\n result = await result();\n }\n\n return result;\n },\n { cont }\n );\n};\n\n/**\n * The function `getMSB` returns the most significant bit of a given number.\n * @param {number} value - The `value` parameter is a number for which we want to find the position of\n * the Most Significant Bit (MSB). The function `getMSB` takes this number as input and calculates the\n * position of the MSB in its binary representation.\n * @returns The function `getMSB` returns the most significant bit (MSB) of the input `value`. If the\n * input value is less than or equal to 0, it returns 0. Otherwise, it calculates the position of the\n * MSB using the `Math.clz32` function and bitwise left shifts 1 to that position.\n */\nexport const getMSB = (value: number): number => {\n if (value <= 0) {\n return 0;\n }\n return 1 << (31 - Math.clz32(value));\n};\n\n/**\n * The `rangeCheck` function in TypeScript is used to validate if an index is within a specified range\n * and throws a `RangeError` with a custom message if it is out of bounds.\n * @param {number} index - The `index` parameter represents the value that you want to check if it\n * falls within a specified range.\n * @param {number} min - The `min` parameter represents the minimum value that the `index` should be\n * compared against in the `rangeCheck` function.\n * @param {number} max - The `max` parameter in the `rangeCheck` function represents the maximum value\n * that the `index` parameter is allowed to have. If the `index` is greater than this `max` value, a\n * `RangeError` will be thrown.\n * @param [message=Index out of bounds.] - The `message` parameter is a string that represents the\n * error message to be thrown if the index is out of bounds. By default, if no message is provided when\n * calling the `rangeCheck` function, the message \"Index out of bounds.\" will be used.\n */\nexport const rangeCheck = (index: number, min: number, max: number, message = 'Index out of bounds.'): void => {\n if (index < min || index > max) throw new RangeError(message);\n};\n\n/**\n * The function `throwRangeError` throws a RangeError with a custom message if called.\n * @param [message=The value is off-limits.] - The `message` parameter is a string that represents the\n * error message to be displayed when a `RangeError` is thrown. If no message is provided, the default\n * message is 'The value is off-limits.'.\n */\nexport const throwRangeError = (message = 'The value is off-limits.'): void => {\n throw new RangeError(message);\n};\n\n/**\n * The function `isWeakKey` checks if the input is an object or a function in TypeScript.\n * @param {unknown} input - The `input` parameter in the `isWeakKey` function is of type `unknown`,\n * which means it can be any type. The function checks if the `input` is an object (excluding `null`)\n * or a function, and returns a boolean indicating whether the `input` is a weak\n * @returns The function `isWeakKey` returns a boolean value indicating whether the input is an object\n * or a function.\n */\nexport const isWeakKey = (input: unknown): input is object => {\n const inputType = typeof input;\n return (inputType === 'object' && input !== null) || inputType === 'function';\n};\n\n/**\n * The function `calcMinUnitsRequired` calculates the minimum number of units required to accommodate a\n * given total quantity based on a specified unit size.\n * @param {number} totalQuantity - The `totalQuantity` parameter represents the total quantity of items\n * that need to be processed or handled.\n * @param {number} unitSize - The `unitSize` parameter represents the size of each unit or package. It\n * is used in the `calcMinUnitsRequired` function to calculate the minimum number of units required to\n * accommodate a total quantity of items.\n */\nexport const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) =>\n Math.floor((totalQuantity + unitSize - 1) / unitSize);\n\n/**\n * The `roundFixed` function in TypeScript rounds a number to a specified number of decimal places.\n * @param {number} num - The `num` parameter is a number that you want to round to a certain number of\n * decimal places.\n * @param {number} [digit=10] - The `digit` parameter in the `roundFixed` function specifies the number\n * of decimal places to round the number to. By default, it is set to 10 if not provided explicitly.\n * @returns The function `roundFixed` returns a number that is rounded to the specified number of\n * decimal places (default is 10 decimal places).\n */\nexport const roundFixed = (num: number, digit: number = 10) => {\n const multiplier = Math.pow(10, digit);\n return Math.round(num * multiplier) / multiplier;\n};\n\n/**\n * The function `isPrimitiveComparable` checks if a value is a primitive type that can be compared.\n * @param {unknown} value - The `value` parameter in the `isPrimitiveComparable` function is of type\n * `unknown`, which means it can be any type. The function checks if the `value` is a primitive type\n * that can be compared, such as number, bigint, string, or boolean.\n * @returns The function `isPrimitiveComparable` returns a boolean value indicating whether the input\n * `value` is a primitive value that can be compared using standard comparison operators (<, >, <=,\n * >=).\n */\nfunction isPrimitiveComparable(value: unknown): value is ComparablePrimitive {\n const valueType = typeof value;\n if (valueType === 'number') return !Number.isNaN(value);\n return valueType === 'bigint' || valueType === 'string' || valueType === 'boolean';\n}\n\n/**\n * The function `tryObjectToPrimitive` attempts to convert an object to a comparable primitive value by\n * first checking the `valueOf` method and then the `toString` method.\n * @param {object} obj - The `obj` parameter in the `tryObjectToPrimitive` function is an object that\n * you want to convert to a primitive value. The function attempts to convert the object to a primitive\n * value by first checking if the object has a `valueOf` method. If the `valueOf` method exists, it\n * @returns The function `tryObjectToPrimitive` returns a value of type `ComparablePrimitive` if a\n * primitive comparable value is found within the object, or a string value if the object has a custom\n * `toString` method that does not return `'[object Object]'`. If neither condition is met, the\n * function returns `null`.\n */\nfunction tryObjectToPrimitive(obj: object): ComparablePrimitive | null {\n if (typeof obj.valueOf === 'function') {\n const valueOfResult = obj.valueOf();\n if (valueOfResult !== obj) {\n if (isPrimitiveComparable(valueOfResult)) return valueOfResult;\n if (typeof valueOfResult === 'object' && valueOfResult !== null) return tryObjectToPrimitive(valueOfResult);\n }\n }\n if (typeof obj.toString === 'function') {\n const stringResult = obj.toString();\n if (stringResult !== '[object Object]') return stringResult;\n }\n return null;\n}\n\n/**\n * The function `isComparable` in TypeScript checks if a value is comparable, handling primitive values\n * and objects with optional force comparison.\n * @param {unknown} value - The `value` parameter in the `isComparable` function represents the value\n * that you want to check if it is comparable. It can be of any type (`unknown`), and the function will\n * determine if it is comparable based on certain conditions.\n * @param [isForceObjectComparable=false] - The `isForceObjectComparable` parameter in the\n * `isComparable` function is a boolean flag that determines whether to treat non-primitive values as\n * comparable objects. When set to `true`, it forces the function to consider non-primitive values as\n * comparable objects, regardless of their type.\n * @returns The function `isComparable` returns a boolean value indicating whether the `value` is\n * considered comparable or not.\n */\nexport function isComparable(value: unknown, isForceObjectComparable = false): value is Comparable {\n if (value === null || value === undefined) return false;\n if (isPrimitiveComparable(value)) return true;\n\n if (typeof value !== 'object') return false;\n if (value instanceof Date) return !Number.isNaN(value.getTime());\n if (isForceObjectComparable) return true;\n const comparableValue = tryObjectToPrimitive(value);\n if (comparableValue === null || comparableValue === undefined) return false;\n return isPrimitiveComparable(comparableValue);\n}\n","/**\n * The function `toBinaryString` converts a number to a binary string representation with a specified\n * number of digits.\n * @param {number} num - The `num` parameter in the `toBinaryString` function represents the number\n * that you want to convert to a binary string.\n * @param [digit=32] - The `digit` parameter in the `toBinaryString` function represents the number of\n * digits the binary string should have. By default, it is set to 32, meaning that the binary string\n * will be padded with zeros at the beginning to ensure it is 32 bits long. You can provide a\n * @returns The function `toBinaryString` takes a number as input and converts it to a binary string\n * representation with a specified number of digits (default is 32). The binary string is padded with\n * zeros at the beginning to ensure it has the specified number of digits. The function returns the\n * binary string representation of the input number.\n */\nexport function toBinaryString(num: number, digit = 32) {\n // Convert number to binary string\n let binaryString = (num >>> 0).toString(2); // Use the unsigned right shift operator to ensure you get a binary representation of a 32-bit unsigned integer\n\n // Use pad Start to ensure the string length is 32 bits\n binaryString = binaryString.padStart(digit, '0');\n\n return binaryString;\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n EntryCallback,\n HashMapLinkedNode,\n HashMapOptions,\n HashMapStoreItem,\n LinkedHashMapOptions\n} from '../../types';\nimport { IterableEntryBase } from '../base';\nimport { isWeakKey, rangeCheck } from '../../utils';\n\n/**\n * 1. Key-Value Pair Storage: HashMap stores key-value pairs. Each key map to a value.\n * 2. Fast Lookup: It's used when you need to quickly find, insert, or delete entries based on a key.\n * 3. Unique Keys: Keys are unique.\n * If you try to insert another entry with the same key, the new one will replace the old entry.\n * 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.\n */\nexport class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {\n /**\n * The constructor function initializes a HashMap object with an optional initial collection and\n * options.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type\n * `T`. It is an optional parameter and its default value is an empty array `[]`.\n * @param [options] - The `options` parameter is an optional object that can contain two properties:\n */\n constructor(entryOrRawElements: Iterable<R | [K, V]> = [], options?: HashMapOptions<K, V, R>) {\n super();\n if (options) {\n const { hashFn, toEntryFn } = options;\n if (hashFn) this._hashFn = hashFn;\n if (toEntryFn) this._toEntryFn = toEntryFn;\n }\n if (entryOrRawElements) {\n this.setMany(entryOrRawElements);\n }\n }\n\n protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};\n\n /**\n * The function returns the store object, which is a dictionary of HashMapStoreItem objects.\n * @returns The store property is being returned. It is a dictionary-like object with string keys and\n * values of type HashMapStoreItem<K, V>.\n */\n get store(): { [p: string]: HashMapStoreItem<K, V> } {\n return this._store;\n }\n\n protected _objMap: Map<object, V> = new Map();\n\n /**\n * The function returns the object map.\n * @returns The `objMap` property is being returned, which is a `Map` object with keys of type\n * `object` and values of type `V`.\n */\n get objMap(): Map<object, V> {\n return this._objMap;\n }\n\n protected _toEntryFn?: (rawElement: R) => [K, V];\n\n /**\n * The function returns the value of the _toEntryFn property.\n * @returns The function being returned is `this._toEntryFn`.\n */\n get toEntryFn() {\n return this._toEntryFn;\n }\n\n protected _size = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n protected _hashFn: (key: K) => string = (key: K) => String(key);\n\n /**\n * The hasFn function is a function that takes in an item and returns a boolean\n * indicating whether the item is contained within the hash table.\n *\n * @return The hash function\n */\n get hashFn() {\n return this._hashFn;\n }\n\n /**\n * The function checks if a given element is an array with exactly two elements.\n * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any\n * data type.\n * @returns a boolean value.\n */\n isEntry(rawElement: any): rawElement is [K, V] {\n return Array.isArray(rawElement) && rawElement.length === 2;\n }\n\n /**\n * The function checks if the size of an object is equal to zero and returns a boolean value.\n * @returns A boolean value indicating whether the size of the object is 0 or not.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * The clear() function resets the state of an object by clearing its internal store, object map, and\n * size.\n */\n clear() {\n this._store = {};\n this._objMap.clear();\n this._size = 0;\n }\n\n /**\n * The `set` function adds a key-value pair to a map-like data structure, incrementing the size if\n * the key is not already present.\n * @param {K} key - The key parameter is the key used to identify the value in the data structure. It\n * can be of any type, but if it is an object, it will be stored in a Map, otherwise it will be\n * stored in a regular JavaScript object.\n * @param {V} value - The value parameter represents the value that you want to associate with the\n * key in the data structure.\n */\n set(key: K, value: V): boolean {\n if (this._isObjKey(key)) {\n if (!this.objMap.has(key)) {\n this._size++;\n }\n this.objMap.set(key, value);\n } else {\n const strKey = this._getNoObjKey(key);\n if (this.store[strKey] === undefined) {\n this._size++;\n }\n this._store[strKey] = { key, value };\n }\n return true;\n }\n\n /**\n * The function `setMany` takes an iterable collection of objects, maps each object to a key-value\n * pair using a mapping function, and sets each key-value pair in the current object.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements of a type\n * `T`.\n * @returns The `setMany` function is returning an array of booleans.\n */\n setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const rawEle of entryOrRawElements) {\n let key: K | undefined, value: V | undefined;\n if (this.isEntry(rawEle)) {\n key = rawEle[0];\n value = rawEle[1];\n } else if (this._toEntryFn) {\n const item = this._toEntryFn(rawEle);\n key = item[0];\n value = item[1];\n }\n\n if (key !== undefined && value !== undefined) results.push(this.set(key, value));\n }\n return results;\n }\n\n /**\n * The `get` function retrieves a value from a map based on a given key, either from an object map or\n * a string map.\n * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be\n * of any type, but it should be compatible with the key type used when the map was created.\n * @returns The method `get(key: K)` returns a value of type `V` if the key exists in the `_objMap`\n * or `_store`, otherwise it returns `undefined`.\n */\n override get(key: K): V | undefined {\n if (this._isObjKey(key)) {\n return this.objMap.get(key);\n } else {\n const strKey = this._getNoObjKey(key);\n return this._store[strKey]?.value;\n }\n }\n\n /**\n * The `has` function checks if a given key exists in the `_objMap` or `_store` based on whether it\n * is an object key or not.\n * @param {K} key - The parameter \"key\" is of type K, which means it can be any type.\n * @returns The `has` method is returning a boolean value.\n */\n override has(key: K): boolean {\n if (this._isObjKey(key)) {\n return this.objMap.has(key);\n } else {\n const strKey = this._getNoObjKey(key);\n return strKey in this.store;\n }\n }\n\n /**\n * The `delete` function removes an element from a map-like data structure based on the provided key.\n * @param {K} key - The `key` parameter is the key of the element that you want to delete from the\n * data structure.\n * @returns The `delete` method returns a boolean value. It returns `true` if the key was\n * successfully deleted from the map, and `false` if the key was not found in the map.\n */\n delete(key: K): boolean {\n if (this._isObjKey(key)) {\n if (this.objMap.has(key)) {\n this._size--;\n }\n\n return this.objMap.delete(key);\n } else {\n const strKey = this._getNoObjKey(key);\n if (strKey in this.store) {\n delete this.store[strKey];\n this._size--;\n return true;\n }\n return false;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The clone function creates a new HashMap with the same key-value pairs as\n * this one. The clone function is useful for creating a copy of an existing\n * HashMap, and then modifying that copy without affecting the original.\n *\n * @return A new hashmap with the same values as this one\n */\n clone(): HashMap<K, V, R> {\n return new HashMap<K, V, R>(this, { hashFn: this._hashFn, toEntryFn: this._toEntryFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function in TypeScript creates a new HashMap by applying a callback function to each\n * key-value pair in the original HashMap.\n * @param callbackfn - The callback function that will be called for each key-value pair in the\n * HashMap. It takes four parameters:\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callbackfn` function. If `thisArg` is provided, it will\n * be passed as the `this` value to the `callbackfn` function. If `thisArg\n * @returns The `map` method is returning a new `HashMap` object with the transformed values based on\n * the provided callback function.\n */\n map<VM>(callbackfn: EntryCallback<K, V, VM>, thisArg?: any): HashMap<K, VM> {\n const resultMap = new HashMap<K, VM>();\n let index = 0;\n for (const [key, value] of this) {\n resultMap.set(key, callbackfn.call(thisArg, value, key, index++, this));\n }\n return resultMap;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new HashMap containing key-value pairs from the original HashMap\n * that satisfy a given predicate function.\n * @param predicate - The predicate parameter is a function that takes four arguments: value, key,\n * index, and map. It is used to determine whether an element should be included in the filtered map\n * or not. The function should return a boolean value - true if the element should be included, and\n * false otherwise.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs\n * from the original `HashMap` that pass the provided `predicate` function.\n */\n filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): HashMap<K, V> {\n const filteredMap = new HashMap<K, V>();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index++, this)) {\n filteredMap.set(key, value);\n }\n }\n return filteredMap;\n }\n\n /**\n * The function returns an iterator that yields key-value pairs from both an object store and an\n * object map.\n */\n protected *_getIterator(): IterableIterator<[K, V]> {\n for (const node of Object.values(this.store)) {\n yield [node.key, node.value] as [K, V];\n }\n for (const node of this.objMap) {\n yield node as [K, V];\n }\n }\n\n /**\n * The function checks if a given key is an object or a function.\n * @param {any} key - The parameter \"key\" can be of any type.\n * @returns a boolean value.\n */\n protected _isObjKey(key: any): key is object | ((...args: any[]) => any) {\n const keyType = typeof key;\n return (keyType === 'object' || keyType === 'function') && key !== null;\n }\n\n /**\n * The function `_getNoObjKey` takes a key and returns a string representation of the key, handling\n * different types of keys.\n * @param {K} key - The `key` parameter is of type `K`, which represents the type of the key being\n * passed to the `_getNoObjKey` function.\n * @returns a string value.\n */\n protected _getNoObjKey(key: K): string {\n const keyType = typeof key;\n\n let strKey: string;\n if (keyType !== 'string' && keyType !== 'number' && keyType !== 'symbol') {\n strKey = this._hashFn(key);\n } else {\n if (keyType === 'number') {\n // TODO numeric key should has its own hash\n strKey = <string>key;\n } else {\n strKey = <string>key;\n }\n }\n return strKey;\n }\n}\n\n/**\n * 1. Maintaining the Order of Element Insertion: Unlike HashMap, LinkedHashMap maintains the order in which entries are inserted. Therefore, when you traverse it, entries will be returned in the order they were inserted into the map.\n * 2. Based on Hash Table and Linked List: It combines the structures of a hash table and a linked list, using the hash table to ensure fast access, while maintaining the order of entries through the linked list.\n * 3. Time Complexity: Similar to HashMap, LinkedHashMap offers constant-time performance for get and put operations in most cases.\n */\nexport class LinkedHashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {\n protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;\n\n /**\n * The constructor initializes a LinkedHashMap object with an optional raw collection and options.\n * @param entryOrRawElements - The `entryOrRawElements` parameter is an iterable collection of elements. It is\n * used to initialize the HashMapLinked instance with key-value pairs. Each element in the\n * `entryOrRawElements` is converted to a key-value pair using the `toEntryFn` function (if provided) and\n * then added to the HashMap\n * @param [options] - The `options` parameter is an optional object that can contain the following\n * properties:\n */\n constructor(entryOrRawElements: Iterable<R | [K, V]> = [], options?: LinkedHashMapOptions<K, V, R>) {\n super();\n this._sentinel = <HashMapLinkedNode<K, V>>{};\n this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;\n\n if (options) {\n const { hashFn, objHashFn, toEntryFn } = options;\n if (hashFn) this._hashFn = hashFn;\n if (objHashFn) this._objHashFn = objHashFn;\n\n if (toEntryFn) {\n this._toEntryFn = toEntryFn;\n }\n }\n\n if (entryOrRawElements) {\n this.setMany(entryOrRawElements);\n }\n }\n\n protected _hashFn: (key: K) => string = (key: K) => String(key);\n\n /**\n * The function returns the hash function used for generating a hash value for a given key.\n * @returns The hash function that takes a key of type K and returns a string.\n */\n get hashFn(): (key: K) => string {\n return this._hashFn;\n }\n\n protected _objHashFn: (key: K) => object = (key: K) => <object>key;\n\n /**\n * The function returns the object hash function.\n * @returns The function `objHashFn` is being returned.\n */\n get objHashFn(): (key: K) => object {\n return this._objHashFn;\n }\n\n protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};\n\n /**\n * The function returns a record of HashMapLinkedNode objects with string keys.\n * @returns The method is returning a Record object, which is a TypeScript type that represents an\n * object with string keys and values that are HashMapLinkedNode objects with keys of type K and\n * values of type V or undefined.\n */\n get noObjMap(): Record<string, HashMapLinkedNode<K, V | undefined>> {\n return this._noObjMap;\n }\n\n protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();\n\n /**\n * The function returns the WeakMap object used to map objects to HashMapLinkedNode instances.\n * @returns The `objMap` property is being returned.\n */\n get objMap(): WeakMap<object, HashMapLinkedNode<K, V | undefined>> {\n return this._objMap;\n }\n\n protected _head: HashMapLinkedNode<K, V | undefined>;\n\n /**\n * The function returns the head node of a HashMapLinkedNode.\n * @returns The method `getHead()` is returning a `HashMapLinkedNode` object with key type `K` and\n * a value type `V | undefined`.\n */\n get head(): HashMapLinkedNode<K, V | undefined> {\n return this._head;\n }\n\n protected _tail: HashMapLinkedNode<K, V | undefined>;\n\n /**\n * The function returns the tail node of a HashMapLinkedNode.\n * @returns The `_tail` property of type `HashMapLinkedNode<K, V | undefined>` is being returned.\n */\n get tail(): HashMapLinkedNode<K, V | undefined> {\n return this._tail;\n }\n\n protected _toEntryFn?: (rawElement: R) => [K, V] = (rawElement: R) => {\n if (this.isEntry(rawElement)) {\n // TODO, For performance optimization, it may be necessary to only inspect the first element traversed.\n return rawElement;\n } else {\n throw new Error(\n \"If the provided entryOrRawElements does not adhere to the [key, value] type format, the toEntryFn in the constructor's options parameter needs to specified.\"\n );\n }\n };\n\n /**\n * The function returns the value of the _toEntryFn property.\n * @returns The function being returned is `this._toEntryFn`.\n */\n get toEntryFn() {\n return this._toEntryFn;\n }\n\n protected _size = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object.\n */\n get size() {\n return this._size;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function returns the key-value pair at the front of a data structure.\n * @returns The front element of the data structure, represented as a tuple with a key (K) and a\n * value (V).\n */\n get first() {\n if (this._size === 0) return;\n return <[K, V]>[this.head.key, this.head.value];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function returns the key-value pair at the end of a data structure.\n * @returns The method is returning an array containing the key-value pair of the tail element in the\n * data structure.\n */\n get last() {\n if (this._size === 0) return;\n return <[K, V]>[this.tail.key, this.tail.value];\n }\n\n /**\n * The `begin()` function in TypeScript iterates over a linked list and yields key-value pairs.\n */\n *begin() {\n let node = this.head;\n while (node !== this._sentinel) {\n yield [node.key, node.value];\n node = node.next;\n }\n }\n\n /**\n * The function `reverseBegin()` iterates over a linked list in reverse order, yielding each node's\n * key and value.\n */\n *reverseBegin() {\n let node = this.tail;\n while (node !== this._sentinel) {\n yield [node.key, node.value];\n node = node.prev;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `set` function adds a new key-value pair to a data structure, either using an object key or a\n * string key.\n * @param {K} key - The `key` parameter is the key to be set in the data structure. It can be of any\n * type, but typically it is a string or symbol.\n * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the\n * value associated with the key being set in the data structure.\n * @returns the size of the data structure after the key-value pair has been set.\n */\n set(key: K, value?: V): boolean {\n let node;\n const isNewKey = !this.has(key); // Check if the key is new\n\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n node = this.objMap.get(hash);\n\n if (!node && isNewKey) {\n // Create a new node\n node = { key: <K>hash, value, prev: this.tail, next: this._sentinel };\n this.objMap.set(hash, node);\n } else if (node) {\n // Update the value of an existing node\n node.value = value;\n }\n } else {\n const hash = this._hashFn(key);\n node = this.noObjMap[hash];\n\n if (!node && isNewKey) {\n this.noObjMap[hash] = node = { key, value, prev: this.tail, next: this._sentinel };\n } else if (node) {\n // Update the value of an existing node\n node.value = value;\n }\n }\n\n if (node && isNewKey) {\n // Update the head and tail of the linked list\n if (this._size === 0) {\n this._head = node;\n this._sentinel.next = node;\n } else {\n this.tail.next = node;\n node.prev = this.tail; // Make sure that the prev of the new node points to the current tail node\n }\n this._tail = node;\n this._sentinel.prev = node;\n this._size++;\n }\n\n return true;\n }\n\n /**\n * The function `setMany` takes an iterable collection, converts each element into a key-value pair\n * using a provided function, and sets each key-value pair in the current object, returning an array\n * of booleans indicating the success of each set operation.\n * @param entryOrRawElements - The entryOrRawElements parameter is an iterable collection of elements of type\n * R.\n * @returns The `setMany` function returns an array of booleans.\n */\n setMany(entryOrRawElements: Iterable<R | [K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const rawEle of entryOrRawElements) {\n let key: K | undefined, value: V | undefined;\n if (this.isEntry(rawEle)) {\n key = rawEle[0];\n value = rawEle[1];\n } else if (this._toEntryFn) {\n const item = this._toEntryFn(rawEle);\n key = item[0];\n value = item[1];\n }\n\n if (key !== undefined && value !== undefined) results.push(this.set(key, value));\n }\n return results;\n }\n\n /**\n * The function checks if a given key exists in a map, using different logic depending on whether the\n * key is a weak key or not.\n * @param {K} key - The `key` parameter is the key that is being checked for existence in the map.\n * @returns The method `has` is returning a boolean value.\n */\n override has(key: K): boolean {\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n return this.objMap.has(hash);\n } else {\n const hash = this._hashFn(key);\n return hash in this.noObjMap;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `get` retrieves the value associated with a given key from a map, either by using the\n * key directly or by using an index stored in the key object.\n * @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be\n * of any type, but typically it is a string or symbol.\n * @returns The value associated with the given key is being returned. If the key is an object key,\n * the value is retrieved from the `_nodes` array using the index stored in the `OBJ_KEY_INDEX`\n * property of the key. If the key is a string key, the value is retrieved from the `_noObjMap` object\n * using the key itself. If the key is not found, `undefined` is\n */\n override get(key: K): V | undefined {\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n const node = this.objMap.get(hash);\n return node ? node.value : undefined;\n } else {\n const hash = this._hashFn(key);\n const node = this.noObjMap[hash];\n return node ? node.value : undefined;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `at` retrieves the key-value pair at a specified index in a linked list.\n * @param {number} index - The index parameter is a number that represents the position of the\n * element we want to retrieve from the data structure.\n * @returns The method `at(index: number)` is returning an array containing the key-value pair at\n * the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,\n * where `K` is the key and `V` is the value.\n */\n at(index: number): V | undefined {\n rangeCheck(index, 0, this._size - 1);\n let node = this.head;\n while (index--) {\n node = node.next;\n }\n return node.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a key-value pair from a map-like data structure.\n * @param {K} key - The `key` parameter is the key that you want to delete from the data structure.\n * It can be of any type, but typically it is a string or an object.\n * @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key\n * was not found.\n */\n delete(key: K): boolean {\n let node;\n\n if (isWeakKey(key)) {\n const hash = this._objHashFn(key);\n // Get nodes from WeakMap\n node = this.objMap.get(hash);\n\n if (!node) {\n return false; // If the node does not exist, return false\n }\n\n // Remove nodes from WeakMap\n this.objMap.delete(hash);\n } else {\n const hash = this._hashFn(key);\n // Get nodes from noObjMap\n node = this.noObjMap[hash];\n\n if (!node) {\n return false; // If the node does not exist, return false\n }\n\n // Remove nodes from orgMap\n delete this.noObjMap[hash];\n }\n\n // Remove node from doubly linked list\n this._deleteNode(node);\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `deleteAt` function deletes a node at a specified index in a linked list.\n * @param {number} index - The index parameter represents the position at which the node should be\n * deleted in the linked list.\n * @returns The size of the list after deleting the element at the specified index.\n */\n deleteAt(index: number): boolean {\n rangeCheck(index, 0, this._size - 1);\n let node = this.head;\n while (index--) {\n node = node.next;\n }\n return this._deleteNode(node);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if a data structure is empty by comparing its size to zero.\n * @returns The method is returning a boolean value indicating whether the size of the object is 0 or\n * not.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * The function checks if a given element is an array with exactly two elements.\n * @param {any} rawElement - The `rawElement` parameter is of type `any`, which means it can be any\n * data type.\n * @returns a boolean value.\n */\n isEntry(rawElement: any): rawElement is [K, V] {\n return Array.isArray(rawElement) && rawElement.length === 2;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function clears all the entries in a data structure and resets its properties.\n */\n clear(): void {\n this._noObjMap = {};\n this._size = 0;\n this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function creates a new instance of a `LinkedHashMap` with the same key-value pairs as\n * the original.\n * @returns The `clone()` method is returning a new instance of `LinkedHashMap<K, V>` that is a clone\n * of the original `LinkedHashMap` object.\n */\n clone(): LinkedHashMap<K, V> {\n const cloned = new LinkedHashMap<K, V>([], { hashFn: this._hashFn, objHashFn: this._objHashFn });\n for (const entry of this) {\n const [key, value] = entry;\n cloned.set(key, value);\n }\n return cloned;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new `LinkedHashMap` containing key-value pairs from the original\n * map that satisfy a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes four arguments:\n * `value`, `key`, `index`, and `this`. It should return a boolean value indicating whether the\n * current element should be included in the filtered map or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the `predicate` function. It is used when you want to bind a\n * specific object as the context for the `predicate` function. If `thisArg` is not provided, `this\n * @returns a new `LinkedHashMap` object that contains the key-value pairs from the original\n * `LinkedHashMap` object that satisfy the given predicate function.\n */\n filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): LinkedHashMap<K, V> {\n const filteredMap = new LinkedHashMap<K, V>();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index, this)) {\n filteredMap.set(key, value);\n }\n index++;\n }\n return filteredMap;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function in TypeScript creates a new `LinkedHashMap` by applying a callback function to\n * each key-value pair in the original map.\n * @param callback - The callback parameter is a function that will be called for each key-value pair\n * in the map. It takes four arguments: the value of the current key-value pair, the key of the\n * current key-value pair, the index of the current key-value pair, and the map itself. The callback\n * function should\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. If provided, the callback function will\n * be called with `thisArg` as its `this` value. If not provided, `this` will refer to the current\n * map\n * @returns a new `LinkedHashMap` object with the values mapped according to the provided callback\n * function.\n */\n map<VM>(callback: EntryCallback<K, V, VM>, thisArg?: any): LinkedHashMap<K, VM> {\n const mappedMap = new LinkedHashMap<K, VM>();\n let index = 0;\n for (const [key, value] of this) {\n const newValue = callback.call(thisArg, value, key, index, this);\n mappedMap.set(key, newValue);\n index++;\n }\n return mappedMap;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n * where n is the number of entries in the LinkedHashMap.\n *\n * The above function is an iterator that yields key-value pairs from a linked list.\n */\n protected *_getIterator() {\n let node = this.head;\n while (node !== this._sentinel) {\n yield [node.key, node.value] as [K, V];\n node = node.next;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_deleteNode` function removes a node from a doubly linked list and updates the head and tail\n * pointers if necessary.\n * @param node - The `node` parameter is an instance of the `HashMapLinkedNode` class, which\n * represents a node in a linked list. It contains a key-value pair and references to the previous\n * and next nodes in the list.\n */\n protected _deleteNode(node: HashMapLinkedNode<K, V | undefined>): boolean {\n const { prev, next } = node;\n prev.next = next;\n next.prev = prev;\n\n if (node === this.head) {\n this._head = next;\n }\n\n if (node === this.tail) {\n this._tail = prev;\n }\n\n this._size -= 1;\n return true;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback, SinglyLinkedListOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\nexport class SinglyLinkedListNode<E = any> {\n /**\n * The constructor function initializes an instance of a class with a given value and sets the next property to undefined.\n * @param {E} value - The \"value\" parameter is of type E, which means it can be any data type. It represents the value that\n * will be stored in the node of a linked list.\n */\n constructor(value: E) {\n this._value = value;\n this._next = undefined;\n }\n\n protected _value: E;\n\n /**\n * The function returns the value of a protected variable.\n * @returns The value of the variable `_value` is being returned.\n */\n get value(): E {\n return this._value;\n }\n\n /**\n * The above function sets the value of a variable.\n * @param {E} value - The parameter \"value\" is of type E, which means it can be any type.\n */\n set value(value: E) {\n this._value = value;\n }\n\n protected _next: SinglyLinkedListNode<E> | undefined;\n\n /**\n * The `next` function returns the next node in a singly linked list.\n * @returns The `next` property is being returned. It can be either a `SinglyLinkedListNode<E>`\n * object or `undefined`.\n */\n get next(): SinglyLinkedListNode<E> | undefined {\n return this._next;\n }\n\n /**\n * The \"next\" property of a SinglyLinkedListNode is set to the provided value.\n * @param {SinglyLinkedListNode<E> | undefined} value - The `value` parameter is of type\n * `SinglyLinkedListNode<E> | undefined`. This means that it can accept either a\n * `SinglyLinkedListNode` object or `undefined` as its value.\n */\n set next(value: SinglyLinkedListNode<E> | undefined) {\n this._next = value;\n }\n}\n\nexport class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R, SinglyLinkedList<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: SinglyLinkedListOptions<E, R>) {\n super(options);\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else {\n this.push(el as E);\n }\n }\n }\n }\n\n protected _head: SinglyLinkedListNode<E> | undefined;\n\n /**\n * The `head` function returns the first node of a singly linked list.\n * @returns The method is returning either a SinglyLinkedListNode object or undefined.\n */\n get head(): SinglyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: SinglyLinkedListNode<E> | undefined;\n\n /**\n * The `tail` function returns the last node of a singly linked list.\n * @returns The method is returning either a SinglyLinkedListNode object or undefined.\n */\n get tail(): SinglyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n /**\n * The above function returns the value of the first element in a linked list, or undefined if the\n * list is empty.\n * @returns The value of the first node in the linked list, or undefined if the linked list is empty.\n */\n get first(): E | undefined {\n return this.head?.value;\n }\n\n /**\n * The function returns the value of the last element in a linked list, or undefined if the list is\n * empty.\n * @returns The value of the last node in the linked list, or undefined if the linked list is empty.\n */\n get last(): E | undefined {\n return this.tail?.value;\n }\n\n protected _size: number = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `fromArray` function creates a new SinglyLinkedList instance and populates it with the elements from the given\n * array.\n * @param {E[]} data - The `data` parameter is an array of elements of type `E`.\n * @returns The `fromArray` function returns a `SinglyLinkedList` object.\n */\n static fromArray<E>(data: E[]) {\n const singlyLinkedList = new SinglyLinkedList<E>();\n for (const item of data) {\n singlyLinkedList.push(item);\n }\n return singlyLinkedList;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds a new element to the end of a singly linked list.\n * @param {E} element - The \"element\" parameter represents the value of the element that you want to\n * add to the linked list.\n * @returns The `push` method is returning a boolean value, `true`.\n */\n push(element: E): boolean {\n const newNode = new SinglyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n this.tail!.next = newNode;\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `pop` function removes and returns the value of the last element in a linked list.\n * @returns The method is returning the value of the element that is being popped from the end of the\n * list.\n */\n pop(): E | undefined {\n if (!this.head) return undefined;\n if (this.head === this.tail) {\n const value = this.head.value;\n this._head = undefined;\n this._tail = undefined;\n this._size--;\n return value;\n }\n\n let current = this.head;\n while (current.next !== this.tail) {\n current = current.next!;\n }\n const value = this.tail!.value;\n current.next = undefined;\n this._tail = current;\n this._size--;\n return value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift()` function removes and returns the value of the first element in a linked list.\n * @returns The value of the removed node.\n */\n shift(): E | undefined {\n if (!this.head) return undefined;\n const removedNode = this.head;\n this._head = this.head.next;\n this._size--;\n return removedNode.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The unshift function adds a new element to the beginning of a singly linked list.\n * @param {E} element - The \"element\" parameter represents the value of the element that you want to\n * add to the beginning of the singly linked list.\n * @returns The `unshift` method is returning a boolean value, `true`.\n */\n unshift(element: E): boolean {\n const newNode = new SinglyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n newNode.next = this.head;\n this._head = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `at` returns the value at a specified index in a linked list, or undefined if the index is out of range.\n * @param {number} index - The index parameter is a number that represents the position of the element we want to\n * retrieve from the list.\n * @returns The method `at(index: number): E | undefined` returns the value at the specified index in the linked list, or\n * `undefined` if the index is out of bounds.\n */\n at(index: number): E | undefined {\n if (index < 0 || index >= this._size) return undefined;\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current!.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `getNodeAt` returns the node at a given index in a singly linked list.\n * @param {number} index - The `index` parameter is a number that represents the position of the node we want to\n * retrieve from the linked list. It indicates the zero-based index of the node we want to access.\n * @returns The method `getNodeAt(index: number)` returns a `SinglyLinkedListNode<E>` object if the node at the\n * specified index exists, or `undefined` if the index is out of bounds.\n */\n getNodeAt(index: number): SinglyLinkedListNode<E> | undefined {\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `deleteAt` function removes an element at a specified index from a linked list and returns the removed element.\n * @param {number} index - The index parameter represents the position of the element that needs to be deleted in the\n * data structure. It is of type number.\n * @returns The method `deleteAt` returns the value of the node that was deleted, or `undefined` if the index is out of\n * bounds.\n */\n deleteAt(index: number): boolean {\n if (index < 0 || index >= this._size) return false;\n if (index === 0) {\n this.shift();\n return true;\n }\n if (index === this._size - 1) {\n this.pop();\n return true;\n }\n\n const prevNode = this.getNodeAt(index - 1);\n const removedNode = prevNode!.next;\n prevNode!.next = removedNode!.next;\n this._size--;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The delete function removes a node with a specific value from a singly linked list.\n * @param {E | SinglyLinkedListNode<E>} valueOrNode - The `valueOrNode` parameter can accept either a value of type `E`\n * or a `SinglyLinkedListNode<E>` object.\n * @returns The `delete` method returns a boolean value. It returns `true` if the value or node is found and\n * successfully deleted from the linked list, and `false` if the value or node is not found in the linked list.\n */\n delete(valueOrNode: E | SinglyLinkedListNode<E> | undefined): boolean {\n if (valueOrNode === undefined) return false;\n let value: E;\n if (valueOrNode instanceof SinglyLinkedListNode) {\n value = valueOrNode.value;\n } else {\n value = valueOrNode;\n }\n let current = this.head,\n prev = undefined;\n\n while (current) {\n if (current.value === value) {\n if (prev === undefined) {\n this._head = current.next;\n if (current === this.tail) {\n this._tail = undefined;\n }\n } else {\n prev.next = current.next;\n if (current === this.tail) {\n this._tail = prev;\n }\n }\n this._size--;\n return true;\n }\n prev = current;\n current = current.next;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `addAt` function inserts a value at a specified index in a singly linked list.\n * @param {number} index - The index parameter represents the position at which the new value should be inserted in the\n * linked list. It is of type number.\n * @param {E} value - The `value` parameter represents the value that you want to insert into the linked list at the\n * specified index.\n * @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`\n * if the index is out of bounds.\n */\n addAt(index: number, value: E): boolean {\n if (index < 0 || index > this._size) return false;\n if (index === 0) {\n this.unshift(value);\n return true;\n }\n if (index === this._size) {\n this.push(value);\n return true;\n }\n\n const newNode = new SinglyLinkedListNode(value);\n const prevNode = this.getNodeAt(index - 1);\n newNode.next = prevNode!.next;\n prevNode!.next = newNode;\n this._size++;\n return true;\n }\n\n /**\n * The function checks if the length of a data structure is equal to zero and returns a boolean value indicating\n * whether it is empty or not.\n * @returns A boolean value indicating whether the length of the object is equal to 0.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * The `clear` function resets the linked list by setting the head, tail, and length to undefined and 0 respectively.\n */\n clear(): void {\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toArray` function converts a linked list into an array.\n * @returns The `toArray()` method is returning an array of type `E[]`.\n */\n toArray(): E[] {\n const array: E[] = [];\n let current = this.head;\n while (current) {\n array.push(current.value);\n current = current.next;\n }\n return array;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reverse` function reverses the order of the nodes in a singly linked list.\n * @returns The reverse() method does not return anything. It has a return type of void.\n */\n reverse(): this {\n if (!this.head || this.head === this.tail) return this;\n\n let prev: SinglyLinkedListNode<E> | undefined = undefined;\n let current: SinglyLinkedListNode<E> | undefined = this.head;\n let next: SinglyLinkedListNode<E> | undefined = undefined;\n\n while (current) {\n next = current.next;\n current.next = prev;\n prev = current;\n current = next;\n }\n\n [this._head, this._tail] = [this.tail!, this.head!];\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `indexOf` function returns the index of the first occurrence of a given value in a linked list.\n * @param {E} value - The value parameter is the value that you want to find the index of in the linked list.\n * @returns The method is returning the index of the first occurrence of the specified value in the linked list. If the\n * value is not found, it returns -1.\n */\n indexOf(value: E): number {\n let index = 0;\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n return index;\n }\n index++;\n current = current.next;\n }\n\n return -1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function finds a node in a singly linked list by its value and returns the node if found, otherwise returns\n * undefined.\n * @param {E} value - The value parameter is the value that we want to search for in the linked list.\n * @returns a `SinglyLinkedListNode<E>` if a node with the specified value is found in the linked list. If no node with\n * the specified value is found, the function returns `undefined`.\n */\n getNode(value: E): SinglyLinkedListNode<E> | undefined {\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n return current;\n }\n current = current.next;\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `addBefore` function inserts a new value before an existing value in a singly linked list.\n * @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node that you want to insert the\n * new value before. It can be either the value itself or a node containing the value in the linked list.\n * @param {E} newValue - The `newValue` parameter represents the value that you want to insert into the linked list.\n * @returns The method `addBefore` returns a boolean value. It returns `true` if the new value was successfully\n * inserted before the existing value, and `false` otherwise.\n */\n addBefore(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {\n if (!this.head) return false;\n\n let existingValue: E;\n if (existingValueOrNode instanceof SinglyLinkedListNode) {\n existingValue = existingValueOrNode.value;\n } else {\n existingValue = existingValueOrNode;\n }\n if (this.head.value === existingValue) {\n this.unshift(newValue);\n return true;\n }\n\n let current = this.head;\n while (current.next) {\n if (current.next.value === existingValue) {\n const newNode = new SinglyLinkedListNode(newValue);\n newNode.next = current.next;\n current.next = newNode;\n this._size++;\n return true;\n }\n current = current.next;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `addAfter` function inserts a new node with a given value after an existing node in a singly linked list.\n * @param {E | SinglyLinkedListNode<E>} existingValueOrNode - The existing value or node in the linked list after which\n * the new value will be inserted. It can be either the value of the existing node or the existing node itself.\n * @param {E} newValue - The value that you want to insert into the linked list after the existing value or node.\n * @returns The method returns a boolean value. It returns true if the new value was successfully inserted after the\n * existing value or node, and false if the existing value or node was not found in the linked list.\n */\n addAfter(existingValueOrNode: E | SinglyLinkedListNode<E>, newValue: E): boolean {\n let existingNode: E | SinglyLinkedListNode<E> | undefined;\n\n if (existingValueOrNode instanceof SinglyLinkedListNode) {\n existingNode = existingValueOrNode;\n } else {\n existingNode = this.getNode(existingValueOrNode);\n }\n\n if (existingNode) {\n const newNode = new SinglyLinkedListNode(newValue);\n newNode.next = existingNode.next;\n existingNode.next = newNode;\n if (existingNode === this.tail) {\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function counts the number of occurrences of a given value in a linked list.\n * @param {E} value - The value parameter is the value that you want to count the occurrences of in the linked list.\n * @returns The count of occurrences of the given value in the linked list.\n */\n countOccurrences(value: E): number {\n let count = 0;\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n count++;\n }\n current = current.next;\n }\n\n return count;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function returns a new instance of the `SinglyLinkedList` class with the same values\n * as the original list.\n * @returns The `clone()` method is returning a new instance of the `SinglyLinkedList` class, which\n * is a clone of the original list.\n */\n clone(): SinglyLinkedList<E, R> {\n return new SinglyLinkedList<E, R>(this, { toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new SinglyLinkedList by iterating over the elements of the current\n * list and applying a callback function to each element to determine if it should be included in the\n * filtered list.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * list. It takes three arguments: the current element, the index of the current element, and the\n * list itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list or not\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `SinglyLinkedList` object that contains the\n * elements that pass the filter condition specified by the `callback` function.\n */\n filter(callback: ElementCallback<E, R, boolean, SinglyLinkedList<E, R>>, thisArg?: any): SinglyLinkedList<E, R> {\n const filteredList = new SinglyLinkedList<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.push(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and returns a new SinglyLinkedList with the results\n * of applying the callback to each element in the original list.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the original list. It takes three arguments: `current` (the current element being processed),\n * `index` (the index of the current element), and `this` (the original list). It should return a\n * value\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * convert the raw element (`RR`) to the desired element type (`T`). It takes the raw element as\n * input and returns the converted element. If this parameter is not provided, the raw element will\n * be used as is.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `SinglyLinkedList` class with the mapped elements.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, SinglyLinkedList<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): SinglyLinkedList<EM, RM> {\n const mappedList = new SinglyLinkedList<EM, RM>([], { toElementFn });\n let index = 0;\n for (const current of this) {\n mappedList.push(callback.call(thisArg, current, index, this));\n index++;\n }\n\n return mappedList;\n }\n\n /**\n * The function `_getIterator` returns an iterable iterator that yields the values of a linked list.\n */\n protected *_getIterator(): IterableIterator<E> {\n let current = this.head;\n\n while (current) {\n yield current.value;\n current = current.next;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { DoublyLinkedListOptions, ElementCallback } from '../../types';\nimport { IterableElementBase } from '../base';\n\nexport class DoublyLinkedListNode<E = any> {\n /**\n * The constructor function initializes the value, next, and previous properties of an object.\n * @param {E} value - The \"value\" parameter is the value that will be stored in the node. It can be of any data type, as it\n * is defined as a generic type \"E\".\n */\n constructor(value: E) {\n this._value = value;\n this._next = undefined;\n this._prev = undefined;\n }\n\n protected _value: E;\n\n /**\n * The function returns the value of a protected variable.\n * @returns The value of the variable `_value` is being returned.\n */\n get value(): E {\n return this._value;\n }\n\n /**\n * The above function sets the value of a variable.\n * @param {E} value - The parameter \"value\" is of type E, which means it can be any type.\n */\n set value(value: E) {\n this._value = value;\n }\n\n protected _next: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The \"next\" function returns the next node in a doubly linked list.\n * @returns The `next` property is being returned. It can be either a `DoublyLinkedListNode<E>`\n * object or `undefined`.\n */\n get next(): DoublyLinkedListNode<E> | undefined {\n return this._next;\n }\n\n /**\n * The \"next\" property of a DoublyLinkedListNode is set to the provided value.\n * @param {DoublyLinkedListNode<E> | undefined} value - The `value` parameter is of type\n * `DoublyLinkedListNode<E> | undefined`. This means that it can accept either a\n * `DoublyLinkedListNode` object or `undefined` as its value.\n */\n set next(value: DoublyLinkedListNode<E> | undefined) {\n this._next = value;\n }\n\n protected _prev: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The `prev` function returns the previous node in a doubly linked list.\n * @returns The `prev` property of the `DoublyLinkedListNode` class is being returned. It can either\n * be a `DoublyLinkedListNode` object or `undefined`.\n */\n get prev(): DoublyLinkedListNode<E> | undefined {\n return this._prev;\n }\n\n /**\n * The function sets the previous node of a doubly linked list node.\n * @param {DoublyLinkedListNode<E> | undefined} value - The `value` parameter is of type\n * `DoublyLinkedListNode<E> | undefined`. This means that it can accept either a\n * `DoublyLinkedListNode` object or `undefined` as its value.\n */\n set prev(value: DoublyLinkedListNode<E> | undefined) {\n this._prev = value;\n }\n}\n\n/**\n * 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.\n * 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.\n * 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.\n * 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.\n */\nexport class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R, DoublyLinkedList<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: DoublyLinkedListOptions<E, R>) {\n super(options);\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else this.push(el as E);\n }\n }\n }\n\n protected _head: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The `head` function returns the first node of a doubly linked list.\n * @returns The method `getHead()` returns either a `DoublyLinkedListNode<E>` object or `undefined`.\n */\n get head(): DoublyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: DoublyLinkedListNode<E> | undefined;\n\n /**\n * The `tail` function returns the last node of a doubly linked list.\n * @returns The `get tail()` method is returning either a `DoublyLinkedListNode<E>` object or\n * `undefined`.\n */\n get tail(): DoublyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n protected _size: number;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `get first` function returns the first node in a doubly linked list, or undefined if the list is empty.\n * @returns The method `get first()` returns the first node of the doubly linked list, or `undefined` if the list is empty.\n */\n get first(): E | undefined {\n return this.head?.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `get last` function returns the last node in a doubly linked list, or undefined if the list is empty.\n * @returns The method `get last()` returns the last node of the doubly linked list, or `undefined` if the list is empty.\n */\n get last(): E | undefined {\n return this.tail?.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `fromArray` function creates a new instance of a DoublyLinkedList and populates it with the elements from the\n * given array.\n * @param {E[]} data - The `data` parameter is an array of elements of type `E`.\n * @returns The `fromArray` function returns a DoublyLinkedList object.\n */\n static fromArray<E>(data: E[]) {\n return new DoublyLinkedList<E>(data);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds a new element to the end of a doubly linked list.\n * @param {E} element - The \"element\" parameter represents the value that you want to add to the\n * doubly linked list.\n * @returns The `push` method is returning a boolean value, `true`.\n */\n push(element: E): boolean {\n const newNode = new DoublyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n newNode.prev = this.tail;\n this.tail!.next = newNode;\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop()` function removes and returns the value of the last element in a linked list.\n * @returns The method is returning the value of the removed node.\n */\n pop(): E | undefined {\n if (!this.tail) return undefined;\n const removedNode = this.tail;\n if (this.head === this.tail) {\n this._head = undefined;\n this._tail = undefined;\n } else {\n this._tail = removedNode.prev;\n this.tail!.next = undefined;\n }\n this._size--;\n return removedNode.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift()` function removes and returns the value of the first element in a doubly linked list.\n * @returns The value of the removed node.\n */\n shift(): E | undefined {\n if (!this.head) return undefined;\n const removedNode = this.head;\n if (this.head === this.tail) {\n this._head = undefined;\n this._tail = undefined;\n } else {\n this._head = removedNode.next;\n this.head!.prev = undefined;\n }\n this._size--;\n return removedNode.value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The unshift function adds a new element to the beginning of a doubly linked list.\n * @param {E} element - The \"element\" parameter represents the value of the element that you want to\n * add to the beginning of the doubly linked list.\n * @returns The `unshift` method is returning a boolean value, `true`.\n */\n unshift(element: E): boolean {\n const newNode = new DoublyLinkedListNode(element);\n if (!this.head) {\n this._head = newNode;\n this._tail = newNode;\n } else {\n newNode.next = this.head;\n this.head!.prev = newNode;\n this._head = newNode;\n }\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `at` function returns the value at a specified index in a linked list, or undefined if the index is out of bounds.\n * @param {number} index - The index parameter is a number that represents the position of the element we want to\n * retrieve from the list.\n * @returns The method is returning the value at the specified index in the linked list. If the index is out of bounds\n * or the linked list is empty, it will return undefined.\n */\n at(index: number): E | undefined {\n if (index < 0 || index >= this._size) return undefined;\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current!.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `getNodeAt` returns the node at a given index in a doubly linked list, or undefined if the index is out of\n * range.\n * @param {number} index - The `index` parameter is a number that represents the position of the node we want to\n * retrieve from the doubly linked list. It indicates the zero-based index of the node we want to access.\n * @returns The method `getNodeAt(index: number)` returns a `DoublyLinkedListNode<E>` object if the index is within the\n * valid range of the linked list, otherwise it returns `undefined`.\n */\n getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {\n if (index < 0 || index >= this._size) return undefined;\n let current = this.head;\n for (let i = 0; i < index; i++) {\n current = current!.next;\n }\n return current;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `findNodeByValue` searches for a node with a specific value in a doubly linked list and returns the\n * node if found, otherwise it returns undefined.\n * @param {E} value - The `value` parameter is the value that we want to search for in the doubly linked list.\n * @returns The function `findNodeByValue` returns a `DoublyLinkedListNode<E>` if a node with the specified value `value`\n * is found in the linked list. If no such node is found, it returns `undefined`.\n */\n getNode(value: E | undefined): DoublyLinkedListNode<E> | undefined {\n let current = this.head;\n\n while (current) {\n if (current.value === value) {\n return current;\n }\n current = current.next;\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `insert` function inserts a value at a specified index in a doubly linked list.\n * @param {number} index - The index parameter represents the position at which the new value should be inserted in the\n * DoublyLinkedList. It is of type number.\n * @param {E} value - The `value` parameter represents the value that you want to insert into the Doubly Linked List at the\n * specified index.\n * @returns The `insert` method returns a boolean value. It returns `true` if the insertion is successful, and `false`\n * if the index is out of bounds.\n */\n addAt(index: number, value: E): boolean {\n if (index < 0 || index > this._size) return false;\n if (index === 0) {\n this.unshift(value);\n return true;\n }\n if (index === this._size) {\n this.push(value);\n return true;\n }\n\n const newNode = new DoublyLinkedListNode(value);\n const prevNode = this.getNodeAt(index - 1);\n const nextNode = prevNode!.next;\n newNode.prev = prevNode;\n newNode.next = nextNode;\n prevNode!.next = newNode;\n nextNode!.prev = newNode;\n this._size++;\n return true;\n }\n\n /**\n * Time Complexity: O(1) or O(n)\n * Space Complexity: O(1)\n *\n * The `addBefore` function inserts a new value before an existing value or node in a doubly linked list.\n * @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list\n * before which the new value will be inserted. It can be either the value of the existing node or the existing node\n * itself.\n * @param {E} newValue - The `newValue` parameter represents the value that you want to insert into the doubly linked\n * list.\n * @returns The method returns a boolean value. It returns `true` if the insertion is successful, and `false` if the\n * insertion fails.\n */\n addBefore(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {\n let existingNode;\n\n if (existingValueOrNode instanceof DoublyLinkedListNode) {\n existingNode = existingValueOrNode;\n } else {\n existingNode = this.getNode(existingValueOrNode);\n }\n\n if (existingNode) {\n const newNode = new DoublyLinkedListNode(newValue);\n newNode.prev = existingNode.prev;\n if (existingNode.prev) {\n existingNode.prev.next = newNode;\n }\n newNode.next = existingNode;\n existingNode.prev = newNode;\n if (existingNode === this.head) {\n this._head = newNode;\n }\n this._size++;\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(1) or O(n)\n * Space Complexity: O(1)\n *\n * The `addAfter` function inserts a new node with a given value after an existing node in a doubly linked list.\n * @param {E | DoublyLinkedListNode<E>} existingValueOrNode - The existing value or node in the doubly linked list\n * after which the new value will be inserted. It can be either the value of the existing node or the existing node\n * itself.\n * @param {E} newValue - The value that you want to insert into the doubly linked list.\n * @returns The method returns a boolean value. It returns true if the insertion is successful, and false if the\n * existing value or node is not found in the doubly linked list.\n */\n addAfter(existingValueOrNode: E | DoublyLinkedListNode<E>, newValue: E): boolean {\n let existingNode;\n\n if (existingValueOrNode instanceof DoublyLinkedListNode) {\n existingNode = existingValueOrNode;\n } else {\n existingNode = this.getNode(existingValueOrNode);\n }\n\n if (existingNode) {\n const newNode = new DoublyLinkedListNode(newValue);\n newNode.next = existingNode.next;\n if (existingNode.next) {\n existingNode.next.prev = newNode;\n }\n newNode.prev = existingNode;\n existingNode.next = newNode;\n if (existingNode === this.tail) {\n this._tail = newNode;\n }\n this._size++;\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `deleteAt` function removes an element at a specified index from a linked list and returns the removed element.\n * @param {number} index - The index parameter represents the position of the element that needs to be deleted in the\n * data structure. It is of type number.\n * @returns The method `deleteAt` returns the value of the node that was deleted, or `undefined` if the index is out of\n * bounds.\n */\n deleteAt(index: number): boolean {\n if (index < 0 || index >= this._size) return false;\n if (index === 0) {\n this.shift();\n return true;\n }\n if (index === this._size - 1) {\n this.pop();\n return true;\n }\n\n const removedNode = this.getNodeAt(index);\n const prevNode = removedNode!.prev;\n const nextNode = removedNode!.next;\n prevNode!.next = nextNode;\n nextNode!.prev = prevNode;\n this._size--;\n return true;\n }\n\n /**\n * Time Complexity: O(1) or O(n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a node from a doubly linked list based on either the node itself or its value.\n * @param {E | DoublyLinkedListNode<E>} valOrNode - The `valOrNode` parameter can accept either a value of type `E` or\n * a `DoublyLinkedListNode<E>` object.\n * @returns The `delete` method returns a boolean value. It returns `true` if the value or node was successfully\n * deleted from the doubly linked list, and `false` if the value or node was not found in the list.\n */\n delete(valOrNode: E | DoublyLinkedListNode<E> | undefined): boolean {\n let node: DoublyLinkedListNode<E> | undefined;\n\n if (valOrNode instanceof DoublyLinkedListNode) {\n node = valOrNode;\n } else {\n node = this.getNode(valOrNode);\n }\n\n if (node) {\n if (node === this.head) {\n this.shift();\n } else if (node === this.tail) {\n this.pop();\n } else {\n const prevNode = node.prev;\n const nextNode = node.next;\n prevNode!.next = nextNode;\n nextNode!.prev = prevNode;\n this._size--;\n }\n return true;\n }\n return false;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if a variable has a size greater than zero and returns a boolean value.\n * @returns A boolean value is being returned.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function resets the linked list by setting the head, tail, and size to undefined and 0 respectively.\n */\n clear(): void {\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function returns the index of the first occurrence of a given value in a linked list.\n * @param {E} value - The parameter `value` is of type `E`, which means it can be any data type. It represents the value\n * that we are searching for in the linked list.\n * @returns The method `indexOf` returns the index of the first occurrence of the specified value `value` in the linked\n * list. If the value is not found, it returns -1.\n */\n indexOf(value: E): number {\n let index = 0;\n let current = this.head;\n while (current) {\n if (current.value === value) {\n return index;\n }\n index++;\n current = current.next;\n }\n return -1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `findBackward` function iterates through a linked list from the last node to the first node and returns the last\n * value that satisfies the given callback function, or undefined if no value satisfies the callback.\n * @param callback - A function that takes a value of type E as its parameter and returns a boolean value. This\n * function is used to determine whether a given value satisfies a certain condition.\n * @returns The method `findBackward` returns the last value in the linked list that satisfies the condition specified by\n * the callback function. If no value satisfies the condition, it returns `undefined`.\n */\n findBackward(callback: (value: E) => boolean): E | undefined {\n let current = this.tail;\n while (current) {\n if (callback(current.value)) {\n return current.value;\n }\n current = current.prev;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `reverse` function reverses the order of the elements in a doubly linked list.\n */\n reverse(): this {\n let current = this.head;\n [this._head, this._tail] = [this.tail, this.head];\n while (current) {\n const next = current.next;\n [current.prev, current.next] = [current.next, current.prev];\n current = next;\n }\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toArray` function converts a linked list into an array.\n * @returns The `toArray()` method is returning an array of type `E[]`.\n */\n toArray(): E[] {\n const array: E[] = [];\n let current = this.head;\n while (current) {\n array.push(current.value);\n current = current.next;\n }\n return array;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toReversedArray` function converts a doubly linked list into an array in reverse order.\n * @returns The `toReversedArray()` function returns an array of type `E[]`.\n */\n toReversedArray(): E[] {\n const array: E[] = [];\n let current = this.tail;\n while (current) {\n array.push(current.value);\n current = current.prev;\n }\n return array;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function creates a new instance of the `DoublyLinkedList` class with the same values\n * as the original list.\n * @returns The `clone()` method is returning a new instance of the `DoublyLinkedList` class, which\n * is a copy of the original list.\n */\n clone(): DoublyLinkedList<E, R> {\n return new DoublyLinkedList<E, R>(this);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new DoublyLinkedList by iterating over the elements of the current\n * list and applying a callback function to each element, returning only the elements for which the\n * callback function returns true.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the DoublyLinkedList. It takes three arguments: the current element, the index of the current\n * element, and the DoublyLinkedList itself. The callback function should return a boolean value\n * indicating whether the current element should be included\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `DoublyLinkedList` object that contains the\n * elements that pass the filter condition specified by the `callback` function.\n */\n filter(callback: ElementCallback<E, R, boolean, DoublyLinkedList<E, R>>, thisArg?: any): DoublyLinkedList<E, R> {\n const filteredList = new DoublyLinkedList<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.push(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and returns a new DoublyLinkedList with the results\n * of applying the callback to each element in the original list.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * original DoublyLinkedList. It takes three arguments: current (the current element being\n * processed), index (the index of the current element), and this (the original DoublyLinkedList).\n * The callback function should return a value of type\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * convert the raw element (`RR`) to the desired element type (`T`). It takes the raw element as\n * input and returns the converted element. If this parameter is not provided, the raw element will\n * be used as is.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `DoublyLinkedList` class with elements of type `T` and `RR`.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, DoublyLinkedList<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): DoublyLinkedList<EM, RM> {\n const mappedList = new DoublyLinkedList<EM, RM>([], { toElementFn });\n let index = 0;\n for (const current of this) {\n mappedList.push(callback.call(thisArg, current, index, this));\n index++;\n }\n\n return mappedList;\n }\n\n /**\n * The function returns an iterator that iterates over the values of a linked list.\n */\n protected *_getIterator(): IterableIterator<E> {\n let current = this.head;\n\n while (current) {\n yield current.value;\n current = current.next;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { SkipLinkedListOptions } from '../../types';\n\nexport class SkipListNode<K, V> {\n key: K;\n value: V;\n forward: SkipListNode<K, V>[];\n\n constructor(key: K, value: V, level: number) {\n this.key = key;\n this.value = value;\n this.forward = new Array(level);\n }\n}\n\nexport class SkipList<K, V> {\n /**\n * The constructor function initializes a SkipLinkedList object with optional options and elements.\n * @param elements - The `elements` parameter is an iterable containing key-value pairs `[K, V]`. It\n * is used to initialize the SkipLinkedList with the given key-value pairs. If no elements are\n * provided, the SkipLinkedList will be empty.\n * @param {SkipLinkedListOptions} [options] - The `options` parameter is an optional object that can\n * contain two properties:\n */\n constructor(elements: Iterable<[K, V]> = [], options?: SkipLinkedListOptions) {\n if (options) {\n const { maxLevel, probability } = options;\n if (typeof maxLevel === 'number') this._maxLevel = maxLevel;\n if (typeof probability === 'number') this._probability = probability;\n }\n\n if (elements) {\n for (const [key, value] of elements) this.add(key, value);\n }\n }\n\n protected _head: SkipListNode<K, V> = new SkipListNode<K, V>(undefined as any, undefined as any, this.maxLevel);\n\n /**\n * The function returns the head node of a SkipList.\n * @returns The method is returning a SkipListNode object with generic key type K and value type V.\n */\n get head(): SkipListNode<K, V> {\n return this._head;\n }\n\n protected _level: number = 0;\n\n /**\n * The function returns the value of the protected variable _level.\n * @returns The level property of the object.\n */\n get level(): number {\n return this._level;\n }\n\n protected _maxLevel: number = 16;\n\n /**\n * The function returns the maximum level.\n * @returns The value of the variable `_maxLevel` is being returned.\n */\n get maxLevel(): number {\n return this._maxLevel;\n }\n\n protected _probability: number = 0.5;\n\n /**\n * The function returns the probability value.\n * @returns The probability value stored in the protected variable `_probability` is being returned.\n */\n get probability(): number {\n return this._probability;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Get the value of the first element (the smallest element) in the Skip List.\n * @returns The value of the first element, or undefined if the Skip List is empty.\n */\n get first(): V | undefined {\n const firstNode = this.head.forward[0];\n return firstNode ? firstNode.value : undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Get the value of the last element (the largest element) in the Skip List.\n * @returns The value of the last element, or undefined if the Skip List is empty.\n */\n get last(): V | undefined {\n let current = this.head;\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i]) {\n current = current.forward[i];\n }\n }\n return current.value;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The add function adds a new node with a given key and value to a Skip List data structure.\n * @param {K} key - The key parameter represents the key of the node that needs to be added to the skip list.\n * @param {V} value - The \"value\" parameter represents the value associated with the key that is being added to the Skip\n * List.\n */\n add(key: K, value: V): void {\n const newNode = new SkipListNode(key, value, this._randomLevel());\n const update: SkipListNode<K, V>[] = new Array(this.maxLevel).fill(this.head);\n let current = this.head;\n\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n update[i] = current;\n }\n\n for (let i = 0; i < newNode.forward.length; i++) {\n newNode.forward[i] = update[i].forward[i];\n update[i].forward[i] = newNode;\n }\n\n if (!newNode.forward[0]) {\n this._level = Math.max(this.level, newNode.forward.length);\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `get` retrieves the value associated with a given key from a skip list data structure.\n * @param {K} key - The `key` parameter is the key of the element that we want to retrieve from the data structure.\n * @returns The method `get(key: K)` returns the value associated with the given key if it exists in the data structure,\n * otherwise it returns `undefined`.\n */\n get(key: K): V | undefined {\n let current = this.head;\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n }\n\n current = current.forward[0];\n\n if (current && current.key === key) {\n return current.value;\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function checks if a key exists in a data structure.\n * @param {K} key - The parameter \"key\" is of type K, which represents the type of the key being\n * checked.\n * @returns a boolean value.\n */\n has(key: K): boolean {\n return this.get(key) !== undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a node with a specific key from a Skip List data structure.\n * @param {K} key - The key parameter represents the key of the node that needs to be removed from the skip list.\n * @returns The `delete` method returns a boolean value. It returns `true` if the key was successfully removed from the\n * skip list, and `false` if the key was not found in the skip list.\n */\n delete(key: K): boolean {\n const update: SkipListNode<K, V>[] = new Array(this.maxLevel).fill(this.head);\n let current = this.head;\n\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n update[i] = current;\n }\n\n current = current.forward[0];\n\n if (current && current.key === key) {\n for (let i = 0; i < this.level; i++) {\n if (update[i].forward[i] !== current) {\n break;\n }\n update[i].forward[i] = current.forward[i];\n }\n while (this.level > 0 && !this.head.forward[this.level - 1]) {\n this._level--;\n }\n return true;\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Get the value of the first element in the Skip List that is greater than the given key.\n * @param key - the given key.\n * @returns The value of the first element greater than the given key, or undefined if there is no such element.\n */\n higher(key: K): V | undefined {\n let current = this.head;\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key <= key) {\n current = current.forward[i];\n }\n }\n const nextNode = current.forward[0];\n return nextNode ? nextNode.value : undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Get the value of the last element in the Skip List that is less than the given key.\n * @param key - the given key.\n * @returns The value of the last element less than the given key, or undefined if there is no such element.\n */\n lower(key: K): V | undefined {\n let current = this.head;\n let lastLess = undefined;\n\n for (let i = this.level - 1; i >= 0; i--) {\n while (current.forward[i] && current.forward[i].key < key) {\n current = current.forward[i];\n }\n if (current.key < key) {\n lastLess = current;\n }\n }\n\n return lastLess ? lastLess.value : undefined;\n }\n\n /**\n * Time Complexity: O(maxLevel)\n * Space Complexity: O(1)\n *\n * The function \"_randomLevel\" generates a random level based on a given probability and maximum level.\n * @returns the level, which is a number.\n */\n protected _randomLevel(): number {\n let level = 1;\n while (Math.random() < this.probability && level < this.maxLevel) {\n level++;\n }\n return level;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback, StackOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\n/**\n * 1. Last In, First Out (LIFO): The core characteristic of a stack is its last in, first out nature, meaning the last element added to the stack will be the first to be removed.\n * 2. Uses: Stacks are commonly used for managing a series of tasks or elements that need to be processed in a last in, first out manner. They are widely used in various scenarios, such as in function calls in programming languages, evaluation of arithmetic expressions, and backtracking algorithms.\n * 3. Performance: Stack operations are typically O(1) in time complexity, meaning that regardless of the stack's size, adding, removing, and viewing the top element are very fast operations.\n * 4. Function Calls: In most modern programming languages, the records of function calls are managed through a stack. When a function is called, its record (including parameters, local variables, and return address) is 'pushed' into the stack. When the function returns, its record is 'popped' from the stack.\n * 5. Expression Evaluation: Used for the evaluation of arithmetic or logical expressions, especially when dealing with parenthesis matching and operator precedence.\n * 6. Backtracking Algorithms: In problems where multiple branches need to be explored but only one branch can be explored at a time, stacks can be used to save the state at each branching point.\n */\nexport class Stack<E = any, R = any> extends IterableElementBase<E, R, Stack<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: StackOptions<E, R>) {\n super(options);\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else {\n this.push(el as E);\n }\n }\n }\n }\n\n protected _elements: E[] = [];\n\n /**\n * The elements function returns the elements of this set.\n * @return An array of elements\n */\n get elements(): E[] {\n return this._elements;\n }\n\n /**\n * The size() function returns the number of elements in an array.\n * @returns The size of the elements array.\n */\n get size(): number {\n return this.elements.length;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function \"fromArray\" creates a new Stack object from an array of elements.\n * @param {E[]} elements - The `elements` parameter is an array of elements of type `E`.\n * @returns {Stack} The method is returning a new instance of the Stack class, initialized with the elements from the input\n * array.\n */\n static fromArray<E>(elements: E[]): Stack<E> {\n return new Stack(elements);\n }\n\n /**\n * The function checks if an array is empty and returns a boolean value.\n * @returns A boolean value indicating whether the `_elements` array is empty or not.\n */\n isEmpty(): boolean {\n return this.elements.length === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `peek` function returns the last element of an array, or undefined if the array is empty.\n * @returns The `peek()` function returns the last element of the `_elements` array, or `undefined` if the array is empty.\n */\n peek(): E | undefined {\n if (this.isEmpty()) return undefined;\n\n return this.elements[this.elements.length - 1];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds an element to the stack and returns the updated stack.\n * @param {E} element - The parameter \"element\" is of type E, which means it can be any data type.\n * @returns The `push` method is returning the updated `Stack<E>` object.\n */\n push(element: E): boolean {\n this.elements.push(element);\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop` function removes and returns the last element from an array, or returns undefined if the array is empty.\n * @returns The `pop()` method is returning the last element of the array `_elements` if the array is not empty. If the\n * array is empty, it returns `undefined`.\n */\n pop(): E | undefined {\n if (this.isEmpty()) return;\n\n return this.elements.pop();\n }\n\n /**\n * The delete function removes an element from the stack.\n * @param element: E Specify the element to be deleted\n * @return A boolean value indicating whether the element was successfully deleted or not\n */\n delete(element: E): boolean {\n const index = this.elements.indexOf(element);\n return this.deleteAt(index);\n }\n\n /**\n * The deleteAt function deletes the element at a given index.\n * @param index: number Determine the index of the element to be deleted\n * @return A boolean value\n */\n deleteAt(index: number): boolean {\n const spliced = this.elements.splice(index, 1);\n return spliced.length === 1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The toArray function returns a copy of the elements in an array.\n * @returns An array of type E.\n */\n toArray(): E[] {\n return this.elements.slice();\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function clears the elements array.\n */\n clear(): void {\n this._elements = [];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone()` function returns a new `Stack` object with the same elements as the original stack.\n * @returns The `clone()` method is returning a new `Stack` object with a copy of the `_elements` array.\n */\n clone(): Stack<E, R> {\n return new Stack<E, R>(this, { toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new stack containing elements from the original stack that satisfy\n * a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being iterated over, the index of the current element, and the stack itself.\n * It should return a boolean value indicating whether the element should be included in the filtered\n * stack or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Stack` object that contains the elements that\n * satisfy the given predicate function.\n */\n filter(predicate: ElementCallback<E, R, boolean, Stack<E, R>>, thisArg?: any): Stack<E, R> {\n const newStack = new Stack<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const el of this) {\n if (predicate.call(thisArg, el, index, this)) {\n newStack.push(el);\n }\n index++;\n }\n return newStack;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and applies it to each element in the stack,\n * returning a new stack with the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * stack. It takes three arguments: the current element, the index of the element, and the stack\n * itself. It should return a new value that will be added to the new stack.\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * transform the raw element (`RM`) into a new element (`EM`) before pushing it into the new stack.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new Stack object with elements of type EM and raw elements of type RM.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Stack<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Stack<EM, RM> {\n const newStack = new Stack<EM, RM>([], { toElementFn });\n let index = 0;\n for (const el of this) {\n newStack.push(callback.call(thisArg, el, index, this));\n index++;\n }\n return newStack;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Custom iterator for the Stack class.\n * @returns An iterator object.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (let i = 0; i < this.elements.length; i++) {\n yield this.elements[i];\n }\n }\n}\n","/**\n * @license MIT\n * @copyright Pablo Zeng <zrwusa@gmail.com>\n * @class\n */\nimport type { ElementCallback, QueueOptions } from '../../types';\nimport { IterableElementBase } from '../base';\nimport { SinglyLinkedList } from '../linked-list';\n\n/**\n * 1. First In, First Out (FIFO): The core feature of a queue is its first in, first out nature. The element added to the queue first will be the one to be removed first.\n * 2. Operations: The main operations include enqueue (adding an element to the end of the queue) and dequeue (removing and returning the element at the front of the queue). Typically, there is also a peek operation (looking at the front element without removing it).\n * 3. Uses: Queues are commonly used to manage a series of tasks or elements that need to be processed in order. For example, managing task queues in a multi-threaded environment, or in algorithms for data structures like trees and graphs for breadth-first search.\n * 4. Task Scheduling: Managing the order of task execution in operating systems or applications.\n * 5. Data Buffering: Acting as a buffer for data packets in network communication.\n * 6. Breadth-First Search (BFS): In traversal algorithms for graphs and trees, queues store elements that are to be visited.\n * 7. Real-time Queuing: Like queuing systems in banks or supermarkets.\n */\nexport class Queue<E = any, R = any> extends IterableElementBase<E, R, Queue<E, R>> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: QueueOptions<E, R>) {\n super(options);\n\n if (options) {\n const { autoCompactRatio = 0.5 } = options;\n this._autoCompactRatio = autoCompactRatio;\n }\n\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) this.push(this.toElementFn(el as R));\n else this.push(el as E);\n }\n }\n }\n\n protected _elements: E[] = [];\n\n /**\n * The elements function returns the elements of this set.\n * @return An array of the elements in the stack\n */\n get elements(): E[] {\n return this._elements;\n }\n\n protected _offset: number = 0;\n\n /**\n * The offset function returns the offset of the current page.\n * @return The value of the protected variable _offset\n */\n get offset(): number {\n return this._offset;\n }\n\n /**\n * The size function returns the number of elements in an array.\n * @returns {number} The size of the array, which is the difference between the length of the array and the offset.\n */\n get size(): number {\n return this.elements.length - this.offset;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `first` function returns the first element of the array `_elements` if it exists, otherwise it returns `undefined`.\n * @returns The `get first()` method returns the first element of the data structure, represented by the `_elements` array at\n * the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.\n */\n get first(): E | undefined {\n return this.size > 0 ? this.elements[this.offset] : undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `last` function returns the last element in an array-like data structure, or undefined if the structure is empty.\n * @returns The method `get last()` returns the last element of the `_elements` array if the array is not empty. If the\n * array is empty, it returns `undefined`.\n */\n get last(): E | undefined {\n return this.size > 0 ? this.elements[this.elements.length - 1] : undefined;\n }\n\n protected _autoCompactRatio: number = 0.5;\n\n /**\n * This function returns the value of the autoCompactRatio property.\n * @returns The `autoCompactRatio` property of the object, which is a number.\n */\n get autoCompactRatio(): number {\n return this._autoCompactRatio;\n }\n\n /**\n * The above function sets the autoCompactRatio property to a specified number in TypeScript.\n * @param {number} v - The parameter `v` represents the value that will be assigned to the\n * `_autoCompactRatio` property.\n */\n set autoCompactRatio(v: number) {\n this._autoCompactRatio = v;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function \"fromArray\" creates a new Queue object from an array of elements.Creates a queue from an existing array.\n * @public\n * @param {E[]} elements - The \"elements\" parameter is an array of elements of type E.\n * @returns The method is returning a new instance of the Queue class, initialized with the elements from the input\n * array.\n */\n static fromArray<E>(elements: E[]): Queue<E> {\n return new Queue(elements);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The push function adds an element to the end of the queue and returns true. Adds an element at the back of the queue.\n * @param {E} element - The `element` parameter represents the element that you want to add to the queue.\n * @returns Always returns true, indicating the element was successfully added.\n */\n push(element: E): boolean {\n this.elements.push(element);\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift` function removes and returns the first element in the queue, and adjusts the internal data structure if\n * necessary to optimize performance.\n * @returns The function `shift()` returns either the first element in the queue or `undefined` if the queue is empty.\n */\n shift(): E | undefined {\n if (this.size === 0) return undefined;\n\n const first = this.first;\n this._offset += 1;\n\n if (this.offset / this.elements.length > this.autoCompactRatio) this.compact();\n return first;\n }\n\n /**\n * The delete function removes an element from the list.\n * @param {E} element - Specify the element to be deleted\n * @return A boolean value indicating whether the element was successfully deleted or not\n */\n delete(element: E): boolean {\n const index = this.elements.indexOf(element);\n return this.deleteAt(index);\n }\n\n /**\n * The deleteAt function deletes the element at a given index.\n * @param {number} index - Determine the index of the element to be deleted\n * @return A boolean value\n */\n deleteAt(index: number): boolean {\n const spliced = this.elements.splice(index, 1);\n return spliced.length === 1;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * @param index\n */\n at(index: number): E | undefined {\n return this.elements[index + this._offset];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if a data structure is empty by comparing its size to zero.\n * @returns {boolean} A boolean value indicating whether the size of the object is 0 or not.\n */\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(n)\n *\n * The toArray() function returns an array of elements from the current offset to the end of the _elements array.\n * @returns An array of type E is being returned.\n */\n toArray(): E[] {\n return this.elements.slice(this.offset);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the elements array and offset to their initial values.\n */\n clear(): void {\n this._elements = [];\n this._offset = 0;\n }\n\n /**\n * The `compact` function in TypeScript slices the elements array based on the offset and resets the\n * offset to zero.\n * @returns The `compact()` method is returning a boolean value of `true`.\n */\n compact(): boolean {\n this._elements = this.elements.slice(this.offset);\n this._offset = 0;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone()` function returns a new Queue object with the same elements as the original Queue.\n * @returns The `clone()` method is returning a new instance of the `Queue` class.\n */\n clone(): Queue<E, R> {\n return new Queue(this.elements.slice(this.offset), { toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new `Queue` object containing elements from the original `Queue`\n * that satisfy a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being iterated over, the index of the current element, and the queue itself.\n * It should return a boolean value indicating whether the element should be included in the filtered\n * queue or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Queue` object that contains the elements that\n * satisfy the given predicate function.\n */\n filter(predicate: ElementCallback<E, R, boolean, Queue<E, R>>, thisArg?: any): Queue<E, R> {\n const newDeque = new Queue<E, R>([], { toElementFn: this.toElementFn });\n let index = 0;\n for (const el of this) {\n if (predicate.call(thisArg, el, index, this)) {\n newDeque.push(el);\n }\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Queue<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Queue<EM, RM> {\n const newDeque = new Queue<EM, RM>([], { toElementFn });\n let index = 0;\n for (const el of this) {\n newDeque.push(callback.call(thisArg, el, index, this));\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `_getIterator` returns an iterable iterator for the elements in the class.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (const item of this.elements.slice(this.offset)) {\n yield item;\n }\n }\n}\n\n/**\n * 1. First In, First Out (FIFO) Strategy: Like other queue implementations, LinkedListQueue follows the first in, first out principle, meaning the element that is added to the queue first will be the first to be removed.\n * 2. Based on Linked List: LinkedListQueue uses a linked list to store elements. Each node in the linked list contains data and a pointer to the next node.\n * 3. Memory Usage: Since each element requires additional space to store a pointer to the next element, linked lists may use more memory compared to arrays.\n * 4. Frequent Enqueuing and Dequeuing Operations: If your application involves frequent enqueuing and dequeuing operations and is less concerned with random access, then LinkedListQueue is a good choice.\n */\nexport class LinkedListQueue<E = any, R = any> extends SinglyLinkedList<E, R> {\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n * The `clone` function returns a new instance of the `LinkedListQueue` class with the same values as\n * the current instance.\n * @returns The `clone()` method is returning a new instance of `LinkedListQueue` with the same\n * values as the original `LinkedListQueue`.\n */\n override clone(): LinkedListQueue<E, R> {\n return new LinkedListQueue<E, R>(this, { toElementFn: this.toElementFn });\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { DequeOptions, ElementCallback, IterableWithSizeOrLength } from '../../types';\nimport { IterableElementBase } from '../base';\nimport { calcMinUnitsRequired, rangeCheck } from '../../utils';\n\n/**\n * 1. Operations at Both Ends: Supports adding and removing elements at both the front and back of the queue. This allows it to be used as a stack (last in, first out) and a queue (first in, first out).\n * 2. Efficient Random Access: Being based on an array, it offers fast random access capability, allowing constant time access to any element.\n * 3. Continuous Memory Allocation: Since it is based on an array, all elements are stored contiguously in memory, which can bring cache friendliness and efficient memory access.\n * 4. Efficiency: Adding and removing elements at both ends of a deque is usually very fast. However, when the dynamic array needs to expand, it may involve copying the entire array to a larger one, and this operation has a time complexity of O(n).\n * 5. Performance jitter: Deque may experience performance jitter, but DoublyLinkedList will not\n */\nexport class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E, R>> {\n /**\n * The constructor initializes a Deque object with optional iterable of elements and options.\n * @param elements - An iterable object (such as an array or a Set) that contains the initial\n * elements to be added to the deque. It can also be an object with a `length` or `size` property\n * that represents the number of elements in the iterable object. If no elements are provided, an\n * empty deque\n * @param {DequeOptions} [options] - The `options` parameter is an optional object that can contain\n * configuration options for the deque. In this code, it is used to set the `bucketSize` option,\n * which determines the size of each bucket in the deque. If the `bucketSize` option is not provided\n * or is not a number\n */\n constructor(elements: IterableWithSizeOrLength<E> | IterableWithSizeOrLength<R> = [], options?: DequeOptions<E, R>) {\n super(options);\n\n if (options) {\n const { bucketSize, maxLen } = options;\n if (typeof bucketSize === 'number') this._bucketSize = bucketSize;\n if (typeof maxLen === 'number' && maxLen > 0 && maxLen % 1 === 0) this._maxLen = maxLen;\n }\n\n let _size: number;\n if ('length' in elements) {\n if (elements.length instanceof Function) _size = elements.length();\n else _size = elements.length;\n } else {\n if (elements.size instanceof Function) _size = elements.size();\n else _size = elements.size;\n }\n\n this._bucketCount = calcMinUnitsRequired(_size, this._bucketSize) || 1;\n for (let i = 0; i < this._bucketCount; ++i) {\n this._buckets.push(new Array(this._bucketSize));\n }\n const needBucketNum = calcMinUnitsRequired(_size, this._bucketSize);\n this._bucketFirst = this._bucketLast = (this._bucketCount >> 1) - (needBucketNum >> 1);\n this._firstInBucket = this._lastInBucket = (this._bucketSize - (_size % this._bucketSize)) >> 1;\n\n for (const el of elements) {\n if (this.toElementFn) {\n this.push(this.toElementFn(el as R));\n } else {\n this.push(el as E);\n }\n }\n }\n\n protected _bucketSize: number = 1 << 12;\n\n /**\n * The bucketSize function returns the size of the bucket.\n *\n * @return The size of the bucket\n */\n get bucketSize() {\n return this._bucketSize;\n }\n\n protected _maxLen: number = -1;\n\n /**\n * The maxLen function returns the max length of the deque.\n *\n * @return The max length of the deque\n */\n get maxLen() {\n return this._maxLen;\n }\n\n protected _bucketFirst = 0;\n\n /**\n * The function returns the value of the protected variable `_bucketFirst`.\n * @returns The value of the `_bucketFirst` property.\n */\n get bucketFirst(): number {\n return this._bucketFirst;\n }\n\n protected _firstInBucket = 0;\n\n /**\n * The function returns the value of the protected variable _firstInBucket.\n * @returns The method is returning the value of the variable `_firstInBucket`, which is of type\n * `number`.\n */\n get firstInBucket(): number {\n return this._firstInBucket;\n }\n\n protected _bucketLast = 0;\n\n /**\n * The function returns the value of the protected variable `_bucketLast`.\n * @returns The value of the `_bucketLast` property, which is a number.\n */\n get bucketLast(): number {\n return this._bucketLast;\n }\n\n protected _lastInBucket = 0;\n\n /**\n * The function returns the value of the protected variable _lastInBucket.\n * @returns The method is returning the value of the variable `_lastInBucket`, which is of type\n * `number`.\n */\n get lastInBucket(): number {\n return this._lastInBucket;\n }\n\n protected _bucketCount = 0;\n\n /**\n * The function returns the number of buckets.\n * @returns The number of buckets.\n */\n get bucketCount(): number {\n return this._bucketCount;\n }\n\n protected _buckets: E[][] = [];\n\n /**\n * The buckets function returns the buckets property of the object.\n * @return The buckets property\n */\n get buckets() {\n return this._buckets;\n }\n\n protected _size = 0;\n\n /**\n * The size function returns the number of items in the stack.\n * @return The number of values in the set\n */\n get size() {\n return this._size;\n }\n\n /**\n * The function returns the first element in a collection if it exists, otherwise it returns\n * undefined.\n * @returns The first element of the collection, of type E, is being returned.\n */\n get first(): E | undefined {\n if (this._size === 0) return;\n return this._buckets[this._bucketFirst][this._firstInBucket];\n }\n\n /**\n * The last function returns the last element in the queue.\n * @return The last element in the array\n */\n get last(): E | undefined {\n if (this._size === 0) return;\n return this._buckets[this._bucketLast][this._lastInBucket];\n }\n\n /**\n * Time Complexity - Amortized O(1) (possible reallocation),\n * Space Complexity - O(n) (due to potential resizing).\n *\n * The push function adds an element to a data structure and reallocates memory if necessary.\n * @param {E} element - The `element` parameter represents the value that you want to add to the data\n * structure.\n * @returns The size of the data structure after the element has been pushed.\n */\n push(element: E): boolean {\n if (this._size) {\n if (this._lastInBucket < this._bucketSize - 1) {\n this._lastInBucket += 1;\n } else if (this._bucketLast < this._bucketCount - 1) {\n this._bucketLast += 1;\n this._lastInBucket = 0;\n } else {\n this._bucketLast = 0;\n this._lastInBucket = 0;\n }\n if (this._bucketLast === this._bucketFirst && this._lastInBucket === this._firstInBucket) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketLast][this._lastInBucket] = element;\n if (this._maxLen > 0 && this._size > this._maxLen) this.shift();\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop()` function removes and returns the last element from a data structure, updating the\n * internal state variables accordingly.\n * @returns The element that was removed from the data structure is being returned.\n */\n pop(): E | undefined {\n if (this._size === 0) return;\n const element = this._buckets[this._bucketLast][this._lastInBucket];\n if (this._size !== 1) {\n if (this._lastInBucket > 0) {\n this._lastInBucket -= 1;\n } else if (this._bucketLast > 0) {\n this._bucketLast -= 1;\n this._lastInBucket = this._bucketSize - 1;\n } else {\n this._bucketLast = this._bucketCount - 1;\n this._lastInBucket = this._bucketSize - 1;\n }\n }\n this._size -= 1;\n return element;\n }\n\n /**\n * Time Complexity: Amortized O(1)\n * Space Complexity: O(n)\n *\n * The `unshift` function adds an element to the beginning of an array-like data structure and\n * returns the new size of the structure.\n * @param {E} element - The `element` parameter represents the element that you want to add to the\n * beginning of the data structure.\n * @returns The size of the data structure after the element has been added.\n */\n unshift(element: E): boolean {\n if (this._size) {\n if (this._firstInBucket > 0) {\n this._firstInBucket -= 1;\n } else if (this._bucketFirst > 0) {\n this._bucketFirst -= 1;\n this._firstInBucket = this._bucketSize - 1;\n } else {\n this._bucketFirst = this._bucketCount - 1;\n this._firstInBucket = this._bucketSize - 1;\n }\n if (this._bucketFirst === this._bucketLast && this._firstInBucket === this._lastInBucket) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketFirst][this._firstInBucket] = element;\n if (this._maxLen > 0 && this._size > this._maxLen) this.pop();\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `shift()` function removes and returns the first element from a data structure, updating the\n * internal state variables accordingly.\n * @returns The element that is being removed from the beginning of the data structure is being\n * returned.\n */\n shift(): E | undefined {\n if (this._size === 0) return;\n const element = this._buckets[this._bucketFirst][this._firstInBucket];\n if (this._size !== 1) {\n if (this._firstInBucket < this._bucketSize - 1) {\n this._firstInBucket += 1;\n } else if (this._bucketFirst < this._bucketCount - 1) {\n this._bucketFirst += 1;\n this._firstInBucket = 0;\n } else {\n this._bucketFirst = 0;\n this._firstInBucket = 0;\n }\n }\n this._size -= 1;\n return element;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if the size of an object is equal to zero and returns a boolean value.\n * @returns A boolean value indicating whether the size of the object is 0 or not.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear() function resets the state of the object by initializing all variables to their default\n * values.\n */\n clear(): void {\n this._buckets = [new Array(this._bucketSize)];\n this._bucketCount = 1;\n this._bucketFirst = this._bucketLast = this._size = 0;\n this._firstInBucket = this._lastInBucket = this._bucketSize >> 1;\n }\n\n /**\n * The below function is a generator that yields elements from a collection one by one.\n */\n *begin(): Generator<E> {\n let index = 0;\n while (index < this._size) {\n yield this.at(index);\n index++;\n }\n }\n\n /**\n * The function `reverseBegin()` is a generator that yields elements in reverse order starting from\n * the last element.\n */\n *reverseBegin(): Generator<E> {\n let index = this._size - 1;\n while (index >= 0) {\n yield this.at(index);\n index--;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `at` function retrieves an element at a specified position in an array-like data structure.\n * @param {number} pos - The `pos` parameter represents the position of the element that you want to\n * retrieve from the data structure. It is of type `number` and should be a valid index within the\n * range of the data structure.\n * @returns The element at the specified position in the data structure is being returned.\n */\n at(pos: number): E {\n rangeCheck(pos, 0, this._size - 1);\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n return this._buckets[bucketIndex][indexInBucket]!;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `setAt` function sets an element at a specific position in an array-like data structure.\n * @param {number} pos - The `pos` parameter represents the position at which the element needs to be\n * set. It is of type `number`.\n * @param {E} element - The `element` parameter is the value that you want to set at the specified\n * position in the data structure.\n */\n setAt(pos: number, element: E): boolean {\n rangeCheck(pos, 0, this._size - 1);\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n this._buckets[bucketIndex][indexInBucket] = element;\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `addAt` function inserts one or more elements at a specified position in an array-like data\n * structure.\n * @param {number} pos - The `pos` parameter represents the position at which the element(s) should\n * be inserted. It is of type `number`.\n * @param {E} element - The `element` parameter represents the element that you want to insert into\n * the array at the specified position.\n * @param [num=1] - The `num` parameter represents the number of times the `element` should be\n * inserted at the specified position (`pos`). By default, it is set to 1, meaning that the `element`\n * will be inserted once. However, you can provide a different value for `num` if you want\n * @returns The size of the array after the insertion is being returned.\n */\n addAt(pos: number, element: E, num = 1): boolean {\n const length = this._size;\n rangeCheck(pos, 0, length);\n if (pos === 0) {\n while (num--) this.unshift(element);\n } else if (pos === this._size) {\n while (num--) this.push(element);\n } else {\n const arr: E[] = [];\n for (let i = pos; i < this._size; ++i) {\n arr.push(this.at(i));\n }\n this.cut(pos - 1, true);\n for (let i = 0; i < num; ++i) this.push(element);\n for (let i = 0; i < arr.length; ++i) this.push(arr[i]);\n }\n return true;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `cut` function updates the state of the object based on the given position and returns the\n * updated size.\n * @param {number} pos - The `pos` parameter represents the position at which the string should be\n * cut. It is a number that indicates the index of the character where the cut should be made.\n * @param {boolean} isCutSelf - If true, the original deque will not be cut, and return a new deque\n * @returns The method is returning the updated size of the data structure.\n */\n cut(pos: number, isCutSelf = false): Deque<E> {\n if (isCutSelf) {\n if (pos < 0) {\n this.clear();\n return this;\n }\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n this._bucketLast = bucketIndex;\n this._lastInBucket = indexInBucket;\n this._size = pos + 1;\n return this;\n } else {\n const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });\n\n for (let i = 0; i <= pos; i++) {\n newDeque.push(this.at(i));\n }\n\n return newDeque;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1) or O(n)\n *\n * The `cutRest` function cuts the elements from a specified position in a deque and returns a new\n * deque with the cut elements.\n * @param {number} pos - The `pos` parameter represents the position from which to cut the Deque. It\n * is a number that indicates the index of the element in the Deque where the cut should start.\n * @param [isCutSelf=false] - isCutSelf is a boolean parameter that determines whether the original\n * Deque should be modified or a new Deque should be created. If isCutSelf is true, the original\n * Deque will be modified by cutting off elements starting from the specified position. If isCutSelf\n * is false, a new De\n * @returns The function `cutRest` returns either the modified original deque (`this`) or a new deque\n * (`newDeque`) depending on the value of the `isCutSelf` parameter.\n */\n cutRest(pos: number, isCutSelf = false): Deque<E> {\n if (isCutSelf) {\n if (pos < 0) {\n return this;\n }\n const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);\n this._bucketFirst = bucketIndex;\n this._firstInBucket = indexInBucket;\n this._size = this._size - pos;\n return this;\n } else {\n const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });\n if (pos < 0) pos = 0;\n for (let i = pos; i < this._size; i++) {\n newDeque.push(this.at(i));\n }\n\n return newDeque;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1) or O(n)\n *\n * The `deleteAt` function removes an element at a specified position in an array-like data\n * structure.\n * @param {number} pos - The `pos` parameter in the `deleteAt` function represents the position at\n * which an element needs to be deleted from the data structure. It is of type `number` and indicates\n * the index of the element to be deleted.\n * @returns The size of the data structure after the deletion operation is performed.\n */\n deleteAt(pos: number): boolean {\n rangeCheck(pos, 0, this._size - 1);\n if (pos === 0) this.shift();\n else if (pos === this._size - 1) this.pop();\n else {\n const length = this._size - 1;\n let { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(pos);\n for (let i = pos; i < length; ++i) {\n const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(pos + 1);\n this._buckets[curBucket][curPointer] = this._buckets[nextBucket][nextPointer];\n curBucket = nextBucket;\n curPointer = nextPointer;\n }\n this.pop();\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes all occurrences of a specified element from an array-like data\n * structure.\n * @param {E} element - The `element` parameter represents the element that you want to delete from\n * the data structure.\n * @returns The size of the data structure after the element has been deleted.\n */\n delete(element: E): boolean {\n const size = this._size;\n if (size === 0) return false;\n let i = 0;\n let index = 0;\n while (i < size) {\n const oldElement = this.at(i);\n if (oldElement !== element) {\n this.setAt(index, oldElement!);\n index += 1;\n }\n i += 1;\n }\n this.cut(index - 1, true);\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The reverse() function reverses the order of the buckets and the elements within each bucket in a\n * data structure.\n * @returns The reverse() method is returning the object itself (this) after performing the reverse\n * operation on the buckets and updating the relevant properties.\n */\n reverse(): this {\n this._buckets.reverse().forEach(function (bucket) {\n bucket.reverse();\n });\n const { _bucketFirst, _bucketLast, _firstInBucket, _lastInBucket } = this;\n this._bucketFirst = this._bucketCount - _bucketLast - 1;\n this._bucketLast = this._bucketCount - _bucketFirst - 1;\n this._firstInBucket = this._bucketSize - _lastInBucket - 1;\n this._lastInBucket = this._bucketSize - _firstInBucket - 1;\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `unique()` function removes duplicate elements from an array-like data structure and returns\n * the number of unique elements.\n * @returns The size of the modified array is being returned.\n */\n unique(): this {\n if (this._size <= 1) {\n return this;\n }\n let index = 1;\n let prev = this.at(0);\n for (let i = 1; i < this._size; ++i) {\n const cur = this.at(i);\n if (cur !== prev) {\n prev = cur;\n this.setAt(index++, cur);\n }\n }\n this.cut(index - 1, true);\n return this;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `sort` function sorts the elements in a data structure using a provided comparator function.\n * @param [comparator] - The `comparator` parameter is a function that takes in two elements `x` and\n * `y` of type `E` and returns a number. The comparator function is used to determine the order of\n * the elements in the sorted array.\n * @returns Deque<E>\n */\n sort(comparator?: (x: E, y: E) => number): this {\n const arr: E[] = [];\n for (let i = 0; i < this._size; ++i) {\n arr.push(this.at(i));\n }\n arr.sort(comparator);\n for (let i = 0; i < this._size; ++i) {\n this.setAt(i, arr[i]);\n }\n return this;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `shrinkToFit` function reorganizes the elements in an array-like data structure to minimize\n * memory usage.\n * @returns Nothing is being returned. The function is using the `return` statement to exit early if\n * `this._size` is 0, but it does not return any value.\n */\n shrinkToFit(): void {\n if (this._size === 0) return;\n const newBuckets = [];\n if (this._bucketFirst === this._bucketLast) return;\n else if (this._bucketFirst < this._bucketLast) {\n for (let i = this._bucketFirst; i <= this._bucketLast; ++i) {\n newBuckets.push(this._buckets[i]);\n }\n } else {\n for (let i = this._bucketFirst; i < this._bucketCount; ++i) {\n newBuckets.push(this._buckets[i]);\n }\n for (let i = 0; i <= this._bucketLast; ++i) {\n newBuckets.push(this._buckets[i]);\n }\n }\n this._bucketFirst = 0;\n this._bucketLast = newBuckets.length - 1;\n this._buckets = newBuckets;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function \"indexOf\" returns the index of the first occurrence of a given element in an array,\n * or -1 if the element is not found.\n * @param {E} element - The \"element\" parameter represents the element that you want to find the\n * index of in the data structure.\n * @returns The indexOf function returns the index of the first occurrence of the specified element\n * in the data structure. If the element is not found, it returns -1.\n */\n indexOf(element: E): number {\n for (let i = 0; i < this._size; ++i) {\n if (this.at(i) === element) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `toArray` function converts the elements of a data structure into an array.\n * @returns The `toArray()` method is returning an array of elements of type `E`.\n */\n toArray(): E[] {\n return [...this];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone()` function returns a new instance of the `Deque` class with the same elements and\n * bucket size as the original instance.\n * @returns The `clone()` method is returning a new instance of the `Deque` class with the same\n * elements as the original deque (`this`) and the same bucket size.\n */\n clone(): Deque<E, R> {\n return new Deque<E, R>(this, { bucketSize: this.bucketSize, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new deque containing elements from the original deque that satisfy\n * a given predicate function.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * the current element being iterated over, the index of the current element, and the deque itself.\n * It should return a boolean value indicating whether the element should be included in the filtered\n * deque or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `predicate` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `predicate` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Deque` object that contains the elements that\n * satisfy the given predicate function.\n */\n filter(predicate: ElementCallback<E, R, boolean, Deque<E, R>>, thisArg?: any): Deque<E, R> {\n const newDeque = new Deque<E, R>([], { bucketSize: this._bucketSize, toElementFn: this.toElementFn });\n let index = 0;\n for (const el of this) {\n if (predicate.call(thisArg, el, index, this)) {\n newDeque.push(el);\n }\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function takes a callback function and applies it to each element in the deque,\n * returning a new deque with the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * deque. It takes three arguments: the current element, the index of the element, and the deque\n * itself. It should return a value of type EM.\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * transform the raw element (`RM`) into a new element (`EM`) before adding it to the new deque. If\n * provided, this function will be called for each raw element in the original deque.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new Deque object with elements of type EM and raw elements of type RM.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Deque<E, R>>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Deque<EM, RM> {\n const newDeque = new Deque<EM, RM>([], { bucketSize: this._bucketSize, toElementFn });\n let index = 0;\n for (const el of this) {\n newDeque.push(callback.call(thisArg, el, index, this));\n index++;\n }\n return newDeque;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The above function is an implementation of the iterator protocol in TypeScript, allowing the\n * object to be iterated over using a for...of loop.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (let i = 0; i < this._size; ++i) {\n yield this.at(i);\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `_reallocate` function reallocates the buckets in an array, adding new buckets if needed.\n * @param {number} [needBucketNum] - The `needBucketNum` parameter is an optional number that\n * specifies the number of new buckets needed. If not provided, it will default to half of the\n * current bucket count (`this._bucketCount >> 1`) or 1 if the current bucket count is less than 2.\n */\n protected _reallocate(needBucketNum?: number) {\n const newBuckets = [];\n const addBucketNum = needBucketNum || this._bucketCount >> 1 || 1;\n for (let i = 0; i < addBucketNum; ++i) {\n newBuckets[i] = new Array(this._bucketSize);\n }\n for (let i = this._bucketFirst; i < this._bucketCount; ++i) {\n newBuckets[newBuckets.length] = this._buckets[i];\n }\n for (let i = 0; i < this._bucketLast; ++i) {\n newBuckets[newBuckets.length] = this._buckets[i];\n }\n newBuckets[newBuckets.length] = [...this._buckets[this._bucketLast]];\n this._bucketFirst = addBucketNum;\n this._bucketLast = newBuckets.length - 1;\n for (let i = 0; i < addBucketNum; ++i) {\n newBuckets[newBuckets.length] = new Array(this._bucketSize);\n }\n this._buckets = newBuckets;\n this._bucketCount = newBuckets.length;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function calculates the bucket index and index within the bucket based on the given position.\n * @param {number} pos - The `pos` parameter represents the position within the data structure. It is\n * a number that indicates the index or position of an element within the structure.\n * @returns an object with two properties: \"bucketIndex\" and \"indexInBucket\".\n */\n protected _getBucketAndPosition(pos: number) {\n let bucketIndex: number;\n let indexInBucket: number;\n\n const overallIndex = this._firstInBucket + pos;\n bucketIndex = this._bucketFirst + Math.floor(overallIndex / this._bucketSize);\n\n if (bucketIndex >= this._bucketCount) {\n bucketIndex -= this._bucketCount;\n }\n\n indexInBucket = ((overallIndex + 1) % this._bucketSize) - 1;\n if (indexInBucket < 0) {\n indexInBucket = this._bucketSize - 1;\n }\n\n return { bucketIndex, indexInBucket };\n }\n}\n","/**\n * data-structure-typed\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\n\nimport type { Comparator, DFSOrderPattern, ElementCallback, HeapOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\n/**\n * 1. Complete Binary Tree: Heaps are typically complete binary trees, meaning every level is fully filled except possibly for the last level, which has nodes as far left as possible.\n * 2. Heap Properties: Each node in a heap follows a specific order property, which varies depending on the type of heap:\n * Max Heap: The value of each parent node is greater than or equal to the value of its children.\n * Min Heap: The value of each parent node is less than or equal to the value of its children.\n * 3. Root Node Access: In a heap, the largest element (in a max heap) or the smallest element (in a min heap) is always at the root of the tree.\n * 4. Efficient Insertion and Deletion: Due to its structure, a heap allows for insertion and deletion operations in logarithmic time (O(log n)).\n * 5. Managing Dynamic Data Sets: Heaps effectively manage dynamic data sets, especially when frequent access to the largest or smallest elements is required.\n * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.\n * 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.\n * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prime's minimum-spanning tree algorithm, which use heaps to improve performance.\n */\nexport class Heap<E = any, R = any> extends IterableElementBase<E, R, Heap<E, R>> {\n /**\n * The constructor initializes a heap data structure with optional elements and options.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the heap.\n * It is an optional parameter, and if not provided, the heap will\n * be initialized as empty.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the heap.\n * In this case, it is used to specify a custom comparator\n * function for comparing elements in the heap.\n * The comparator function is used to determine the\n * order of elements in the heap.\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: HeapOptions<E, R>) {\n super(options);\n\n if (options) {\n const { comparator } = options;\n if (comparator) this._comparator = comparator;\n }\n\n if (elements) {\n for (const el of elements) {\n if (this.toElementFn) this.add(this.toElementFn(el as R));\n else this.add(el as E);\n }\n }\n }\n\n protected _elements: E[] = [];\n\n /**\n * The function returns an array of elements.\n * @returns The element array is being returned.\n */\n get elements(): E[] {\n return this._elements;\n }\n\n /**\n * Get the size (number of elements) of the heap.\n */\n get size(): number {\n return this.elements.length;\n }\n\n /**\n * Get the last element in the heap, which is not necessarily a leaf node.\n * @returns The last element or undefined if the heap is empty.\n */\n get leaf(): E | undefined {\n return this.elements[this.size - 1] ?? undefined;\n }\n\n /**\n * Static method that creates a binary heap from an array of elements and a comparison function.\n * @returns A new Heap instance.\n * @param elements\n * @param options\n */\n static heapify<E = any, R = any>(elements: Iterable<E>, options: HeapOptions<E, R>): Heap<E> {\n return new Heap<E>(elements, options);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Insert an element into the heap and maintain the heap properties.\n * @param element - The element to be inserted.\n */\n add(element: E): boolean {\n this._elements.push(element);\n return this._bubbleUp(this.elements.length - 1);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @returns The top element or undefined if the heap is empty.\n */\n poll(): E | undefined {\n if (this.elements.length === 0) return;\n const value = this.elements[0];\n const last = this.elements.pop()!;\n if (this.elements.length) {\n this.elements[0] = last;\n this._sinkDown(0, this.elements.length >> 1);\n }\n return value;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Peek at the top element of the heap without removing it.\n * @returns The top element or undefined if the heap is empty.\n */\n peek(): E | undefined {\n return this.elements[0];\n }\n\n /**\n * Check if the heap is empty.\n * @returns True if the heap is empty, otherwise false.\n */\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n /**\n * Reset the elements of the heap. Make the elements empty.\n */\n clear(): void {\n this._elements = [];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Clear and add elements of the heap\n * @param elements\n */\n refill(elements: E[]): boolean[] {\n this._elements = elements;\n return this.fix();\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * Use a comparison function to check whether a binary heap contains a specific element.\n * @param element - the element to check.\n * @returns Returns true if the specified element is contained; otherwise, returns false.\n */\n override has(element: E): boolean {\n return this.elements.includes(element);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `delete` function removes an element from an array-like data structure, maintaining the order\n * and structure of the remaining elements.\n * @param {E} element - The `element` parameter represents the element that you want to delete from\n * the array `this.elements`.\n * @returns The `delete` function is returning a boolean value. It returns `true` if the element was\n * successfully deleted from the array, and `false` if the element was not found in the array.\n */\n delete(element: E): boolean {\n const index = this.elements.indexOf(element);\n if (index < 0) return false;\n if (index === 0) {\n this.poll();\n } else if (index === this.elements.length - 1) {\n this.elements.pop();\n } else {\n this.elements.splice(index, 1, this.elements.pop()!);\n this._bubbleUp(index);\n this._sinkDown(index, this.elements.length >> 1);\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * Depth-first search (DFS) method, different traversal orders can be selected。\n * @param order - Traverse order parameter: 'IN' (in-order), 'PRE' (pre-order) or 'POST' (post-order).\n * @returns An array containing elements traversed in the specified order.\n */\n dfs(order: DFSOrderPattern = 'PRE'): E[] {\n const result: E[] = [];\n\n // Auxiliary recursive function, traverses the binary heap according to the traversal order\n const _dfs = (index: number) => {\n const left = 2 * index + 1,\n right = left + 1;\n if (index < this.size) {\n if (order === 'IN') {\n _dfs(left);\n result.push(this.elements[index]);\n _dfs(right);\n } else if (order === 'PRE') {\n result.push(this.elements[index]);\n _dfs(left);\n _dfs(right);\n } else if (order === 'POST') {\n _dfs(left);\n _dfs(right);\n result.push(this.elements[index]);\n }\n }\n };\n\n _dfs(0); // Traverse starting from the root node\n\n return result;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Convert the heap to an array.\n * @returns An array containing the elements of the heap.\n */\n toArray(): E[] {\n return [...this.elements];\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * Clone the heap, creating a new heap with the same elements.\n * @returns A new Heap instance containing the same elements.\n */\n clone(): Heap<E, R> {\n return new Heap<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * Sort the elements in the heap and return them as an array.\n * @returns An array containing the elements sorted in ascending order.\n */\n sort(): E[] {\n const visitedNode: E[] = [];\n const cloned = new Heap<E, R>(this, { comparator: this.comparator });\n while (cloned.size !== 0) {\n const top = cloned.poll();\n if (top !== undefined) visitedNode.push(top);\n }\n return visitedNode;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * Fix the entire heap to maintain heap properties.\n */\n fix(): boolean[] {\n const results: boolean[] = [];\n for (let i = Math.floor(this.size / 2); i >= 0; i--) results.push(this._sinkDown(i, this.elements.length >> 1));\n return results;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new Heap object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `Heap` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n filter(callback: ElementCallback<E, R, boolean, Heap<E, R>>, thisArg?: any): Heap<E, R> {\n const filteredList = new Heap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.add(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `Heap` class with the mapped elements.\n */\n map<EM, RM>(\n callback: ElementCallback<E, R, EM, Heap<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): Heap<EM, RM> {\n const mappedHeap: Heap<EM, RM> = new Heap<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedHeap.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedHeap;\n }\n\n protected _DEFAULT_COMPARATOR = (a: E, b: E): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a > b) return 1;\n if (a < b) return -1;\n return 0;\n };\n\n protected _comparator: Comparator<E> = this._DEFAULT_COMPARATOR;\n\n /**\n * The function returns the value of the _comparator property.\n * @returns The `_comparator` property is being returned.\n */\n get comparator() {\n return this._comparator;\n }\n\n /**\n * The function `_getIterator` returns an iterable iterator for the elements in the class.\n */\n protected *_getIterator(): IterableIterator<E> {\n for (const element of this.elements) {\n yield element;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Float operation to maintain heap properties after adding an element.\n * @param index - The index of the newly added element.\n */\n protected _bubbleUp(index: number): boolean {\n const element = this.elements[index];\n while (index > 0) {\n const parent = (index - 1) >> 1;\n const parentItem = this.elements[parent];\n if (this.comparator(parentItem, element) <= 0) break;\n this.elements[index] = parentItem;\n index = parent;\n }\n this.elements[index] = element;\n return true;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Sinking operation to maintain heap properties after removing the top element.\n * @param index - The index from which to start sinking.\n * @param halfLength\n */\n protected _sinkDown(index: number, halfLength: number): boolean {\n const element = this.elements[index];\n while (index < halfLength) {\n let left = (index << 1) | 1;\n const right = left + 1;\n let minItem = this.elements[left];\n if (right < this.elements.length && this.comparator(minItem, this.elements[right]) > 0) {\n left = right;\n minItem = this.elements[right];\n }\n if (this.comparator(minItem, element) >= 0) break;\n this.elements[index] = minItem;\n index = left;\n }\n this.elements[index] = element;\n return true;\n }\n}\n\nexport class FibonacciHeapNode<E> {\n element: E;\n degree: number;\n left?: FibonacciHeapNode<E>;\n right?: FibonacciHeapNode<E>;\n child?: FibonacciHeapNode<E>;\n parent?: FibonacciHeapNode<E>;\n marked: boolean;\n\n /**\n * The constructor function initializes an object with an element and a degree, and sets the marked\n * property to false.\n * @param {E} element - The \"element\" parameter represents the value or data that will be stored in\n * the node of a data structure. It can be any type of data, such as a number, string, object, or\n * even another data structure.\n * @param [degree=0] - The degree parameter represents the degree of the element in a data structure\n * called a Fibonacci heap. The degree of a node is the number of children it has. By default, the\n * degree is set to 0 when a new node is created.\n */\n constructor(element: E, degree = 0) {\n this.element = element;\n this.degree = degree;\n this.marked = false;\n }\n}\n\nexport class FibonacciHeap<E> {\n /**\n * The constructor function initializes a FibonacciHeap object with an optional comparator function.\n * @param [comparator] - The `comparator` parameter is an optional argument that represents a\n * function used to compare elements in the FibonacciHeap. If a comparator function is provided, it\n * will be used to determine the order of elements in the heap. If no comparator function is\n * provided, a default comparator function will be used.\n */\n constructor(comparator?: Comparator<E>) {\n this.clear();\n this._comparator = comparator || this._defaultComparator;\n\n if (typeof this.comparator !== 'function') {\n throw new Error('FibonacciHeap constructor: given comparator should be a function.');\n }\n }\n\n protected _root?: FibonacciHeapNode<E>;\n\n /**\n * The function returns the root node of a Fibonacci heap.\n * @returns The method is returning either a FibonacciHeapNode object or undefined.\n */\n get root(): FibonacciHeapNode<E> | undefined {\n return this._root;\n }\n\n protected _size = 0;\n\n /**\n * The function returns the size of an object.\n * @returns The size of the object, which is a number.\n */\n get size(): number {\n return this._size;\n }\n\n protected _min?: FibonacciHeapNode<E>;\n\n /**\n * The function returns the minimum node in a Fibonacci heap.\n * @returns The method is returning the minimum node of the Fibonacci heap, which is of type\n * `FibonacciHeapNode<E>`. If there is no minimum node, it will return `undefined`.\n */\n get min(): FibonacciHeapNode<E> | undefined {\n return this._min;\n }\n\n protected _comparator: Comparator<E>;\n\n /**\n * The function returns the comparator used for comparing elements.\n * @returns The `_comparator` property of the object.\n */\n get comparator(): Comparator<E> {\n return this._comparator;\n }\n\n /**\n * Get the size (number of elements) of the heap.\n * @returns {number} The size of the heap. Returns 0 if the heap is empty. Returns -1 if the heap is invalid.\n */\n clear(): void {\n this._root = undefined;\n this._min = undefined;\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Insert an element into the heap and maintain the heap properties.\n * @param element\n * @returns {FibonacciHeap<E>} FibonacciHeap<E> - The heap itself.\n */\n add(element: E): FibonacciHeap<E> {\n return this.push(element);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Insert an element into the heap and maintain the heap properties.\n * @param element\n * @returns {FibonacciHeap<E>} FibonacciHeap<E> - The heap itself.\n */\n push(element: E): FibonacciHeap<E> {\n const node = this.createNode(element);\n node.left = node;\n node.right = node;\n this.mergeWithRoot(node);\n\n if (!this.min || this.comparator(node.element, this.min.element) <= 0) {\n this._min = node;\n }\n\n this._size++;\n return this;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Peek at the top element of the heap without removing it.\n * @returns The top element or undefined if the heap is empty.\n * @protected\n */\n peek(): E | undefined {\n return this.min ? this.min.element : undefined;\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n *\n * Get the size (number of elements) of the heap.\n * @param {FibonacciHeapNode<E>} head - The head of the linked list.\n * @protected\n * @returns FibonacciHeapNode<E>[] - An array containing the elements of the linked list.\n */\n consumeLinkedList(head?: FibonacciHeapNode<E>): FibonacciHeapNode<E>[] {\n const elements: FibonacciHeapNode<E>[] = [];\n if (!head) return elements;\n\n let node: FibonacciHeapNode<E> | undefined = head;\n let flag = false;\n\n while (true) {\n if (node === head && flag) break;\n else if (node === head) flag = true;\n\n if (node) {\n elements.push(node);\n node = node.right;\n }\n }\n\n return elements;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * @param parent\n * @param node\n */\n mergeWithChild(parent: FibonacciHeapNode<E>, node: FibonacciHeapNode<E>): void {\n if (!parent.child) {\n parent.child = node;\n } else {\n node.right = parent.child.right;\n node.left = parent.child;\n parent.child.right!.left = node;\n parent.child.right = node;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @returns The top element or undefined if the heap is empty.\n */\n poll(): E | undefined {\n return this.pop();\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @returns The top element or undefined if the heap is empty.\n */\n pop(): E | undefined {\n if (this._size === 0) return undefined;\n\n const z = this.min!;\n if (z.child) {\n const elements = this.consumeLinkedList(z.child);\n for (const node of elements) {\n this.mergeWithRoot(node);\n node.parent = undefined;\n }\n }\n\n this.removeFromRoot(z);\n\n if (z === z.right) {\n this._min = undefined;\n this._root = undefined;\n } else {\n this._min = z.right;\n this._consolidate();\n }\n\n this._size--;\n\n return z.element;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * merge two heaps. The heap that is merged will be cleared. The heap that is merged into will remain.\n * @param heapToMerge\n */\n merge(heapToMerge: FibonacciHeap<E>): void {\n if (heapToMerge.size === 0) {\n return; // Nothing to merge\n }\n\n // Merge the root lists of the two heaps\n if (this.root && heapToMerge.root) {\n const thisRoot = this.root;\n const otherRoot = heapToMerge.root;\n\n const thisRootRight = thisRoot.right!;\n const otherRootLeft = otherRoot.left!;\n\n thisRoot.right = otherRoot;\n otherRoot.left = thisRoot;\n\n thisRootRight.left = otherRootLeft;\n otherRootLeft.right = thisRootRight;\n }\n\n // Update the minimum node\n if (!this.min || (heapToMerge.min && this.comparator(heapToMerge.min.element, this.min.element) < 0)) {\n this._min = heapToMerge.min;\n }\n\n // Update the size\n this._size += heapToMerge.size;\n\n // Clear the heap that was merged\n heapToMerge.clear();\n }\n\n /**\n * Create a new node.\n * @param element\n * @protected\n */\n createNode(element: E): FibonacciHeapNode<E> {\n return new FibonacciHeapNode<E>(element);\n }\n\n /**\n * Default comparator function used by the heap.\n * @param {E} a\n * @param {E} b\n * @protected\n */\n protected _defaultComparator(a: E, b: E): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Merge the given node with the root list.\n * @param node - The node to be merged.\n */\n protected mergeWithRoot(node: FibonacciHeapNode<E>): void {\n if (!this.root) {\n this._root = node;\n } else {\n node.right = this.root.right;\n node.left = this.root;\n this.root.right!.left = node;\n this.root.right = node;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @param node - The node to be removed.\n * @protected\n */\n protected removeFromRoot(node: FibonacciHeapNode<E>): void {\n if (this.root === node) this._root = node.right;\n if (node.left) node.left.right = node.right;\n if (node.right) node.right.left = node.left;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @param y\n * @param x\n * @protected\n */\n protected _link(y: FibonacciHeapNode<E>, x: FibonacciHeapNode<E>): void {\n this.removeFromRoot(y);\n y.left = y;\n y.right = y;\n this.mergeWithChild(x, y);\n x.degree++;\n y.parent = x;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * Remove and return the top element (the smallest or largest element) from the heap.\n * @protected\n */\n protected _consolidate(): void {\n const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this._size);\n const elements = this.consumeLinkedList(this.root);\n let x: FibonacciHeapNode<E> | undefined,\n y: FibonacciHeapNode<E> | undefined,\n d: number,\n t: FibonacciHeapNode<E> | undefined;\n\n for (const node of elements) {\n x = node;\n d = x.degree;\n\n while (A[d]) {\n y = A[d] as FibonacciHeapNode<E>;\n\n if (this.comparator(x.element, y.element) > 0) {\n t = x;\n x = y;\n y = t;\n }\n\n this._link(y, x);\n A[d] = undefined;\n d++;\n }\n\n A[d] = x;\n }\n\n for (let i = 0; i < this._size; i++) {\n if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) {\n this._min = A[i]!;\n }\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, HeapOptions } from '../../types';\nimport { Heap } from './heap';\n\n/**\n * 1. Complete Binary Tree: Heaps are typically complete binary trees, meaning every level is fully filled except possibly for the last level, which has nodes as far left as possible.\n * 2. Heap Properties: The value of each parent node is greater than or equal to the value of its children.\n * 3. Root Node Access: In a heap, the largest element (in a max heap) or the smallest element (in a min heap) is always at the root of the tree.\n * 4. Efficient Insertion and Deletion: Due to its structure, a heap allows for insertion and deletion operations in logarithmic time (O(log n)).\n * 5. Managing Dynamic Data Sets: Heaps effectively manage dynamic data sets, especially when frequent access to the largest or smallest elements is required.\n * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.\n * 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.\n * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prim's minimum-spanning tree algorithm, which use heaps to improve performance.\n */\nexport class MaxHeap<E = any, R = any> extends Heap<E, R> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: HeapOptions<E, R>) {\n super(elements, {\n comparator: (a: E, b: E): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a < b) return 1;\n if (a > b) return -1;\n return 0;\n },\n ...options\n });\n }\n\n /**\n * The `clone` function returns a new instance of the `MaxHeap` class with the same properties as the\n * current instance.\n * @returns The `clone()` method is returning a new instance of the `MaxHeap` class with the same\n * properties as the current instance.\n */\n override clone(): MaxHeap<E, R> {\n return new MaxHeap<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MaxHeap object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MaxHeap` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(callback: ElementCallback<E, R, boolean, MaxHeap<E, R>>, thisArg?: any): MaxHeap<E, R> {\n const filteredList = new MaxHeap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.add(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MaxHeap` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MaxHeap<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MaxHeap<EM, RM> {\n const mappedHeap: MaxHeap<EM, RM> = new MaxHeap<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedHeap.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedHeap;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, HeapOptions } from '../../types';\nimport { Heap } from './heap';\n\n/**\n * 1. Complete Binary Tree: Heaps are typically complete binary trees, meaning every level is fully filled except possibly for the last level, which has nodes as far left as possible.\n * 2. MinHeap Properties: The value of each parent node is less than or equal to the value of its children.\n * 3. Root Node Access: In a heap, the largest element (in a max heap) or the smallest element (in a min heap) is always at the root of the tree.\n * 4. Efficient Insertion and Deletion: Due to its structure, a heap allows for insertion and deletion operations in logarithmic time (O(log n)).\n * 5. Managing Dynamic Data Sets: Heaps effectively manage dynamic data sets, especially when frequent access to the largest or smallest elements is required.\n * 6. Non-linear Search: While a heap allows rapid access to its largest or smallest element, it is less efficient for other operations, such as searching for a specific element, as it is not designed for these tasks.\n * 7. Efficient Sorting Algorithms: For example, heap sort. MinHeap sort uses the properties of a heap to sort elements.\n * 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prim's minimum spanning tree algorithm, which use heaps to improve performance.\n */\nexport class MinHeap<E = any, R = any> extends Heap<E, R> {\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: HeapOptions<E, R>) {\n super(elements, options);\n }\n\n /**\n * The `clone` function returns a new instance of the `MinHeap` class with the same comparator and\n * toElementFn as the original instance.\n * @returns The `clone()` method is returning a new instance of the `MinHeap` class with the same\n * properties as the current instance.\n */\n override clone(): MinHeap<E, R> {\n return new MinHeap<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MinHeap object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MinHeap` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(callback: ElementCallback<E, R, boolean, MinHeap<E, R>>, thisArg?: any): MinHeap<E, R> {\n const filteredList = new MinHeap<E, R>([], { toElementFn: this.toElementFn, comparator: this.comparator });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredList.add(current);\n }\n index++;\n }\n return filteredList;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MinHeap` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MinHeap<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MinHeap<EM, RM> {\n const mappedHeap: MinHeap<EM, RM> = new MinHeap<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedHeap.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedHeap;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { DijkstraResult, EntryCallback, VertexKey } from '../../types';\nimport { uuidV4 } from '../../utils';\nimport { IterableEntryBase } from '../base';\nimport { IGraph } from '../../interfaces';\nimport { Heap } from '../heap';\nimport { Queue } from '../queue';\n\nexport abstract class AbstractVertex<V = any> {\n key: VertexKey;\n value: V | undefined;\n\n /**\n * The function is a protected constructor that takes an key and an optional value as parameters.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex. It is\n * used to uniquely identify the vertex object.\n * @param {V} [value] - The parameter \"value\" is an optional parameter of type V. It is used to assign a value to the\n * vertex. If no value is provided, it will be set to undefined.\n */\n protected constructor(key: VertexKey, value?: V) {\n this.key = key;\n this.value = value;\n }\n}\n\nexport abstract class AbstractEdge<E = any> {\n value: E | undefined;\n weight: number;\n\n /**\n * The above function is a protected constructor that initializes the weight, value, and hash code properties of an\n * object.\n * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the object. If\n * a value is provided, it will be assigned to the `_weight` property. If no value is provided, the default value of 1\n * will be assigned.\n * @param {VO} [value] - The `value` parameter is of type `VO`, which means it can be any type. It is an optional parameter,\n * meaning it can be omitted when creating an instance of the class.\n */\n protected constructor(weight?: number, value?: E) {\n this.weight = weight !== undefined ? weight : 1;\n this.value = value;\n this._hashCode = uuidV4();\n }\n\n protected _hashCode: string;\n\n get hashCode(): string {\n return this._hashCode;\n }\n\n /**\n * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.\n * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.\n */\n}\n\nexport abstract class AbstractGraph<\n V = any,\n E = any,\n VO extends AbstractVertex<V> = AbstractVertex<V>,\n EO extends AbstractEdge<E> = AbstractEdge<E>\n >\n extends IterableEntryBase<VertexKey, V | undefined>\n implements IGraph<V, E, VO, EO>\n{\n constructor() {\n super();\n }\n\n protected _vertexMap: Map<VertexKey, VO> = new Map<VertexKey, VO>();\n\n get vertexMap(): Map<VertexKey, VO> {\n return this._vertexMap;\n }\n\n set vertexMap(v: Map<VertexKey, VO>) {\n this._vertexMap = v;\n }\n\n get size(): number {\n return this._vertexMap.size;\n }\n\n /**\n * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.\n * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.\n * @param key\n * @param value\n */\n abstract createVertex(key: VertexKey, value?: V): VO;\n\n /**\n * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.\n * This means that using abstract methods in the parent class cannot constrain the grandchild classes. Defining methods within an interface also cannot constrain the descendant classes. When inheriting from this class, developers need to be aware that this method needs to be overridden.\n * @param srcOrV1\n * @param destOrV2\n * @param weight\n * @param value\n */\n abstract createEdge(srcOrV1: VertexKey, destOrV2: VertexKey, weight?: number, value?: E): EO;\n\n abstract deleteEdge(edge: EO): EO | undefined;\n\n abstract getEdge(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined;\n\n abstract degreeOf(vertexOrKey: VO | VertexKey): number;\n\n abstract edgeSet(): EO[];\n\n abstract edgesOf(vertexOrKey: VO | VertexKey): EO[];\n\n abstract getNeighbors(vertexOrKey: VO | VertexKey): VO[];\n\n abstract getEndsOfEdge(edge: EO): [VO, VO] | undefined;\n\n /**\n * Time Complexity: O(1) - Constant time for Map lookup.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function \"getVertex\" returns the vertex with the specified ID or undefined if it doesn't exist.\n * @param {VertexKey} vertexKey - The `vertexKey` parameter is the identifier of the vertex that you want to retrieve from\n * the `_vertexMap` map.\n * @returns The method `getVertex` returns the vertex with the specified `vertexKey` if it exists in the `_vertexMap`\n * map. If the vertex does not exist, it returns `undefined`.\n */\n getVertex(vertexKey: VertexKey): VO | undefined {\n return this._vertexMap.get(vertexKey) || undefined;\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map lookup.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function checks if a vertex exists in a graph.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns a boolean value.\n */\n hasVertex(vertexOrKey: VO | VertexKey): boolean {\n return this._vertexMap.has(this._getVertexKey(vertexOrKey));\n }\n\n addVertex(vertex: VO): boolean;\n\n addVertex(key: VertexKey, value?: V): boolean;\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n */\n\n addVertex(keyOrVertex: VertexKey | VO, value?: V): boolean {\n if (keyOrVertex instanceof AbstractVertex) {\n return this._addVertex(keyOrVertex);\n } else {\n const newVertex = this.createVertex(keyOrVertex, value);\n return this._addVertex(newVertex);\n }\n }\n\n isVertexKey(potentialKey: any): potentialKey is VertexKey {\n const potentialKeyType = typeof potentialKey;\n return potentialKeyType === 'string' || potentialKeyType === 'number';\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n */\n\n abstract deleteVertex(vertexOrKey: VO | VertexKey): boolean;\n\n /**\n * Time Complexity: O(K), where K is the number of vertexMap to be removed.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function removes all vertexMap from a graph and returns a boolean indicating if any vertexMap were removed.\n * @param {VO[] | VertexKey[]} vertexMap - The `vertexMap` parameter can be either an array of vertexMap (`VO[]`) or an array\n * of vertex IDs (`VertexKey[]`).\n * @returns a boolean value. It returns true if at least one vertex was successfully removed, and false if no vertexMap\n * were removed.\n */\n removeManyVertices(vertexMap: VO[] | VertexKey[]): boolean {\n const removed: boolean[] = [];\n for (const v of vertexMap) {\n removed.push(this.deleteVertex(v));\n }\n return removed.length > 0;\n }\n\n /**\n * Time Complexity: O(1) - Depends on the implementation in the concrete class.\n * Space Complexity: O(1) - Depends on the implementation in the concrete class.\n *\n * The function checks if there is an edge between two vertexMap and returns a boolean value indicating the result.\n * @param {VertexKey | VO} v1 - The parameter v1 can be either a VertexKey or a VO. A VertexKey represents the unique\n * identifier of a vertex in a graph, while VO represents the type of the vertex object itself.\n * @param {VertexKey | VO} v2 - The parameter `v2` represents the second vertex in the edge. It can be either a\n * `VertexKey` or a `VO` type, which represents the type of the vertex.\n * @returns A boolean value is being returned.\n */\n hasEdge(v1: VertexKey | VO, v2: VertexKey | VO): boolean {\n const edge = this.getEdge(v1, v2);\n return !!edge;\n }\n\n addEdge(edge: EO): boolean;\n\n addEdge(src: VO | VertexKey, dest: VO | VertexKey, weight?: number, value?: E): boolean;\n\n /**\n * Time Complexity: O(1) - Depends on the implementation in the concrete class.\n * Space Complexity: O(1) - Depends on the implementation in the concrete class.\n */\n\n addEdge(srcOrEdge: VO | VertexKey | EO, dest?: VO | VertexKey, weight?: number, value?: E): boolean {\n if (srcOrEdge instanceof AbstractEdge) {\n return this._addEdge(srcOrEdge);\n } else {\n if (dest instanceof AbstractVertex || typeof dest === 'string' || typeof dest === 'number') {\n if (!(this.hasVertex(srcOrEdge) && this.hasVertex(dest))) return false;\n if (srcOrEdge instanceof AbstractVertex) srcOrEdge = srcOrEdge.key;\n if (dest instanceof AbstractVertex) dest = dest.key;\n const newEdge = this.createEdge(srcOrEdge, dest, weight, value);\n return this._addEdge(newEdge);\n } else {\n throw new Error('dest must be a Vertex or vertex key while srcOrEdge is an Edge');\n }\n }\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map and Edge operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The function sets the weight of an edge between two vertexMap in a graph.\n * @param {VertexKey | VO} srcOrKey - The `srcOrKey` parameter can be either a `VertexKey` or a `VO` object. It represents\n * the source vertex of the edge.\n * @param {VertexKey | VO} destOrKey - The `destOrKey` parameter represents the destination vertex of the edge. It can be\n * either a `VertexKey` or a vertex object `VO`.\n * @param {number} weight - The weight parameter represents the weight of the edge between the source vertex (srcOrKey)\n * and the destination vertex (destOrKey).\n * @returns a boolean value. If the edge exists between the source and destination vertexMap, the function will update\n * the weight of the edge and return true. If the edge does not exist, the function will return false.\n */\n setEdgeWeight(srcOrKey: VertexKey | VO, destOrKey: VertexKey | VO, weight: number): boolean {\n const edge = this.getEdge(srcOrKey, destOrKey);\n if (edge) {\n edge.weight = weight;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Time Complexity: O(P), where P is the number of paths found (in the worst case, exploring all paths).\n * Space Complexity: O(P) - Linear space, where P is the number of paths found.\n *\n * The function `getAllPathsBetween` finds all paths between two vertexMap in a graph using depth-first search.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).\n * It is the starting vertex for finding paths.\n * @param {VO | VertexKey} v2 - The parameter `v2` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).\n * @param limit - The count of limitation of result array.\n * @returns The function `getAllPathsBetween` returns an array of arrays of vertexMap (`VO[][]`).\n */\n getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey, limit = 1000): VO[][] {\n const paths: VO[][] = [];\n const vertex1 = this._getVertex(v1);\n const vertex2 = this._getVertex(v2);\n\n if (!(vertex1 && vertex2)) {\n return [];\n }\n\n const stack: { vertex: VO; path: VO[] }[] = [];\n stack.push({ vertex: vertex1, path: [vertex1] });\n\n while (stack.length > 0) {\n const { vertex, path } = stack.pop()!;\n\n if (vertex === vertex2) {\n paths.push(path);\n if (paths.length >= limit) return paths;\n }\n\n const neighbors = this.getNeighbors(vertex);\n for (const neighbor of neighbors) {\n if (!path.includes(neighbor)) {\n const newPath = [...path, neighbor];\n stack.push({ vertex: neighbor, path: newPath });\n }\n }\n }\n return paths;\n }\n\n /**\n * Time Complexity: O(L), where L is the length of the path.\n * Space Complexity: O(1) - Constant space.\n *\n * The function calculates the sum of weights along a given path.\n * @param {VO[]} path - An array of vertexMap (VO) representing a path in a graph.\n * @returns The function `getPathSumWeight` returns the sum of the weights of the edgeMap in the given path.\n */\n getPathSumWeight(path: VO[]): number {\n let sum = 0;\n for (let i = 0; i < path.length; i++) {\n sum += this.getEdge(path[i], path[i + 1])?.weight || 0;\n }\n return sum;\n }\n\n /**\n * Time Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).\n * Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).\n *\n * The function `getMinCostBetween` calculates the minimum cost between two vertexMap in a graph, either based on edge\n * weights or using a breadth-first search algorithm.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex or its ID.\n * @param {VO | VertexKey} v2 - The parameter `v2` represents the destination vertex or its ID. It is the vertex to which\n * you want to find the minimum cost or weight from the source vertex `v1`.\n * @param {boolean} [isWeight] - isWeight is an optional parameter that indicates whether the graph edgeMap have weights.\n * If isWeight is set to true, the function will calculate the minimum cost between v1 and v2 based on the weights of\n * the edgeMap. If isWeight is set to false or not provided, the function will calculate the\n * @returns The function `getMinCostBetween` returns a number representing the minimum cost between two vertexMap (`v1`\n * and `v2`). If the `isWeight` parameter is `true`, it calculates the minimum weight among all paths between the\n * vertexMap. If `isWeight` is `false` or not provided, it uses a breadth-first search (BFS) algorithm to calculate the\n * minimum number of\n */\n getMinCostBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): number | undefined {\n if (isWeight === undefined) isWeight = false;\n\n if (isWeight) {\n const allPaths = this.getAllPathsBetween(v1, v2);\n let min = Infinity;\n for (const path of allPaths) {\n min = Math.min(this.getPathSumWeight(path), min);\n }\n return min;\n } else {\n // BFS\n const vertex2 = this._getVertex(v2);\n const vertex1 = this._getVertex(v1);\n if (!(vertex1 && vertex2)) {\n return undefined;\n }\n\n const visited: Map<VO, boolean> = new Map();\n const queue = new Queue<VO>([vertex1]);\n visited.set(vertex1, true);\n let cost = 0;\n while (queue.size > 0) {\n for (let i = 0; i < queue.size; i++) {\n const cur = queue.shift();\n if (cur === vertex2) {\n return cost;\n }\n // TODO consider optimizing to AbstractGraph\n if (cur !== undefined) {\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor)) {\n visited.set(neighbor, true);\n queue.push(neighbor);\n }\n }\n }\n }\n cost++;\n }\n return undefined;\n }\n }\n\n /**\n * Time Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm or DFS).\n * Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm or DFS).\n *\n * The function `getMinPathBetween` returns the minimum path between two vertexMap in a graph, either based on weight or\n * using a breadth-first search algorithm.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex of the path. It can be either a vertex\n * object (`VO`) or a vertex ID (`VertexKey`).\n * @param {VO | VertexKey} v2 - VO | VertexKey - The second vertex or vertex ID between which we want to find the minimum\n * path.\n * @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edgeMap in finding the\n * minimum path. If set to true, the function will use Dijkstra's algorithm to find the minimum weighted path. If set\n * to false, the function will use breadth-first search (BFS) to find the minimum path.\n * @param isDFS - If set to true, it enforces the use of getAllPathsBetween to first obtain all possible paths,\n * followed by iterative computation of the shortest path. This approach may result in exponential time complexity,\n * so the default method is to use the Dijkstra algorithm to obtain the shortest weighted path.\n * @returns The function `getMinPathBetween` returns an array of vertexMap (`VO[]`) representing the minimum path between\n * two vertexMap (`v1` and `v2`). If there is no path between the vertexMap, it returns `undefined`.\n */\n getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean, isDFS = false): VO[] | undefined {\n if (isWeight === undefined) isWeight = false;\n\n if (isWeight) {\n if (isDFS) {\n const allPaths = this.getAllPathsBetween(v1, v2, 10000);\n let min = Infinity;\n let minIndex = -1;\n let index = 0;\n for (const path of allPaths) {\n const pathSumWeight = this.getPathSumWeight(path);\n if (pathSumWeight < min) {\n min = pathSumWeight;\n minIndex = index;\n }\n index++;\n }\n return allPaths[minIndex] || undefined;\n } else {\n return this.dijkstra(v1, v2, true, true)?.minPath ?? [];\n }\n } else {\n // DFS\n let minPath: VO[] = [];\n const vertex1 = this._getVertex(v1);\n const vertex2 = this._getVertex(v2);\n if (!(vertex1 && vertex2)) return [];\n\n const dfs = (cur: VO, dest: VO, visiting: Set<VO>, path: VO[]) => {\n visiting.add(cur);\n if (cur === dest) {\n minPath = [vertex1, ...path];\n return;\n }\n\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!visiting.has(neighbor)) {\n path.push(neighbor);\n dfs(neighbor, dest, visiting, path);\n path.pop();\n }\n }\n\n visiting.delete(cur);\n };\n\n dfs(vertex1, vertex2, new Set<VO>(), []);\n return minPath;\n }\n }\n\n /**\n * Time Complexity: O(V^2 + E) - Quadratic time in the worst case (no heap optimization).\n * Space Complexity: O(V + E) - Depends on the implementation (Dijkstra's algorithm).\n *\n * The function `dijkstraWithoutHeap` implements Dijkstra's algorithm to find the shortest path between two vertexMap in\n * a graph without using a heap data structure.\n * @param {VO | VertexKey} src - The source vertex from which to start the Dijkstra's algorithm. It can be either a\n * vertex object or a vertex ID.\n * @param {VO | VertexKey | undefined} [dest] - The `dest` parameter in the `dijkstraWithoutHeap` function is an optional\n * parameter that specifies the destination vertex for the Dijkstra algorithm. It can be either a vertex object or its\n * identifier. If no destination is provided, the value is set to `undefined`.\n * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum\n * distance from the source vertex to the destination vertex should be calculated and returned in the result. If\n * `getMinDist` is set to `true`, the `minDist` property in the result will contain the minimum distance\n * @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate\n * paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the\n * shortest paths from the source vertex to all other vertexMap in the graph. If `genPaths\n * @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<VO>`.\n */\n dijkstraWithoutHeap(\n src: VO | VertexKey,\n dest: VO | VertexKey | undefined = undefined,\n getMinDist: boolean = false,\n genPaths: boolean = false\n ): DijkstraResult<VO> {\n let minDist = Infinity;\n let minDest: VO | undefined = undefined;\n let minPath: VO[] = [];\n const paths: VO[][] = [];\n\n const vertexMap = this._vertexMap;\n const distMap: Map<VO, number> = new Map();\n const seen: Set<VO> = new Set();\n const preMap: Map<VO, VO | undefined> = new Map(); // predecessor\n const srcVertex = this._getVertex(src);\n\n const destVertex = dest ? this._getVertex(dest) : undefined;\n\n if (!srcVertex) {\n return undefined;\n }\n\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);\n }\n distMap.set(srcVertex, 0);\n preMap.set(srcVertex, undefined);\n\n const getMinOfNoSeen = () => {\n let min = Infinity;\n let minV: VO | undefined = undefined;\n for (const [key, value] of distMap) {\n if (!seen.has(key)) {\n if (value < min) {\n min = value;\n minV = key;\n }\n }\n }\n return minV;\n };\n\n const getPaths = (minV: VO | undefined) => {\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n\n if (vertexOrKey instanceof AbstractVertex) {\n const path: VO[] = [vertexOrKey];\n let parent = preMap.get(vertexOrKey);\n while (parent) {\n path.push(parent);\n parent = preMap.get(parent);\n }\n const reversed = path.reverse();\n if (vertex[1] === minV) minPath = reversed;\n paths.push(reversed);\n }\n }\n };\n\n for (let i = 1; i < vertexMap.size; i++) {\n const cur = getMinOfNoSeen();\n if (cur) {\n seen.add(cur);\n if (destVertex && destVertex === cur) {\n if (getMinDist) {\n minDist = distMap.get(destVertex) || Infinity;\n }\n if (genPaths) {\n getPaths(destVertex);\n }\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!seen.has(neighbor)) {\n const edge = this.getEdge(cur, neighbor);\n if (edge) {\n const curFromMap = distMap.get(cur);\n const neighborFromMap = distMap.get(neighbor);\n // TODO after no-non-undefined-assertion not ensure the logic\n if (curFromMap !== undefined && neighborFromMap !== undefined) {\n if (edge.weight + curFromMap < neighborFromMap) {\n distMap.set(neighbor, edge.weight + curFromMap);\n preMap.set(neighbor, cur);\n }\n }\n }\n }\n }\n }\n }\n\n if (getMinDist)\n distMap.forEach((d, v) => {\n if (v !== srcVertex) {\n if (d < minDist) {\n minDist = d;\n if (genPaths) minDest = v;\n }\n }\n });\n\n if (genPaths) getPaths(minDest);\n\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n\n /**\n * Time Complexity: O((V + E) * log(V)) - Depends on the implementation (using a binary heap).\n * Space Complexity: O(V + E) - Depends on the implementation (using a binary heap).\n *\n * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative.\n * The `dijkstra` function implements Dijkstra's algorithm to find the shortest path between a source vertex and an\n * optional destination vertex, and optionally returns the minimum distance, the paths, and other information.\n * @param {VO | VertexKey} src - The `src` parameter represents the source vertex from which the Dijkstra algorithm will\n * start. It can be either a vertex object or a vertex ID.\n * @param {VO | VertexKey | undefined} [dest] - The `dest` parameter is the destination vertex or vertex ID. It specifies the\n * vertex to which the shortest path is calculated from the source vertex. If no destination is provided, the algorithm\n * will calculate the shortest paths to all other vertexMap from the source vertex.\n * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum\n * distance from the source vertex to the destination vertex should be calculated and returned in the result. If\n * `getMinDist` is set to `true`, the `minDist` property in the result will contain the minimum distance\n * @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate\n * paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the\n * shortest paths from the source vertex to all other vertexMap in the graph. If `genPaths\n * @returns The function `dijkstra` returns an object of type `DijkstraResult<VO>`.\n */\n dijkstra(\n src: VO | VertexKey,\n dest: VO | VertexKey | undefined = undefined,\n getMinDist: boolean = false,\n genPaths: boolean = false\n ): DijkstraResult<VO> {\n let minDist = Infinity;\n let minDest: VO | undefined = undefined;\n let minPath: VO[] = [];\n const paths: VO[][] = [];\n const vertexMap = this._vertexMap;\n const distMap: Map<VO, number> = new Map();\n const seen: Set<VO> = new Set();\n const preMap: Map<VO, VO | undefined> = new Map(); // predecessor\n\n const srcVertex = this._getVertex(src);\n const destVertex = dest ? this._getVertex(dest) : undefined;\n\n if (!srcVertex) return undefined;\n\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);\n }\n\n const heap = new Heap<{ key: number; value: VO }>([], { comparator: (a, b) => a.key - b.key });\n heap.add({ key: 0, value: srcVertex });\n\n distMap.set(srcVertex, 0);\n preMap.set(srcVertex, undefined);\n\n /**\n * The function `getPaths` retrieves all paths from vertexMap to a specified minimum vertex.\n * @param {VO | undefined} minV - The parameter `minV` is of type `VO | undefined`. It represents the minimum vertex value or\n * undefined.\n */\n const getPaths = (minV: VO | undefined) => {\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) {\n const path: VO[] = [vertexOrKey];\n let parent = preMap.get(vertexOrKey);\n while (parent) {\n path.push(parent);\n parent = preMap.get(parent);\n }\n const reversed = path.reverse();\n if (vertex[1] === minV) minPath = reversed;\n paths.push(reversed);\n }\n }\n };\n\n while (heap.size > 0) {\n const curHeapNode = heap.poll();\n const dist = curHeapNode?.key;\n const cur = curHeapNode?.value;\n if (dist !== undefined) {\n if (cur) {\n seen.add(cur);\n if (destVertex && destVertex === cur) {\n if (getMinDist) {\n minDist = distMap.get(destVertex) || Infinity;\n }\n if (genPaths) {\n getPaths(destVertex);\n }\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n const neighbors = this.getNeighbors(cur);\n for (const neighbor of neighbors) {\n if (!seen.has(neighbor)) {\n const weight = this.getEdge(cur, neighbor)?.weight;\n if (typeof weight === 'number') {\n const distSrcToNeighbor = distMap.get(neighbor);\n if (distSrcToNeighbor) {\n if (dist + weight < distSrcToNeighbor) {\n heap.add({ key: dist + weight, value: neighbor });\n preMap.set(neighbor, cur);\n distMap.set(neighbor, dist + weight);\n }\n }\n }\n }\n }\n }\n }\n }\n\n if (getMinDist) {\n distMap.forEach((d, v) => {\n if (v !== srcVertex) {\n if (d < minDist) {\n minDist = d;\n if (genPaths) minDest = v;\n }\n }\n });\n }\n\n if (genPaths) {\n getPaths(minDest);\n }\n\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n\n /**\n * Time Complexity: O(V * E) - Quadratic time in the worst case (Bellman-Ford algorithm).\n * Space Complexity: O(V + E) - Depends on the implementation (Bellman-Ford algorithm).\n *\n * one to rest pairs\n * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edgeMap for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edgeMap, the Bellman-Ford algorithm is more flexible in some scenarios.\n * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to\n * all other vertexMap in a graph, and optionally detects negative cycles and generates the minimum path.\n * @param {VO | VertexKey} src - The `src` parameter is the source vertex from which the Bellman-Ford algorithm will\n * start calculating the shortest paths. It can be either a vertex object or a vertex ID.\n * @param {boolean} [scanNegativeCycle] - A boolean flag indicating whether to scan for negative cycles in the graph.\n * @param {boolean} [getMin] - The `getMin` parameter is a boolean flag that determines whether the algorithm should\n * calculate the minimum distance from the source vertex to all other vertexMap in the graph. If `getMin` is set to\n * `true`, the algorithm will find the minimum distance and update the `min` variable with the minimum\n * @param {boolean} [genPath] - A boolean flag indicating whether to generate paths for all vertexMap from the source\n * vertex.\n * @returns The function `bellmanFord` returns an object with the following properties:\n */\n bellmanFord(src: VO | VertexKey, scanNegativeCycle?: boolean, getMin?: boolean, genPath?: boolean) {\n if (getMin === undefined) getMin = false;\n if (genPath === undefined) genPath = false;\n\n const srcVertex = this._getVertex(src);\n const paths: VO[][] = [];\n const distMap: Map<VO, number> = new Map();\n const preMap: Map<VO, VO> = new Map(); // predecessor\n let min = Infinity;\n let minPath: VO[] = [];\n // TODO\n let hasNegativeCycle: boolean | undefined;\n if (scanNegativeCycle) hasNegativeCycle = false;\n if (!srcVertex) return { hasNegativeCycle, distMap, preMap, paths, min, minPath };\n\n const vertexMap = this._vertexMap;\n const numOfVertices = vertexMap.size;\n const edgeMap = this.edgeSet();\n const numOfEdges = edgeMap.length;\n\n this._vertexMap.forEach(vertex => {\n distMap.set(vertex, Infinity);\n });\n\n distMap.set(srcVertex, 0);\n\n for (let i = 1; i < numOfVertices; ++i) {\n for (let j = 0; j < numOfEdges; ++j) {\n const ends = this.getEndsOfEdge(edgeMap[j]);\n if (ends) {\n const [s, d] = ends;\n const weight = edgeMap[j].weight;\n const sWeight = distMap.get(s);\n const dWeight = distMap.get(d);\n if (sWeight !== undefined && dWeight !== undefined) {\n if (distMap.get(s) !== Infinity && sWeight + weight < dWeight) {\n distMap.set(d, sWeight + weight);\n if (genPath) preMap.set(d, s);\n }\n }\n }\n }\n }\n\n let minDest: VO | undefined = undefined;\n if (getMin) {\n distMap.forEach((d, v) => {\n if (v !== srcVertex) {\n if (d < min) {\n min = d;\n if (genPath) minDest = v;\n }\n }\n });\n }\n\n if (genPath) {\n for (const vertex of vertexMap) {\n const vertexOrKey = vertex[1];\n if (vertexOrKey instanceof AbstractVertex) {\n const path: VO[] = [vertexOrKey];\n let parent = preMap.get(vertexOrKey);\n while (parent !== undefined) {\n path.push(parent);\n parent = preMap.get(parent);\n }\n const reversed = path.reverse();\n if (vertex[1] === minDest) minPath = reversed;\n paths.push(reversed);\n }\n }\n }\n\n for (let j = 0; j < numOfEdges; ++j) {\n const ends = this.getEndsOfEdge(edgeMap[j]);\n if (ends) {\n const [s] = ends;\n const weight = edgeMap[j].weight;\n const sWeight = distMap.get(s);\n if (sWeight) {\n if (sWeight !== Infinity && sWeight + weight < sWeight) hasNegativeCycle = true;\n }\n }\n }\n\n return { hasNegativeCycle, distMap, preMap, paths, min, minPath };\n }\n\n /**\n * Dijkstra algorithm time: O(logVE) space: O(VO + EO)\n */\n\n /**\n * Dijkstra algorithm time: O(logVE) space: O(VO + EO)\n * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative.\n */\n\n /**\n * BellmanFord time:O(VE) space:O(VO)\n * one to rest pairs\n * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edgeMap for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edgeMap, the Bellman-Ford algorithm is more flexible in some scenarios.\n * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to\n */\n\n /**\n * Time Complexity: O(V^3) - Cubic time (Floyd-Warshall algorithm).\n * Space Complexity: O(V^2) - Quadratic space (Floyd-Warshall algorithm).\n *\n * Not support graph with negative weight cycle\n * all pairs\n * The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edgeMap, and it can simultaneously compute shortest paths between any two nodes.\n * The function implements the Floyd-Warshall algorithm to find the shortest path between all pairs of vertexMap in a\n * graph.\n * @returns The function `floydWarshall()` returns an object with two properties: `costs` and `predecessor`. The `costs`\n * property is a 2D array of numbers representing the shortest path costs between vertexMap in a graph. The\n * `predecessor` property is a 2D array of vertexMap (or `undefined`) representing the predecessor vertexMap in the shortest\n * path between vertexMap in the\n */\n floydWarshall(): { costs: number[][]; predecessor: (VO | undefined)[][] } {\n const idAndVertices = [...this._vertexMap];\n const n = idAndVertices.length;\n\n const costs: number[][] = [];\n const predecessor: (VO | undefined)[][] = [];\n // successors\n\n for (let i = 0; i < n; i++) {\n costs[i] = [];\n predecessor[i] = [];\n for (let j = 0; j < n; j++) {\n predecessor[i][j] = undefined;\n }\n }\n\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n costs[i][j] = this.getEdge(idAndVertices[i][1], idAndVertices[j][1])?.weight || Infinity;\n }\n }\n\n for (let k = 0; k < n; k++) {\n for (let i = 0; i < n; i++) {\n for (let j = 0; j < n; j++) {\n if (costs[i][j] > costs[i][k] + costs[k][j]) {\n costs[i][j] = costs[i][k] + costs[k][j];\n predecessor[i][j] = idAndVertices[k][1];\n }\n }\n }\n }\n return { costs, predecessor };\n }\n\n /**\n * O(V+E+C)\n * O(V+C)\n */\n getCycles(isInclude2Cycle: boolean = false): VertexKey[][] {\n const cycles: VertexKey[][] = [];\n const visited: Set<VO> = new Set();\n\n const dfs = (vertex: VO, currentPath: VertexKey[], visited: Set<VO>) => {\n if (visited.has(vertex)) {\n if (\n ((!isInclude2Cycle && currentPath.length > 2) || (isInclude2Cycle && currentPath.length >= 2)) &&\n currentPath[0] === vertex.key\n ) {\n cycles.push([...currentPath]);\n }\n return;\n }\n\n visited.add(vertex);\n currentPath.push(vertex.key);\n\n for (const neighbor of this.getNeighbors(vertex)) {\n if (neighbor) dfs(neighbor, currentPath, visited);\n }\n\n visited.delete(vertex);\n currentPath.pop();\n };\n\n for (const vertex of this.vertexMap.values()) {\n dfs(vertex, [], visited);\n }\n\n // Use a set to eliminate duplicate cycles\n const uniqueCycles = new Map<string, VertexKey[]>();\n\n for (const cycle of cycles) {\n const sorted = [...cycle].sort().toString();\n\n if (uniqueCycles.has(sorted)) continue;\n else {\n uniqueCycles.set(sorted, cycle);\n }\n }\n\n // Convert the unique cycles back to an array\n return [...uniqueCycles].map(cycleString => cycleString[1]);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function iterates over key-value pairs in a data structure and returns an array of\n * pairs that satisfy a given predicate.\n * @param predicate - The `predicate` parameter is a callback function that takes four arguments:\n * `value`, `key`, `index`, and `this`. It is used to determine whether an element should be included\n * in the filtered array. The callback function should return `true` if the element should be\n * included, and `\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the `predicate` function. It is used when you want to bind a\n * specific object as the context for the `predicate` function. If `thisArg` is provided, it will be\n * @returns The `filter` method returns an array of key-value pairs `[VertexKey, V | undefined][]`\n * that satisfy the given predicate function.\n */\n filter(predicate: EntryCallback<VertexKey, V | undefined, boolean>, thisArg?: any): [VertexKey, V | undefined][] {\n const filtered: [VertexKey, V | undefined][] = [];\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index, this)) {\n filtered.push([key, value]);\n }\n index++;\n }\n return filtered;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function iterates over the elements of a collection and applies a callback function to\n * each element, returning an array of the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * map. It takes four arguments:\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. If `thisArg` is provided, it will be\n * used as the `this` value when calling the callback function. If `thisArg` is not provided, `\n * @returns The `map` function is returning an array of type `T[]`.\n */\n map<T>(callback: EntryCallback<VertexKey, V | undefined, T>, thisArg?: any): T[] {\n const mapped: T[] = [];\n let index = 0;\n for (const [key, value] of this) {\n mapped.push(callback.call(thisArg, value, key, index, this));\n index++;\n }\n return mapped;\n }\n\n protected *_getIterator(): IterableIterator<[VertexKey, V | undefined]> {\n for (const vertex of this._vertexMap.values()) {\n yield [vertex.key, vertex.value];\n }\n }\n\n protected abstract _addEdge(edge: EO): boolean;\n\n protected _addVertex(newVertex: VO): boolean {\n if (this.hasVertex(newVertex)) {\n return false;\n // throw (new Error('Duplicated vertex key is not allowed'));\n }\n this._vertexMap.set(newVertex.key, newVertex);\n return true;\n }\n\n protected _getVertex(vertexOrKey: VertexKey | VO): VO | undefined {\n const vertexKey = this._getVertexKey(vertexOrKey);\n return this._vertexMap.get(vertexKey) || undefined;\n }\n\n protected _getVertexKey(vertexOrKey: VO | VertexKey): VertexKey {\n return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { TopologicalStatus, VertexKey } from '../../types';\nimport { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';\nimport { IGraph } from '../../interfaces';\nimport { arrayRemove } from '../../utils';\n\nexport class DirectedVertex<V = any> extends AbstractVertex<V> {\n /**\n * The constructor function initializes a vertex with an optional value.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex. It is\n * used to uniquely identify the vertex within a graph or data structure.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It is used to initialize the value of the\n * vertex. If no value is provided, the vertex will be initialized with a default value.\n */\n constructor(key: VertexKey, value?: V) {\n super(key, value);\n }\n}\n\nexport class DirectedEdge<E = any> extends AbstractEdge<E> {\n src: VertexKey;\n dest: VertexKey;\n\n /**\n * The constructor function initializes the source and destination vertexMap of an edge, along with an optional weight\n * and value.\n * @param {VertexKey} src - The `src` parameter is the source vertex ID. It represents the starting point of an edge in\n * a graph.\n * @param {VertexKey} dest - The `dest` parameter represents the destination vertex of an edge. It is of type\n * `VertexKey`, which is likely a unique identifier for a vertex in a graph.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.\n * @param {E} [value] - The `value` parameter is an optional parameter of type `E`. It represents the value associated with\n * the edge.\n */\n constructor(src: VertexKey, dest: VertexKey, weight?: number, value?: E) {\n super(weight, value);\n this.src = src;\n this.dest = dest;\n }\n}\n\nexport class DirectedGraph<\n V = any,\n E = any,\n VO extends DirectedVertex<V> = DirectedVertex<V>,\n EO extends DirectedEdge<E> = DirectedEdge<E>\n >\n extends AbstractGraph<V, E, VO, EO>\n implements IGraph<V, E, VO, EO>\n{\n /**\n * The constructor function initializes an instance of a class.\n */\n constructor() {\n super();\n }\n\n protected _outEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();\n\n get outEdgeMap(): Map<VO, EO[]> {\n return this._outEdgeMap;\n }\n\n set outEdgeMap(v: Map<VO, EO[]>) {\n this._outEdgeMap = v;\n }\n\n protected _inEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();\n\n get inEdgeMap(): Map<VO, EO[]> {\n return this._inEdgeMap;\n }\n\n set inEdgeMap(v: Map<VO, EO[]>) {\n this._inEdgeMap = v;\n }\n\n /**\n * The function creates a new vertex with an optional value and returns it.\n * @param {VertexKey} key - The `key` parameter is the unique identifier for the vertex. It is of type `VertexKey`, which\n * could be a number or a string depending on how you want to identify your vertexMap.\n * @param [value] - The 'value' parameter is an optional value that can be assigned to the vertex. If a value is provided,\n * it will be assigned to the 'value' property of the vertex. If no value is provided, the 'value' property will be\n * assigned the same value as the 'key' parameter\n * @returns a new instance of a DirectedVertex object, casted as type VO.\n */\n createVertex(key: VertexKey, value?: V): VO {\n return new DirectedVertex(key, value) as VO;\n }\n\n /**\n * The function creates a directed edge between two vertexMap with an optional weight and value.\n * @param {VertexKey} src - The source vertex ID of the edge. It represents the starting point of the edge.\n * @param {VertexKey} dest - The `dest` parameter is the identifier of the destination vertex for the edge.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge. If no\n * weight is provided, it defaults to 1.\n * @param [value] - The 'value' parameter is an optional value that can be assigned to the edge. It can be of any type and\n * is used to store additional information or data associated with the edge.\n * @returns a new instance of a DirectedEdge object, casted as type EO.\n */\n createEdge(src: VertexKey, dest: VertexKey, weight?: number, value?: E): EO {\n return new DirectedEdge(src, dest, weight ?? 1, value) as EO;\n }\n\n /**\n * Time Complexity: O(|V|) where |V| is the number of vertexMap\n * Space Complexity: O(1)\n *\n * The `getEdge` function retrieves an edge between two vertexMap based on their source and destination IDs.\n * @param {VO | VertexKey | undefined} srcOrKey - The source vertex or its ID. It can be either a vertex object or a vertex ID.\n * @param {VO | VertexKey | undefined} destOrKey - The `destOrKey` parameter in the `getEdge` function represents the\n * destination vertex of the edge. It can be either a vertex object (`VO`), a vertex ID (`VertexKey`), or `undefined` if the\n * destination is not specified.\n * @returns the first edge found between the source and destination vertexMap, or undefined if no such edge is found.\n */\n getEdge(srcOrKey: VO | VertexKey | undefined, destOrKey: VO | VertexKey | undefined): EO | undefined {\n let edgeMap: EO[] = [];\n\n if (srcOrKey !== undefined && destOrKey !== undefined) {\n const src: VO | undefined = this._getVertex(srcOrKey);\n const dest: VO | undefined = this._getVertex(destOrKey);\n\n if (src && dest) {\n const srcOutEdges = this._outEdgeMap.get(src);\n if (srcOutEdges) {\n edgeMap = srcOutEdges.filter(edge => edge.dest === dest.key);\n }\n }\n }\n\n return edgeMap[0] || undefined;\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function removes an edge between two vertexMap in a graph and returns the removed edge.\n * @param {VO | VertexKey} srcOrKey - The source vertex or its ID.\n * @param {VO | VertexKey} destOrKey - The `destOrKey` parameter represents the destination vertex or its ID.\n * @returns the removed edge (EO) if it exists, or undefined if either the source or destination vertex does not exist.\n */\n deleteEdgeSrcToDest(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined {\n const src: VO | undefined = this._getVertex(srcOrKey);\n const dest: VO | undefined = this._getVertex(destOrKey);\n let removed: EO | undefined = undefined;\n if (!src || !dest) {\n return undefined;\n }\n\n const srcOutEdges = this._outEdgeMap.get(src);\n if (srcOutEdges) {\n arrayRemove<EO>(srcOutEdges, (edge: EO) => edge.dest === dest.key);\n }\n\n const destInEdges = this._inEdgeMap.get(dest);\n if (destInEdges) {\n removed = arrayRemove<EO>(destInEdges, (edge: EO) => edge.src === src.key)[0] || undefined;\n }\n return removed;\n }\n\n /**\n * Time Complexity: O(E) where E is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The `deleteEdge` function removes an edge from a graph and returns the removed edge.\n * @param {EO | VertexKey} edgeOrSrcVertexKey - The `edge` parameter can be either an `EO` object (edge object) or\n * a `VertexKey` (key of a vertex).\n * @param {VertexKey} [destVertexKey] - The `destVertexKey` parameter is an optional parameter that\n * represents the key of the destination vertex of the edge. It is used to specify the destination\n * vertex when the `edge` parameter is a vertex key. If `destVertexKey` is not provided, the function\n * assumes that the `edge`\n * @returns the removed edge (EO) or undefined if no edge was removed.\n */\n deleteEdge(edgeOrSrcVertexKey: EO | VertexKey, destVertexKey?: VertexKey): EO | undefined {\n let removed: EO | undefined = undefined;\n let src: VO | undefined, dest: VO | undefined;\n if (this.isVertexKey(edgeOrSrcVertexKey)) {\n if (this.isVertexKey(destVertexKey)) {\n src = this._getVertex(edgeOrSrcVertexKey);\n dest = this._getVertex(destVertexKey);\n } else {\n return;\n }\n } else {\n src = this._getVertex(edgeOrSrcVertexKey.src);\n dest = this._getVertex(edgeOrSrcVertexKey.dest);\n }\n\n if (src && dest) {\n const srcOutEdges = this._outEdgeMap.get(src);\n if (srcOutEdges && srcOutEdges.length > 0) {\n arrayRemove(srcOutEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest?.key);\n }\n\n const destInEdges = this._inEdgeMap.get(dest);\n if (destInEdges && destInEdges.length > 0) {\n removed = arrayRemove(destInEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest!.key)[0];\n }\n }\n\n return removed;\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method is returning a boolean value.\n */\n deleteVertex(vertexOrKey: VO | VertexKey): boolean {\n let vertexKey: VertexKey;\n let vertex: VO | undefined;\n if (this.isVertexKey(vertexOrKey)) {\n vertex = this.getVertex(vertexOrKey);\n vertexKey = vertexOrKey;\n } else {\n vertex = vertexOrKey;\n vertexKey = this._getVertexKey(vertexOrKey);\n }\n\n if (vertex) {\n const neighbors = this.getNeighbors(vertex);\n for (const neighbor of neighbors) {\n // this._inEdgeMap.delete(neighbor);\n this.deleteEdgeSrcToDest(vertex, neighbor);\n }\n this._outEdgeMap.delete(vertex);\n this._inEdgeMap.delete(vertex);\n }\n\n return this._vertexMap.delete(vertexKey);\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function removes edgeMap between two vertexMap and returns the removed edgeMap.\n * @param {VertexKey | VO} v1 - The parameter `v1` can be either a `VertexKey` or a `VO`. A `VertexKey` represents the\n * unique identifier of a vertex in a graph, while `VO` represents the actual vertex object.\n * @param {VertexKey | VO} v2 - The parameter `v2` represents either a `VertexKey` or a `VO` object. It is used to specify\n * the second vertex in the edge that needs to be removed.\n * @returns an array of removed edgeMap (EO[]).\n */\n deleteEdgesBetween(v1: VertexKey | VO, v2: VertexKey | VO): EO[] {\n const removed: EO[] = [];\n\n if (v1 && v2) {\n const v1ToV2 = this.deleteEdgeSrcToDest(v1, v2);\n const v2ToV1 = this.deleteEdgeSrcToDest(v2, v1);\n\n if (v1ToV2) removed.push(v1ToV2);\n if (v2ToV1) removed.push(v2ToV1);\n }\n\n return removed;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `incomingEdgesOf` returns an array of incoming edgeMap for a given vertex or vertex ID.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method `incomingEdgesOf` returns an array of edgeMap (`EO[]`).\n */\n incomingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {\n const target = this._getVertex(vertexOrKey);\n if (target) {\n return this.inEdgeMap.get(target) || [];\n }\n return [];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `outgoingEdgesOf` returns an array of outgoing edgeMap from a given vertex or vertex ID.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can accept either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method `outgoingEdgesOf` returns an array of edgeMap (`EO[]`).\n */\n outgoingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {\n const target = this._getVertex(vertexOrKey);\n if (target) {\n return this._outEdgeMap.get(target) || [];\n }\n return [];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"degreeOf\" returns the total degree of a vertex, which is the sum of its out-degree and in-degree.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The sum of the out-degree and in-degree of the specified vertex or vertex ID.\n */\n degreeOf(vertexOrKey: VertexKey | VO): number {\n return this.outDegreeOf(vertexOrKey) + this.inDegreeOf(vertexOrKey);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"inDegreeOf\" returns the number of incoming edgeMap for a given vertex.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The number of incoming edgeMap of the specified vertex or vertex ID.\n */\n inDegreeOf(vertexOrKey: VertexKey | VO): number {\n return this.incomingEdgesOf(vertexOrKey).length;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `outDegreeOf` returns the number of outgoing edgeMap from a given vertex.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The number of outgoing edgeMap from the specified vertex or vertex ID.\n */\n outDegreeOf(vertexOrKey: VertexKey | VO): number {\n return this.outgoingEdgesOf(vertexOrKey).length;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"edgesOf\" returns an array of both outgoing and incoming edgeMap of a given vertex or vertex ID.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The function `edgesOf` returns an array of edgeMap.\n */\n edgesOf(vertexOrKey: VertexKey | VO): EO[] {\n return [...this.outgoingEdgesOf(vertexOrKey), ...this.incomingEdgesOf(vertexOrKey)];\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEdgeSrc\" returns the source vertex of an edge, or undefined if the edge does not exist.\n * @param {EO} e - The parameter \"e\" is of type EO, which represents an edge in a graph.\n * @returns either a vertex object (VO) or undefined.\n */\n getEdgeSrc(e: EO): VO | undefined {\n return this._getVertex(e.src);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEdgeDest\" returns the destination vertex of an edge.\n * @param {EO} e - The parameter \"e\" is of type \"EO\", which represents an edge in a graph.\n * @returns either a vertex object of type VO or undefined.\n */\n getEdgeDest(e: EO): VO | undefined {\n return this._getVertex(e.dest);\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function `getDestinations` returns an array of destination vertexMap connected to a given vertex.\n * @param {VO | VertexKey | undefined} vertex - The `vertex` parameter represents the starting vertex from which we want to\n * find the destinations. It can be either a `VO` object, a `VertexKey` value, or `undefined`.\n * @returns an array of vertexMap (VO[]).\n */\n getDestinations(vertex: VO | VertexKey | undefined): VO[] {\n if (vertex === undefined) {\n return [];\n }\n const destinations: VO[] = [];\n const outgoingEdges = this.outgoingEdgesOf(vertex);\n for (const outEdge of outgoingEdges) {\n const child = this.getEdgeDest(outEdge);\n if (child) {\n destinations.push(child);\n }\n }\n return destinations;\n }\n\n /**\n * Time Complexity: O(|V| + |E|) where |V| is the number of vertexMap and |E| is the number of edgeMap\n * Space Complexity: O(|V|)\n *\n * The `topologicalSort` function performs a topological sort on a graph and returns an array of vertexMap or vertex IDs\n * in the sorted order, or undefined if the graph contains a cycle.\n * @param {'vertex' | 'key'} [propertyName] - The `propertyName` parameter is an optional parameter that specifies the\n * property to use for sorting the vertexMap. It can have two possible values: 'vertex' or 'key'. If 'vertex' is\n * specified, the vertexMap themselves will be used for sorting. If 'key' is specified, the ids of\n * @returns an array of vertexMap or vertex IDs in topological order. If there is a cycle in the graph, it returns undefined.\n */\n topologicalSort(propertyName?: 'vertex' | 'key'): Array<VO | VertexKey> | undefined {\n propertyName = propertyName ?? 'key';\n // When judging whether there is a cycle in the undirected graph, all nodes with degree of **<= 1** are enqueued\n // When judging whether there is a cycle in the directed graph, all nodes with **in degree = 0** are enqueued\n const statusMap: Map<VO | VertexKey, TopologicalStatus> = new Map<VO | VertexKey, TopologicalStatus>();\n for (const entry of this.vertexMap) {\n statusMap.set(entry[1], 0);\n }\n\n let sorted: (VO | VertexKey)[] = [];\n let hasCycle = false;\n const dfs = (cur: VO | VertexKey) => {\n statusMap.set(cur, 1);\n const children = this.getDestinations(cur);\n for (const child of children) {\n const childStatus = statusMap.get(child);\n if (childStatus === 0) {\n dfs(child);\n } else if (childStatus === 1) {\n hasCycle = true;\n }\n }\n statusMap.set(cur, 2);\n sorted.push(cur);\n };\n\n for (const entry of this.vertexMap) {\n if (statusMap.get(entry[1]) === 0) {\n dfs(entry[1]);\n }\n }\n\n if (hasCycle) return undefined;\n\n if (propertyName === 'key') sorted = sorted.map(vertex => (vertex instanceof DirectedVertex ? vertex.key : vertex));\n return sorted.reverse();\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(|E|)\n *\n * The `edgeSet` function returns an array of all the edgeMap in the graph.\n * @returns The `edgeSet()` method returns an array of edgeMap (`EO[]`).\n */\n edgeSet(): EO[] {\n let edgeMap: EO[] = [];\n this._outEdgeMap.forEach(outEdges => {\n edgeMap = [...edgeMap, ...outEdges];\n });\n return edgeMap;\n }\n\n /**\n * Time Complexity: O(|E|) where |E| is the number of edgeMap\n * Space Complexity: O(1)\n *\n * The function `getNeighbors` returns an array of neighboring vertexMap of a given vertex or vertex ID in a graph.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns an array of vertexMap (VO[]).\n */\n getNeighbors(vertexOrKey: VO | VertexKey): VO[] {\n const neighbors: VO[] = [];\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n const outEdges = this.outgoingEdgesOf(vertex);\n for (const outEdge of outEdges) {\n const neighbor = this._getVertex(outEdge.dest);\n // TODO after no-non-undefined-assertion not ensure the logic\n if (neighbor) {\n neighbors.push(neighbor);\n }\n }\n }\n return neighbors;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEndsOfEdge\" returns the source and destination vertexMap of an edge if it exists in the graph,\n * otherwise it returns undefined.\n * @param {EO} edge - The parameter `edge` is of type `EO`, which represents an edge in a graph.\n * @returns The function `getEndsOfEdge` returns an array containing two vertexMap `[VO, VO]` if the edge exists in the\n * graph. If the edge does not exist, it returns `undefined`.\n */\n getEndsOfEdge(edge: EO): [VO, VO] | undefined {\n if (!this.hasEdge(edge.src, edge.dest)) {\n return undefined;\n }\n const v1 = this._getVertex(edge.src);\n const v2 = this._getVertex(edge.dest);\n if (v1 && v2) {\n return [v1, v2];\n } else {\n return undefined;\n }\n }\n\n /**\n * The isEmpty function checks if the graph is empty.\n *\n * @return A boolean value\n */\n isEmpty(): boolean {\n return this.vertexMap.size === 0 && this.inEdgeMap.size === 0 && this.outEdgeMap.size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the vertex map, in-edge map, and out-edge map.\n */\n clear() {\n this._vertexMap = new Map<VertexKey, VO>();\n this._inEdgeMap = new Map<VO, EO[]>();\n this._outEdgeMap = new Map<VO, EO[]>();\n }\n\n /**\n * The clone function creates a new DirectedGraph object with the same vertices and edges as the original.\n *\n * @return A new instance of the directedgraph class\n */\n clone(): DirectedGraph<V, E, VO, EO> {\n const cloned = new DirectedGraph<V, E, VO, EO>();\n cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);\n cloned.inEdgeMap = new Map<VO, EO[]>(this.inEdgeMap);\n cloned.outEdgeMap = new Map<VO, EO[]>(this.outEdgeMap);\n return cloned;\n }\n\n /**\n * Time Complexity: O(V + E)\n * Space Complexity: O(V)\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.\n *\n * The function `tarjan` implements the Tarjan's algorithm to find strongly connected components in a\n * graph.\n * @returns The function `tarjan()` returns an object with three properties: `dfnMap`, `lowMap`, and\n * `SCCs`.\n */\n tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; SCCs: Map<number, VO[]> } {\n const dfnMap = new Map<VO, number>();\n const lowMap = new Map<VO, number>();\n const SCCs = new Map<number, VO[]>();\n\n let time = 0;\n\n const stack: VO[] = [];\n const inStack: Set<VO> = new Set();\n\n const dfs = (vertex: VO) => {\n dfnMap.set(vertex, time);\n lowMap.set(vertex, time);\n time++;\n\n stack.push(vertex);\n inStack.add(vertex);\n\n const neighbors = this.getNeighbors(vertex);\n for (const neighbor of neighbors) {\n if (!dfnMap.has(neighbor)) {\n dfs(neighbor);\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, lowMap.get(neighbor)!));\n } else if (inStack.has(neighbor)) {\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));\n }\n }\n\n if (dfnMap.get(vertex) === lowMap.get(vertex)) {\n const SCC: VO[] = [];\n let poppedVertex: VO | undefined;\n\n do {\n poppedVertex = stack.pop();\n inStack.delete(poppedVertex!);\n SCC.push(poppedVertex!);\n } while (poppedVertex !== vertex);\n\n SCCs.set(SCCs.size, SCC);\n }\n };\n\n for (const vertex of this.vertexMap.values()) {\n if (!dfnMap.has(vertex)) {\n dfs(vertex);\n }\n }\n\n return { dfnMap, lowMap, SCCs };\n }\n\n /**\n * Time Complexity: O(V + E) - Depends on the implementation (Tarjan's algorithm).\n * Space Complexity: O(V) - Depends on the implementation (Tarjan's algorithm).\n *\n * The function returns a map that associates each vertex object with its corresponding depth-first\n * number.\n * @returns A Map object with keys of type VO and values of type number.\n */\n getDFNMap(): Map<VO, number> {\n return this.tarjan().dfnMap;\n }\n\n /**\n * The function returns a Map object that contains the low values of each vertex in a Tarjan\n * algorithm.\n * @returns The method `getLowMap()` is returning a `Map` object with keys of type `VO` and values of\n * type `number`.\n */\n getLowMap(): Map<VO, number> {\n return this.tarjan().lowMap;\n }\n\n /**\n * The function \"getSCCs\" returns a map of strongly connected components (SCCs) using the Tarjan\n * algorithm.\n * @returns a map where the keys are numbers and the values are arrays of VO objects.\n */\n getSCCs(): Map<number, VO[]> {\n return this.tarjan().SCCs;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_addEdge` adds an edge to a graph if the source and destination vertexMap exist.\n * @param {EO} edge - The parameter `edge` is of type `EO`, which represents an edge in a graph. It is the edge that\n * needs to be added to the graph.\n * @returns a boolean value. It returns true if the edge was successfully added to the graph, and false if either the\n * source or destination vertex does not exist in the graph.\n */\n protected _addEdge(edge: EO): boolean {\n if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {\n return false;\n }\n\n const srcVertex = this._getVertex(edge.src);\n const destVertex = this._getVertex(edge.dest);\n\n // TODO after no-non-undefined-assertion not ensure the logic\n if (srcVertex && destVertex) {\n const srcOutEdges = this._outEdgeMap.get(srcVertex);\n if (srcOutEdges) {\n srcOutEdges.push(edge);\n } else {\n this._outEdgeMap.set(srcVertex, [edge]);\n }\n\n const destInEdges = this._inEdgeMap.get(destVertex);\n if (destInEdges) {\n destInEdges.push(edge);\n } else {\n this._inEdgeMap.set(destVertex, [edge]);\n }\n return true;\n } else {\n return false;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { VertexKey } from '../../types';\nimport { IGraph } from '../../interfaces';\nimport { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';\nimport { arrayRemove } from '../../utils';\n\nexport class UndirectedVertex<V = any> extends AbstractVertex<V> {\n /**\n * The constructor function initializes a vertex with an optional value.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex. It is\n * used to uniquely identify the vertex within a graph or network.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It is used to initialize the value of the\n * vertex. If no value is provided, the vertex will be initialized with a default value.\n */\n constructor(key: VertexKey, value?: V) {\n super(key, value);\n }\n}\n\nexport class UndirectedEdge<E = number> extends AbstractEdge<E> {\n endpoints: [VertexKey, VertexKey];\n\n /**\n * The constructor function creates an instance of a class with two vertex IDs, an optional weight, and an optional\n * value.\n * @param {VertexKey} v1 - The first vertex ID of the edge.\n * @param {VertexKey} v2 - The parameter `v2` is a `VertexKey`, which represents the identifier of the second vertex in a\n * graph edge.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.\n * @param {E} [value] - The \"value\" parameter is an optional parameter of type E. It is used to store a value associated\n * with the edge.\n */\n constructor(v1: VertexKey, v2: VertexKey, weight?: number, value?: E) {\n super(weight, value);\n this.endpoints = [v1, v2];\n }\n}\n\nexport class UndirectedGraph<\n V = any,\n E = any,\n VO extends UndirectedVertex<V> = UndirectedVertex<V>,\n EO extends UndirectedEdge<E> = UndirectedEdge<E>\n >\n extends AbstractGraph<V, E, VO, EO>\n implements IGraph<V, E, VO, EO>\n{\n /**\n * The constructor initializes a new Map object to store edgeMap.\n */\n constructor() {\n super();\n this._edgeMap = new Map<VO, EO[]>();\n }\n\n protected _edgeMap: Map<VO, EO[]>;\n\n get edgeMap(): Map<VO, EO[]> {\n return this._edgeMap;\n }\n\n set edgeMap(v: Map<VO, EO[]>) {\n this._edgeMap = v;\n }\n\n /**\n * The function creates a new vertex with an optional value and returns it.\n * @param {VertexKey} key - The `key` parameter is the unique identifier for the vertex. It is used to distinguish one\n * vertex from another in the graph.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the vertex. If a value is provided,\n * it will be used as the value of the vertex. If no value is provided, the `key` parameter will be used as the value of\n * the vertex.\n * @returns The method is returning a new instance of the `UndirectedVertex` class, casted as type `VO`.\n */\n override createVertex(key: VertexKey, value?: VO['value']): VO {\n return new UndirectedVertex(key, value ?? key) as VO;\n }\n\n /**\n * The function creates an undirected edge between two vertexMap with an optional weight and value.\n * @param {VertexKey} v1 - The parameter `v1` represents the first vertex of the edge.\n * @param {VertexKey} v2 - The parameter `v2` represents the second vertex of the edge.\n * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the edge. If\n * no weight is provided, it defaults to 1.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the edge. It can be of any type and\n * is used to store additional information or data associated with the edge.\n * @returns a new instance of the `UndirectedEdge` class, which is casted as type `EO`.\n */\n override createEdge(v1: VertexKey, v2: VertexKey, weight?: number, value?: EO['value']): EO {\n return new UndirectedEdge(v1, v2, weight ?? 1, value) as EO;\n }\n\n /**\n * Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.\n * Space Complexity: O(1)\n *\n * The function `getEdge` returns the first edge that connects two endpoints, or undefined if no such edge exists.\n * @param {VO | VertexKey | undefined} v1 - The parameter `v1` represents a vertex or vertex ID. It can be of type `VO` (vertex\n * object), `undefined`, or `VertexKey` (a string or number representing the ID of a vertex).\n * @param {VO | VertexKey | undefined} v2 - The parameter `v2` represents a vertex or vertex ID. It can be of type `VO` (vertex\n * object), `undefined`, or `VertexKey` (vertex ID).\n * @returns an edge (EO) or undefined.\n */\n getEdge(v1: VO | VertexKey | undefined, v2: VO | VertexKey | undefined): EO | undefined {\n let edgeMap: EO[] | undefined = [];\n\n if (v1 !== undefined && v2 !== undefined) {\n const vertex1: VO | undefined = this._getVertex(v1);\n const vertex2: VO | undefined = this._getVertex(v2);\n\n if (vertex1 && vertex2) {\n edgeMap = this._edgeMap.get(vertex1)?.filter(e => e.endpoints.includes(vertex2.key));\n }\n }\n\n return edgeMap ? edgeMap[0] || undefined : undefined;\n }\n\n /**\n * Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.\n * Space Complexity: O(1)\n *\n * The function removes an edge between two vertexMap in a graph and returns the removed edge.\n * @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).\n * @param {VO | VertexKey} v2 - VO | VertexKey - This parameter can be either a vertex object (VO) or a vertex ID\n * (VertexKey). It represents the second vertex of the edge that needs to be removed.\n * @returns the removed edge (EO) if it exists, or undefined if either of the endpoints (VO) does not exist.\n */\n deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | undefined {\n const vertex1: VO | undefined = this._getVertex(v1);\n const vertex2: VO | undefined = this._getVertex(v2);\n\n if (!vertex1 || !vertex2) {\n return undefined;\n }\n\n const v1Edges = this._edgeMap.get(vertex1);\n let removed: EO | undefined = undefined;\n if (v1Edges) {\n removed = arrayRemove<EO>(v1Edges, (e: EO) => e.endpoints.includes(vertex2.key))[0] || undefined;\n }\n const v2Edges = this._edgeMap.get(vertex2);\n if (v2Edges) {\n arrayRemove<EO>(v2Edges, (e: EO) => e.endpoints.includes(vertex1.key));\n }\n return removed;\n }\n\n /**\n * Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.\n * Space Complexity: O(1)\n *\n * The function `deleteEdge` deletes an edge between two endpoints in a graph.\n * @param {EO | VertexKey} edgeOrOneSideVertexKey - The parameter `edgeOrOneSideVertexKey` can be\n * either an edge object or a vertex key.\n * @param {VertexKey} [otherSideVertexKey] - The parameter `otherSideVertexKey` is an optional\n * parameter that represents the key of the vertex on the other side of the edge. It is used when the\n * `edgeOrOneSideVertexKey` parameter is a vertex key, and it specifies the key of the vertex on the\n * other side of the\n * @returns The `deleteEdge` function returns either the deleted edge object (EO) or `undefined`.\n */\n deleteEdge(edgeOrOneSideVertexKey: EO | VertexKey, otherSideVertexKey?: VertexKey): EO | undefined {\n let oneSide: VO | undefined, otherSide: VO | undefined;\n if (this.isVertexKey(edgeOrOneSideVertexKey)) {\n if (this.isVertexKey(otherSideVertexKey)) {\n oneSide = this._getVertex(edgeOrOneSideVertexKey);\n otherSide = this._getVertex(otherSideVertexKey);\n } else {\n return;\n }\n } else {\n oneSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[0]);\n otherSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[1]);\n }\n\n if (oneSide && otherSide) {\n return this.deleteEdgeBetween(oneSide, otherSide);\n } else {\n return;\n }\n }\n\n /**\n * Time Complexity: O(1) - Constant time for Map operations.\n * Space Complexity: O(1) - Constant space, as it creates only a few variables.\n *\n * The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns The method is returning a boolean value.\n */\n deleteVertex(vertexOrKey: VO | VertexKey): boolean {\n let vertexKey: VertexKey;\n let vertex: VO | undefined;\n if (this.isVertexKey(vertexOrKey)) {\n vertex = this.getVertex(vertexOrKey);\n vertexKey = vertexOrKey;\n } else {\n vertex = vertexOrKey;\n vertexKey = this._getVertexKey(vertexOrKey);\n }\n\n const neighbors = this.getNeighbors(vertexOrKey);\n\n if (vertex) {\n neighbors.forEach(neighbor => {\n const neighborEdges = this._edgeMap.get(neighbor);\n if (neighborEdges) {\n const restEdges = neighborEdges.filter(edge => {\n return !edge.endpoints.includes(vertexKey);\n });\n this._edgeMap.set(neighbor, restEdges);\n }\n });\n this._edgeMap.delete(vertex);\n }\n\n return this._vertexMap.delete(vertexKey);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `degreeOf` returns the degree of a vertex in a graph, which is the number of edgeMap connected to that\n * vertex.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.\n * @returns The function `degreeOf` returns the degree of a vertex in a graph. The degree of a vertex is the number of\n * edgeMap connected to that vertex.\n */\n degreeOf(vertexOrKey: VertexKey | VO): number {\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n return this._edgeMap.get(vertex)?.length || 0;\n } else {\n return 0;\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function returns the edgeMap of a given vertex or vertex ID.\n * @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`. A `VertexKey` is a\n * unique identifier for a vertex in a graph, while `VO` represents the type of the vertex.\n * @returns an array of edgeMap.\n */\n edgesOf(vertexOrKey: VertexKey | VO): EO[] {\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n return this._edgeMap.get(vertex) || [];\n } else {\n return [];\n }\n }\n\n /**\n * Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.\n * Space Complexity: O(|E|)\n *\n * The function \"edgeSet\" returns an array of unique edgeMap from a set of edgeMap.\n * @returns The method `edgeSet()` returns an array of type `EO[]`.\n */\n edgeSet(): EO[] {\n const edgeSet: Set<EO> = new Set();\n this._edgeMap.forEach(edgeMap => {\n edgeMap.forEach(edge => {\n edgeSet.add(edge);\n });\n });\n return [...edgeSet];\n }\n\n /**\n * Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.\n * Space Complexity: O(|E|)\n *\n * The function \"getNeighbors\" returns an array of neighboring endpoints for a given vertex or vertex ID.\n * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID\n * (`VertexKey`).\n * @returns an array of vertexMap (VO[]).\n */\n getNeighbors(vertexOrKey: VO | VertexKey): VO[] {\n const neighbors: VO[] = [];\n const vertex = this._getVertex(vertexOrKey);\n if (vertex) {\n const neighborEdges = this.edgesOf(vertex);\n for (const edge of neighborEdges) {\n const neighbor = this._getVertex(edge.endpoints.filter(e => e !== vertex.key)[0]);\n if (neighbor) {\n neighbors.push(neighbor);\n }\n }\n }\n return neighbors;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEndsOfEdge\" returns the endpoints at the ends of an edge if the edge exists in the graph, otherwise\n * it returns undefined.\n * @param {EO} edge - The parameter \"edge\" is of type EO, which represents an edge in a graph.\n * @returns The function `getEndsOfEdge` returns an array containing two endpoints `[VO, VO]` if the edge exists in the\n * graph. If the edge does not exist, it returns `undefined`.\n */\n getEndsOfEdge(edge: EO): [VO, VO] | undefined {\n if (!this.hasEdge(edge.endpoints[0], edge.endpoints[1])) {\n return undefined;\n }\n const v1 = this._getVertex(edge.endpoints[0]);\n const v2 = this._getVertex(edge.endpoints[1]);\n if (v1 && v2) {\n return [v1, v2];\n } else {\n return undefined;\n }\n }\n\n /**\n * The isEmpty function checks if the graph is empty.\n * @return True if the graph is empty and false otherwise\n */\n isEmpty(): boolean {\n return this.vertexMap.size === 0 && this.edgeMap.size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the vertex and edge maps to empty maps.\n */\n clear() {\n this._vertexMap = new Map<VertexKey, VO>();\n this._edgeMap = new Map<VO, EO[]>();\n }\n\n /**\n * The clone function creates a new UndirectedGraph object and copies the\n * vertexMap and edgeMap from this graph to the new one. This is done by\n * assigning each of these properties to their respective counterparts in the\n * cloned graph. The clone function returns a reference to this newly created,\n * cloned UndirectedGraph object.\n *\n * @return A new instance of the undirectedgraph class\n */\n clone(): UndirectedGraph<V, E, VO, EO> {\n const cloned = new UndirectedGraph<V, E, VO, EO>();\n cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);\n cloned.edgeMap = new Map<VO, EO[]>(this.edgeMap);\n return cloned;\n }\n\n /**\n * Time Complexity: O(V + E)\n * Space Complexity: O(V)\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * 1. Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time\n *\n * The function `tarjan` implements the Tarjan's algorithm to find bridges and cut vertices in a\n * graph.\n * @returns The function `tarjan()` returns an object with the following properties:\n */\n tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; bridges: EO[]; cutVertices: VO[] } {\n const dfnMap = new Map<VO, number>();\n const lowMap = new Map<VO, number>();\n const bridges: EO[] = [];\n const cutVertices: VO[] = [];\n\n let time = 0;\n\n const dfs = (vertex: VO, parent: VO | undefined) => {\n dfnMap.set(vertex, time);\n lowMap.set(vertex, time);\n time++;\n\n const neighbors = this.getNeighbors(vertex);\n let childCount = 0;\n\n for (const neighbor of neighbors) {\n if (!dfnMap.has(neighbor)) {\n childCount++;\n dfs(neighbor, vertex);\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, lowMap.get(neighbor)!));\n\n if (lowMap.get(neighbor)! > dfnMap.get(vertex)!) {\n // Found a bridge\n const edge = this.getEdge(vertex, neighbor);\n if (edge) {\n bridges.push(edge);\n }\n }\n\n if (parent !== undefined && lowMap.get(neighbor)! >= dfnMap.get(vertex)!) {\n // Found an articulation point\n cutVertices.push(vertex);\n }\n } else if (neighbor !== parent) {\n lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));\n }\n }\n\n if (parent === undefined && childCount > 1) {\n // Special case for root in DFS tree\n cutVertices.push(vertex);\n }\n };\n\n for (const vertex of this.vertexMap.values()) {\n if (!dfnMap.has(vertex)) {\n dfs(vertex, undefined);\n }\n }\n\n return {\n dfnMap,\n lowMap,\n bridges,\n cutVertices\n };\n }\n\n /**\n * The function \"getBridges\" returns an array of bridges in a graph using the Tarjan's algorithm.\n * @returns The function `getBridges()` is returning the bridges found using the Tarjan's algorithm.\n */\n getBridges() {\n return this.tarjan().bridges;\n }\n\n /**\n * The function \"getCutVertices\" returns an array of cut vertices using the Tarjan's algorithm.\n * @returns the cut vertices found using the Tarjan's algorithm.\n */\n getCutVertices() {\n return this.tarjan().cutVertices;\n }\n\n /**\n * The function returns the dfnMap property of the result of the tarjan() function.\n * @returns the `dfnMap` property of the result of calling the `tarjan()` function.\n */\n getDFNMap() {\n return this.tarjan().dfnMap;\n }\n\n /**\n * The function returns the lowMap property of the result of the tarjan() function.\n * @returns the lowMap property of the result of calling the tarjan() function.\n */\n getLowMap() {\n return this.tarjan().lowMap;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function adds an edge to the graph by updating the adjacency list with the vertexMap of the edge.\n * @param {EO} edge - The parameter \"edge\" is of type EO, which represents an edge in a graph.\n * @returns a boolean value.\n */\n protected _addEdge(edge: EO): boolean {\n for (const end of edge.endpoints) {\n const endVertex = this._getVertex(end);\n if (endVertex === undefined) return false;\n if (endVertex) {\n const edgeMap = this._edgeMap.get(endVertex);\n if (edgeMap) {\n edgeMap.push(edge);\n } else {\n this._edgeMap.set(endVertex, [edge]);\n }\n }\n }\n return true;\n }\n}\n","import type { MapGraphCoordinate, VertexKey } from '../../types';\nimport { DirectedEdge, DirectedGraph, DirectedVertex } from './directed-graph';\n\nexport class MapVertex<V = any> extends DirectedVertex<V> {\n lat: number;\n long: number;\n\n /**\n * The constructor function initializes an object with an key, latitude, longitude, and an optional value.\n * @param {VertexKey} key - The `key` parameter is of type `VertexKey` and represents the identifier of the vertex.\n * @param {number} lat - The \"lat\" parameter represents the latitude of a vertex. Latitude is a geographic coordinate\n * that specifies the north-south position of a point on the Earth's surface. It is measured in degrees, with positive\n * values representing points north of the equator and negative values representing points south of the equator.\n * @param {number} long - The \"long\" parameter represents the longitude of a location. Longitude is a geographic\n * coordinate that specifies the east-west position of a point on the Earth's surface. It is measured in degrees, with\n * values ranging from -180 to 180.\n * @param {V} [value] - The \"value\" parameter is an optional value of type V. It is not required to be provided when\n * creating an instance of the class.\n */\n constructor(key: VertexKey, value: V, lat: number, long: number) {\n super(key, value);\n this.lat = lat;\n this.long = long;\n }\n}\n\nexport class MapEdge<E = any> extends DirectedEdge<E> {\n /**\n * The constructor function initializes a new instance of a class with the given source, destination, weight, and\n * value.\n * @param {VertexKey} src - The `src` parameter is the source vertex ID. It represents the starting point of an edge in\n * a graph.\n * @param {VertexKey} dest - The `dest` parameter is the identifier of the destination vertex for an edge.\n * @param {number} [weight] - The weight parameter is an optional number that represents the weight of the edge.\n * @param {E} [value] - The \"value\" parameter is an optional parameter of type E. It is used to store additional\n * information or data associated with the edge.\n */\n constructor(src: VertexKey, dest: VertexKey, weight?: number, value?: E) {\n super(src, dest, weight, value);\n }\n}\n\nexport class MapGraph<\n V = any,\n E = any,\n VO extends MapVertex<V> = MapVertex<V>,\n EO extends MapEdge<E> = MapEdge<E>\n> extends DirectedGraph<V, E, VO, EO> {\n /**\n * The constructor function initializes the originCoord and bottomRight properties of a MapGraphCoordinate object.\n * @param {MapGraphCoordinate} originCoord - The `originCoord` parameter is a `MapGraphCoordinate` object that represents the\n * starting point or reference point of the map graph. It defines the coordinates of the top-left corner of the map\n * graph.\n * @param {MapGraphCoordinate} [bottomRight] - The `bottomRight` parameter is an optional parameter of type\n * `MapGraphCoordinate`. It represents the bottom right coordinate of a map graph. If this parameter is not provided,\n * it will default to `undefined`.\n */\n constructor(originCoord: MapGraphCoordinate, bottomRight?: MapGraphCoordinate) {\n super();\n this._originCoord = originCoord;\n this._bottomRight = bottomRight;\n }\n\n protected _originCoord: MapGraphCoordinate = [0, 0];\n\n get originCoord(): MapGraphCoordinate {\n return this._originCoord;\n }\n\n protected _bottomRight: MapGraphCoordinate | undefined;\n\n get bottomRight(): MapGraphCoordinate | undefined {\n return this._bottomRight;\n }\n\n /**\n * The function creates a new vertex with the given key, value, latitude, and longitude.\n * @param {VertexKey} key - The key parameter is the unique identifier for the vertex. It is of type VertexKey, which could\n * be a string or a number depending on how you define it in your code.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the `value` property of the vertex. It\n * is of type `V`, which means it should be of the same type as the `value` property of the vertex class `VO`.\n * @param {number} lat - The `lat` parameter represents the latitude of the vertex. It is a number that specifies the\n * position of the vertex on the Earth's surface in the north-south direction.\n * @param {number} long - The `long` parameter represents the longitude coordinate of the vertex.\n * @returns The method is returning a new instance of the `MapVertex` class, casted as type `VO`.\n */\n override createVertex(\n key: VertexKey,\n value?: V,\n lat: number = this.originCoord[0],\n long: number = this.originCoord[1]\n ): VO {\n return new MapVertex(key, value, lat, long) as VO;\n }\n\n /**\n * The function creates a new instance of a MapEdge with the given source, destination, weight, and value.\n * @param {VertexKey} src - The source vertex ID of the edge. It represents the starting point of the edge.\n * @param {VertexKey} dest - The `dest` parameter is the identifier of the destination vertex for the edge being\n * created.\n * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the edge. It\n * is used to assign a numerical value to the edge, which can be used in algorithms such as shortest path algorithms.\n * If the weight is not provided, it can be set to a default value or left undefined.\n * @param [value] - The `value` parameter is an optional value that can be assigned to the edge. It can be of any type,\n * depending on the specific implementation of the `MapEdge` class.\n * @returns a new instance of the `MapEdge` class, cast as type `EO`.\n */\n override createEdge(src: VertexKey, dest: VertexKey, weight?: number, value?: E): EO {\n return new MapEdge(src, dest, weight, value) as EO;\n }\n\n /**\n * The override function is used to override the default behavior of a function.\n * In this case, we are overriding the clone() function from Graph&lt;V, E&gt;.\n * The clone() function returns a new graph that is an exact copy of the original graph.\n *\n * @return A mapgraph&lt;v, e, vo, eo&gt;\n */\n override clone(): MapGraph<V, E, VO, EO> {\n const cloned = new MapGraph<V, E, VO, EO>(this.originCoord, this.bottomRight);\n cloned.vertexMap = new Map<VertexKey, VO>(this.vertexMap);\n cloned.inEdgeMap = new Map<VO, EO[]>(this.inEdgeMap);\n cloned.outEdgeMap = new Map<VO, EO[]>(this.outEdgeMap);\n return cloned;\n }\n}\n","export enum DFSOperation {\n VISIT = 0,\n PROCESS = 1\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type {\n BinaryTreeDeleteResult,\n BinaryTreeNested,\n BinaryTreeNodeNested,\n BinaryTreeOptions,\n BinaryTreePrintOptions,\n BTNCallback,\n BTNEntry,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n DFSOrderPattern,\n DFSStackItem,\n EntryCallback,\n FamilyPosition,\n IterationType,\n NodeDisplayLayout,\n OptBTNOrNull\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { isComparable, trampoline } from '../../utils';\nimport { Queue } from '../queue';\nimport { IterableEntryBase } from '../base';\nimport { DFSOperation } from '../../constants';\n\n/**\n * Represents a node in a binary tree.\n * @template V - The type of data stored in the node.\n * @template NODE - The type of the family relationship in the binary tree.\n */\nexport class BinaryTreeNode<\n K = any,\n V = any,\n NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>\n> {\n key: K;\n\n value?: V;\n\n parent?: NODE;\n\n constructor(key: K, value?: V) {\n this.key = key;\n this.value = value;\n }\n\n protected _left?: OptBTNOrNull<NODE>;\n\n get left(): OptBTNOrNull<NODE> {\n return this._left;\n }\n\n set left(v: OptBTNOrNull<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._left = v;\n }\n\n protected _right?: OptBTNOrNull<NODE>;\n\n get right(): OptBTNOrNull<NODE> {\n return this._right;\n }\n\n set right(v: OptBTNOrNull<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._right = v;\n }\n\n get familyPosition(): FamilyPosition {\n const that = this as unknown as NODE;\n if (!this.parent) {\n return this.left || this.right ? 'ROOT' : 'ISOLATED';\n }\n\n if (this.parent.left === that) {\n return this.left || this.right ? 'ROOT_LEFT' : 'LEFT';\n } else if (this.parent.right === that) {\n return this.left || this.right ? 'ROOT_RIGHT' : 'RIGHT';\n }\n\n return 'MAL_NODE';\n }\n}\n\n/**\n * 1. Two Children Maximum: Each node has at most two children.\n * 2. Left and Right Children: Nodes have distinct left and right children.\n * 3. Depth and Height: Depth is the number of edges from the root to a node; height is the maximum depth in the tree.\n * 4. Subtrees: Each child of a node forms the root of a subtree.\n * 5. Leaf Nodes: Nodes without children are leaves.\n */\nexport class BinaryTree<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends BinaryTreeNode<K, V, NODE> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>,\n TREE extends BinaryTree<K, V, R, NODE, TREE> = BinaryTree<K, V, R, NODE, BinaryTreeNested<K, V, R, NODE>>\n >\n extends IterableEntryBase<K, V | undefined>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n iterationType: IterationType = 'ITERATIVE';\n\n /**\n * The constructor initializes a binary tree with optional options and adds keys, nodes, entries, or\n * raw data if provided.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter in the constructor\n * is an iterable that can contain elements of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. It is\n * initialized with an empty array `[]` by default.\n * @param [options] - The `options` parameter in the constructor is an object that can contain the\n * following properties:\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE> | R> = [],\n options?: BinaryTreeOptions<K, V, R>\n ) {\n super();\n if (options) {\n const { iterationType, toEntryFn } = options;\n if (iterationType) this.iterationType = iterationType;\n if (typeof toEntryFn === 'function') this._toEntryFn = toEntryFn;\n else if (toEntryFn) throw TypeError('toEntryFn must be a function type');\n }\n\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected _root?: OptBTNOrNull<NODE>;\n\n get root(): OptBTNOrNull<NODE> {\n return this._root;\n }\n\n protected _size: number = 0;\n\n get size(): number {\n return this._size;\n }\n\n protected _NIL: NODE = new BinaryTreeNode<K, V>(NaN as K) as unknown as NODE;\n\n get NIL(): NODE {\n return this._NIL;\n }\n\n protected _toEntryFn?: (rawElement: R) => BTNEntry<K, V>;\n\n get toEntryFn() {\n return this._toEntryFn;\n }\n\n /**\n * The function creates a new binary tree node with a specified key and optional value.\n * @param {K} key - The `key` parameter is the key of the node being created in the binary tree.\n * @param {V} [value] - The `value` parameter in the `createNode` function is optional, meaning it is\n * not required to be provided when calling the function. If a `value` is provided, it should be of\n * type `V`, which is the type of the value associated with the node.\n * @returns A new BinaryTreeNode instance with the provided key and value is being returned, casted\n * as NODE.\n */\n createNode(key: K, value?: V): NODE {\n return new BinaryTreeNode<K, V, NODE>(key, value) as NODE;\n }\n\n /**\n * The function creates a binary tree with the specified options.\n * @param [options] - The `options` parameter in the `createTree` function is an optional parameter\n * that allows you to provide partial configuration options for creating a binary tree. It is of type\n * `Partial<BinaryTreeOptions<K, V, R>>`, which means you can pass in an object containing a subset\n * of properties\n * @returns A new instance of a binary tree with the specified options is being returned.\n */\n createTree(options?: BinaryTreeOptions<K, V, R>): TREE {\n return new BinaryTree<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function `keyValueOrEntryOrRawElementToNode` converts various input types into a node object\n * or returns null.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyValueOrEntryOrRawElementToNode` function takes in a parameter `keyOrNodeOrEntryOrRaw`, which\n * can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. This parameter represents either a key, a\n * node, an entry\n * @param {V} [value] - The `value` parameter in the `keyValueOrEntryOrRawElementToNode` function is\n * an optional parameter of type `V`. It represents the value associated with the key in the node\n * being created. If a `value` is provided, it will be used when creating the node. If\n * @returns The `keyValueOrEntryOrRawElementToNode` function returns an optional node\n * (`OptBTNOrNull<NODE>`) based on the input parameters provided. The function checks the type of the\n * input parameter (`keyOrNodeOrEntryOrRaw`) and processes it accordingly to return a node or null\n * value.\n */\n keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V\n ): OptBTNOrNull<NODE> {\n if (keyOrNodeOrEntryOrRaw === undefined) return;\n if (keyOrNodeOrEntryOrRaw === null) return null;\n\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const [key, entryValue] = keyOrNodeOrEntryOrRaw;\n if (key === undefined) return;\n else if (key === null) return null;\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue);\n }\n\n if (this._toEntryFn) {\n const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue);\n else return;\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value);\n\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `ensureNode` in TypeScript checks if a given input is a node, entry, key, or raw\n * value and returns the corresponding node or null.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `ensureNode` function can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. It\n * is used to determine whether the input is a key, node, entry, or raw data. The\n * @param {IterationType} iterationType - The `iterationType` parameter in the `ensureNode` function\n * is used to specify the type of iteration to be performed. It has a default value of\n * `this.iterationType` if not explicitly provided.\n * @returns The `ensureNode` function returns either a node, `null`, or `undefined` based on the\n * conditions specified in the code snippet.\n */\n ensureNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType: IterationType = this.iterationType\n ): OptBTNOrNull<NODE> {\n if (keyOrNodeOrEntryOrRaw === null) return null;\n if (keyOrNodeOrEntryOrRaw === undefined) return;\n if (keyOrNodeOrEntryOrRaw === this._NIL) return;\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const key = keyOrNodeOrEntryOrRaw[0];\n if (key === null) return null;\n if (key === undefined) return;\n return this.getNodeByKey(key, iterationType);\n }\n\n if (this._toEntryFn) {\n const [key] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.getNodeByKey(key);\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.getNodeByKey(keyOrNodeOrEntryOrRaw, iterationType);\n return;\n }\n\n /**\n * The function isNode checks if the input is an instance of BinaryTreeNode.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be either a key, a node, an entry, or raw data. The function is\n * checking if the input is an instance of a `BinaryTreeNode` and returning a boolean value\n * accordingly.\n * @returns The function `isNode` is checking if the input `keyOrNodeOrEntryOrRaw` is an instance of\n * `BinaryTreeNode`. If it is, the function returns `true`, indicating that the input is a node. If\n * it is not an instance of `BinaryTreeNode`, the function returns `false`, indicating that the input\n * is not a node.\n */\n isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof BinaryTreeNode;\n }\n\n /**\n * The function `isRealNode` checks if a given input is a valid node in a binary tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `isRealNode` function can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`.\n * The function checks if the input parameter is a `NODE` type by verifying if it is not equal\n * @returns The function `isRealNode` is checking if the input `keyOrNodeOrEntryOrRaw` is a valid\n * node by comparing it to `this._NIL`, `null`, and `undefined`. If the input is not one of these\n * values, it then calls the `isNode` method to further determine if the input is a node. The\n * function will return a boolean value indicating whether the\n */\n isRealNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n if (keyOrNodeOrEntryOrRaw === this._NIL || keyOrNodeOrEntryOrRaw === null || keyOrNodeOrEntryOrRaw === undefined)\n return false;\n return this.isNode(keyOrNodeOrEntryOrRaw);\n }\n\n /**\n * The function checks if a given input is a valid node or null.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` in the `isRealNodeOrNull` function can be of type `BTNKeyOrNodeOrEntry<K,\n * V, NODE>` or `R`. It is a union type that can either be a key, a node, an entry, or\n * @returns The function `isRealNodeOrNull` is returning a boolean value. It checks if the input\n * `keyOrNodeOrEntryOrRaw` is either `null` or a real node, and returns `true` if it is a node or\n * `null`, and `false` otherwise.\n */\n isRealNodeOrNull(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE | null {\n return keyOrNodeOrEntryOrRaw === null || this.isRealNode(keyOrNodeOrEntryOrRaw);\n }\n\n /**\n * The function isNIL checks if a given key, node, entry, or raw value is equal to the _NIL value.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - BTNKeyOrNodeOrEntry<K, V,\n * NODE> | R\n * @returns The function is checking if the `keyOrNodeOrEntryOrRaw` parameter is equal to the `_NIL`\n * property of the current object and returning a boolean value based on that comparison.\n */\n isNIL(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): boolean {\n return keyOrNodeOrEntryOrRaw === this._NIL;\n }\n\n /**\n * The function determines whether a given key, node, entry, or raw data is a leaf node in a binary\n * tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. It represents a\n * key, node, entry, or raw data in a binary tree structure. The function `isLeaf` checks whether the\n * provided\n * @returns The function `isLeaf` returns a boolean value indicating whether the input\n * `keyOrNodeOrEntryOrRaw` is a leaf node in a binary tree.\n */\n isLeaf(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): boolean {\n keyOrNodeOrEntryOrRaw = this.ensureNode(keyOrNodeOrEntryOrRaw);\n if (keyOrNodeOrEntryOrRaw === undefined) return false;\n if (keyOrNodeOrEntryOrRaw === null) return true;\n return !this.isRealNode(keyOrNodeOrEntryOrRaw.left) && !this.isRealNode(keyOrNodeOrEntryOrRaw.right);\n }\n\n /**\n * The function `isEntry` checks if the input is a BTNEntry object by verifying if it is an array\n * with a length of 2.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `isEntry` function can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or type `R`.\n * The function checks if the provided `keyOrNodeOrEntryOrRaw` is of type `BTN\n * @returns The `isEntry` function is checking if the `keyOrNodeOrEntryOrRaw` parameter is an array\n * with a length of 2. If it is, then it returns `true`, indicating that the parameter is of type\n * `BTNEntry<K, V>`. If the condition is not met, it returns `false`.\n */\n isEntry(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is BTNEntry<K, V> {\n return Array.isArray(keyOrNodeOrEntryOrRaw) && keyOrNodeOrEntryOrRaw.length === 2;\n }\n\n /**\n * Time Complexity O(1)\n * Space Complexity O(1)\n *\n * The function `isKey` checks if a given key is comparable.\n * @param {any} key - The `key` parameter is of type `any`, which means it can be any data type in\n * TypeScript.\n * @returns The function `isKey` is checking if the `key` parameter is `null` or if it is comparable.\n * If the `key` is `null`, the function returns `true`. Otherwise, it returns the result of the\n * `isComparable` function, which is not provided in the code snippet.\n */\n isKey(key: any): key is K {\n if (key === null) return true;\n return isComparable(key);\n }\n\n /**\n * Time Complexity O(n)\n * Space Complexity O(1)\n *\n * The `add` function in TypeScript adds a new node to a binary tree while handling duplicate keys\n * and finding the correct insertion position.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `add` method you provided\n * seems to be for adding a new node to a binary tree structure. The `keyOrNodeOrEntryOrRaw`\n * parameter in the method can accept different types of values:\n * @param {V} [value] - The `value` parameter in the `add` method represents the value associated\n * with the key that you want to add to the binary tree. When adding a key-value pair to the binary\n * tree, you provide the key and its corresponding value. The `add` method then creates a new node\n * with this\n * @returns The `add` method returns a boolean value. It returns `true` if the insertion of the new\n * node was successful, and `false` if the insertion position could not be found or if a duplicate\n * key was found and the node was replaced instead of inserted.\n */\n add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);\n if (newNode === undefined) return false;\n\n // If the tree is empty, directly set the new node as the root node\n if (!this._root) {\n this._setRoot(newNode);\n this._size = 1;\n return true;\n }\n\n const queue = new Queue<NODE>([this._root]);\n let potentialParent: NODE | undefined; // Record the parent node of the potential insertion location\n\n while (queue.size > 0) {\n const cur = queue.shift();\n\n if (!cur) continue;\n\n // Check for duplicate keys when newNode is not null\n if (newNode !== null && cur.key === newNode.key) {\n this._replaceNode(cur, newNode);\n return true; // If duplicate keys are found, no insertion is performed\n }\n\n // Record the first possible insertion location found\n if (potentialParent === undefined && (cur.left === undefined || cur.right === undefined)) {\n potentialParent = cur;\n }\n\n // Continue traversing the left and right subtrees\n if (cur.left !== null) {\n if (cur.left) queue.push(cur.left);\n }\n if (cur.right !== null) {\n if (cur.right) queue.push(cur.right);\n }\n }\n\n // At the end of the traversal, if the insertion position is found, insert\n if (potentialParent) {\n if (potentialParent.left === undefined) {\n potentialParent.left = newNode;\n } else if (potentialParent.right === undefined) {\n potentialParent.right = newNode;\n }\n this._size++;\n return true;\n }\n\n return false; // If the insertion position cannot be found, return undefined\n }\n\n /**\n * Time Complexity: O(k * n)\n * Space Complexity: O(1)\n *\n * The `addMany` function takes in multiple keys or nodes or entries or raw values along with\n * optional values, and adds them to a data structure while returning an array indicating whether\n * each insertion was successful.\n * @param keysOrNodesOrEntriesOrRaws - `keysOrNodesOrEntriesOrRaws` is an iterable that can contain a\n * mix of keys, nodes, entries, or raw values. Each element in this iterable can be of type\n * `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`.\n * @param [values] - The `values` parameter in the `addMany` function is an optional parameter that\n * accepts an iterable of values. These values correspond to the keys or nodes being added in the\n * `keysOrNodesOrEntriesOrRaws` parameter. If provided, the function will iterate over the values and\n * assign them\n * @returns The `addMany` method returns an array of boolean values indicating whether each key,\n * node, entry, or raw value was successfully added to the data structure. Each boolean value\n * corresponds to the success of adding the corresponding key or value in the input iterable.\n */\n addMany(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE> | R>,\n values?: Iterable<V | undefined>\n ): boolean[] {\n // TODO not sure addMany not be run multi times\n const inserted: boolean[] = [];\n\n let valuesIterator: Iterator<V | undefined> | undefined;\n if (values) {\n valuesIterator = values[Symbol.iterator]();\n }\n\n for (const keyOrNodeOrEntryOrRaw of keysOrNodesOrEntriesOrRaws) {\n let value: V | undefined | null = undefined;\n\n if (valuesIterator) {\n const valueResult = valuesIterator.next();\n if (!valueResult.done) {\n value = valueResult.value;\n }\n }\n\n inserted.push(this.add(keyOrNodeOrEntryOrRaw, value));\n }\n\n return inserted;\n }\n\n /**\n * Time Complexity: O(k * n)\n * Space Complexity: O(1)\n *\n * The `refill` function clears the existing data structure and then adds new key-value pairs based\n * on the provided input.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter in the `refill`\n * method can accept an iterable containing a mix of `BTNKeyOrNodeOrEntry<K, V, NODE>` objects or `R`\n * objects.\n * @param [values] - The `values` parameter in the `refill` method is an optional parameter that\n * accepts an iterable of values of type `V` or `undefined`.\n */\n refill(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE> | R>,\n values?: Iterable<V | undefined>\n ): void {\n this.clear();\n this.addMany(keysOrNodesOrEntriesOrRaws, values);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `delete` in TypeScript implements the deletion of a node in a binary tree and returns\n * the deleted node along with information for tree balancing.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw\n * - The `delete` method you provided is used to delete a node from a binary tree based on the key,\n * node, entry or raw data. The method returns an array of\n * `BinaryTreeDeleteResult` objects containing information about the deleted node and whether\n * balancing is needed.\n * @returns The `delete` method returns an array of `BinaryTreeDeleteResult` objects. Each object in\n * the array contains information about the node that was deleted (`deleted`) and the node that may\n * need to be balanced (`needBalanced`).\n */\n delete(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): BinaryTreeDeleteResult<NODE>[] {\n const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];\n if (!this._root) return deletedResult;\n\n const curr = this.getNode(keyOrNodeOrEntryOrRaw);\n if (!curr) return deletedResult;\n\n const parent: NODE | undefined = curr?.parent;\n let needBalanced: NODE | undefined;\n let orgCurrent: NODE | undefined = curr;\n\n if (!curr.left && !curr.right && !parent) {\n this._setRoot(undefined);\n } else if (curr.left) {\n const leftSubTreeRightMost = this.getRightMost(node => node, curr.left);\n if (leftSubTreeRightMost) {\n const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;\n orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);\n if (parentOfLeftSubTreeMax) {\n if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)\n parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;\n else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;\n needBalanced = parentOfLeftSubTreeMax;\n }\n }\n } else if (parent) {\n const { familyPosition: fp } = curr;\n if (fp === 'LEFT' || fp === 'ROOT_LEFT') {\n parent.left = curr.right;\n } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {\n parent.right = curr.right;\n }\n needBalanced = parent;\n } else {\n this._setRoot(curr.right);\n curr.right = undefined;\n }\n\n this._size = this._size - 1;\n\n deletedResult.push({ deleted: orgCurrent, needBalanced });\n return deletedResult;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(k + log n)\n *\n * The function `getNodes` retrieves nodes from a binary tree based on a key, node, entry, raw data,\n * or predicate, with options for recursive or iterative traversal.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `getNodes` function you provided takes several parameters:\n * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` function is a boolean flag that\n * determines whether to return only the first node that matches the criteria specified by the\n * `keyOrNodeOrEntryOrRawOrPredicate` parameter. If `onlyOne` is set to `true`, the function will\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getNodes` function is used to specify the starting point for traversing the binary tree. It\n * represents the root node of the binary tree or the node from which the traversal should begin. If\n * not provided, the default value is set to `this._root\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` function\n * determines the type of iteration to be performed when traversing the nodes of a binary tree. It\n * can have two possible values:\n * @returns The `getNodes` function returns an array of nodes that satisfy the provided condition\n * based on the input parameters and the iteration type specified.\n */\n getNodes(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n onlyOne = false,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): NODE[] {\n if (keyOrNodeOrEntryOrRawOrPredicate === undefined) return [];\n if (keyOrNodeOrEntryOrRawOrPredicate === null) return [];\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const callback = this._ensurePredicate(keyOrNodeOrEntryOrRawOrPredicate);\n\n const ans: NODE[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return;\n }\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n };\n\n dfs(beginRoot);\n } else {\n const stack = [beginRoot];\n while (stack.length > 0) {\n const cur = stack.pop();\n if (this.isRealNode(cur)) {\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n if (this.isRealNode(cur.left)) stack.push(cur.left);\n if (this.isRealNode(cur.right)) stack.push(cur.right);\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n).\n *\n * The `getNode` function retrieves a node based on the provided key, node, entry, raw data, or\n * predicate.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `getNode` function can accept a key,\n * node, entry, raw data, or a predicate function.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getNode` function is used to specify the starting point for searching for a node in a binary\n * tree. If no specific starting point is provided, the default value is set to `this._root`, which\n * is typically the root node of the binary tree.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is\n * used to specify the type of iteration to be performed when searching for a node. It has a default\n * value of `this.iterationType`, which means it will use the iteration type defined in the current\n * context if no specific value is provided\n * @returns The `getNode` function is returning the first node that matches the specified criteria,\n * or `null` if no matching node is found.\n */\n getNode(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): OptBTNOrNull<NODE> {\n return this.getNodes(keyOrNodeOrEntryOrRawOrPredicate, true, beginRoot, iterationType)[0] ?? null;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getNodeByKey` retrieves a node by its key from a binary tree structure.\n * @param {K} key - The `key` parameter is the value used to search for a specific node in a data\n * structure.\n * @param {IterationType} iterationType - The `iterationType` parameter is a type of iteration that\n * specifies how the tree nodes should be traversed when searching for a node with the given key. It\n * is an optional parameter with a default value of `this.iterationType`.\n * @returns The `getNodeByKey` function is returning an optional binary tree node\n * (`OptBTNOrNull<NODE>`).\n */\n getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptBTNOrNull<NODE> {\n return this.getNode(key, this._root, iterationType);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * This function overrides the `get` method to retrieve the value associated with a specified key,\n * node, entry, raw data, or predicate in a data structure.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `get` method can accept one of the\n * following types:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `get`\n * method is used to specify the starting point for searching for a key or node in the binary tree.\n * If no specific starting point is provided, the default starting point is the root of the binary\n * tree (`this._root`).\n * @param {IterationType} iterationType - The `iterationType` parameter in the `get` method is used\n * to specify the type of iteration to be performed when searching for a key in the binary tree. It\n * is an optional parameter with a default value of `this.iterationType`, which means it will use the\n * iteration type defined in the\n * @returns The `get` method is returning the value associated with the specified key, node, entry,\n * raw data, or predicate in the binary tree map. If the specified key or node is found in the tree,\n * the method returns the corresponding value. If the key or node is not found, it returns\n * `undefined`.\n */\n override get(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): V | undefined {\n return this.getNode(keyOrNodeOrEntryOrRawOrPredicate, beginRoot, iterationType)?.value;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The `has` function in TypeScript checks if a specified key, node, entry, raw data, or predicate\n * exists in the data structure.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrNodeOrEntryOrRawOrPredicate\n * - The `keyOrNodeOrEntryOrRawOrPredicate` parameter in the `override has` method can accept one of\n * the following types:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `override` method is used to specify the starting point for the search operation within the data\n * structure. It defaults to `this._root` if not provided explicitly.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `override has` method\n * is used to specify the type of iteration to be performed. It has a default value of\n * `this.iterationType`, which means it will use the iteration type defined in the current context if\n * no value is provided when calling the method.\n * @returns The `override has` method is returning a boolean value. It checks if there are any nodes\n * that match the provided key, node, entry, raw data, or predicate in the tree structure. If there\n * are matching nodes, it returns `true`, indicating that the tree contains the specified element.\n * Otherwise, it returns `false`.\n */\n override has(\n keyOrNodeOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): boolean {\n return this.getNodes(keyOrNodeOrEntryOrRawOrPredicate, true, beginRoot, iterationType).length > 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function resets the root node and size of a data structure to empty.\n */\n clear() {\n this._setRoot(undefined);\n this._size = 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `isEmpty` function in TypeScript checks if a data structure has no elements and returns a\n * boolean value.\n * @returns The `isEmpty()` method is returning a boolean value, specifically `true` if the `_size`\n * property is equal to 0, indicating that the data structure is empty, and `false` otherwise.\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function checks if a binary tree is perfectly balanced by comparing its minimum height with\n * its height.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for checking if the binary tree is perfectly balanced. It represents the root node of the\n * binary tree or a specific node from which the balance check should begin.\n * @returns The method `isPerfectlyBalanced` is returning a boolean value, which indicates whether\n * the tree starting from the `beginRoot` node is perfectly balanced or not. The return value is\n * determined by comparing the minimum height of the tree with the height of the tree. If the minimum\n * height plus 1 is greater than or equal to the height of the tree, then it is considered perfectly\n * balanced and\n */\n isPerfectlyBalanced(beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root): boolean {\n return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `isBST` in TypeScript checks if a binary search tree is valid using either recursive\n * or iterative methods.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `isBST`\n * function represents the starting point for checking whether a binary search tree (BST) is valid.\n * It can be a node in the BST or a reference to the root of the BST. If no specific node is\n * provided, the function will default to\n * @param {IterationType} iterationType - The `iterationType` parameter in the `isBST` function\n * determines whether the function should use a recursive approach or an iterative approach to check\n * if the binary search tree (BST) is valid.\n * @returns The `isBST` method is returning a boolean value, which indicates whether the binary\n * search tree (BST) represented by the given root node is a valid BST or not. The method checks if\n * the tree satisfies the BST property, where for every node, all nodes in its left subtree have keys\n * less than the node's key, and all nodes in its right subtree have keys greater than the node's\n */\n isBST(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): boolean {\n // TODO there is a bug\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return true;\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: OptBTNOrNull<NODE>, min: number, max: number): boolean => {\n if (!this.isRealNode(cur)) return true;\n const numKey = Number(cur.key);\n if (numKey <= min || numKey >= max) return false;\n return dfs(cur.left, min, numKey) && dfs(cur.right, numKey, max);\n };\n\n const isStandardBST = dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);\n const isInverseBST = dfs(beginRoot, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);\n return isStandardBST || isInverseBST;\n } else {\n const checkBST = (checkMax = false) => {\n const stack = [];\n let prev = checkMax ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;\n // @ts-ignore\n let curr: OptBTNOrNull<NODE> = beginRoot;\n while (this.isRealNode(curr) || stack.length > 0) {\n while (this.isRealNode(curr)) {\n stack.push(curr);\n curr = curr.left;\n }\n curr = stack.pop()!;\n const numKey = Number(curr.key);\n if (!this.isRealNode(curr) || (!checkMax && prev >= numKey) || (checkMax && prev <= numKey)) return false;\n prev = numKey;\n curr = curr.right;\n }\n return true;\n };\n const isStandardBST = checkBST(false),\n isInverseBST = checkBST(true);\n return isStandardBST || isInverseBST;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `getDepth` function calculates the depth between two nodes in a binary tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} dist - The `dist` parameter in the `getDepth`\n * function represents the node or entry in a binary tree map, or a reference to a node in the tree.\n * It is the target node for which you want to calculate the depth from the `beginRoot` node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getDepth` function represents the starting point from which you want to calculate the depth of a\n * given node or entry in a binary tree. If no specific starting point is provided, the default value\n * for `beginRoot` is set to the root of the binary\n * @returns The `getDepth` method returns the depth of a given node `dist` relative to the\n * `beginRoot` node in a binary tree. If the `dist` node is not found in the path to the `beginRoot`\n * node, it returns the depth of the `dist` node from the root of the tree.\n */\n getDepth(\n dist: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root\n ): number {\n let distEnsured = this.ensureNode(dist);\n const beginRootEnsured = this.ensureNode(beginRoot);\n let depth = 0;\n while (distEnsured?.parent) {\n if (distEnsured === beginRootEnsured) {\n return depth;\n }\n depth++;\n distEnsured = distEnsured.parent;\n }\n return depth;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `getHeight` function calculates the maximum height of a binary tree using either a recursive\n * or iterative approach in TypeScript.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point from which the height of the binary tree will be calculated. It can be a node in the binary\n * tree or a reference to the root of the tree. If not provided, it defaults to the root of the\n * binary tree data structure.\n * @param {IterationType} iterationType - The `iterationType` parameter is used to determine the type\n * of iteration to be performed while calculating the height of the binary tree. It can have two\n * possible values:\n * @returns The `getHeight` method returns the height of the binary tree starting from the specified\n * root node. The height is calculated based on the maximum depth of the tree, considering either a\n * recursive approach or an iterative approach depending on the `iterationType` parameter.\n */\n getHeight(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!this.isRealNode(beginRoot)) return -1;\n\n if (iterationType === 'RECURSIVE') {\n const _getMaxHeight = (cur: OptBTNOrNull<NODE>): number => {\n if (!this.isRealNode(cur)) return -1;\n const leftHeight = _getMaxHeight(cur.left);\n const rightHeight = _getMaxHeight(cur.right);\n return Math.max(leftHeight, rightHeight) + 1;\n };\n\n return _getMaxHeight(beginRoot);\n } else {\n const stack: { node: NODE; depth: number }[] = [{ node: beginRoot, depth: 0 }];\n let maxHeight = 0;\n\n while (stack.length > 0) {\n const { node, depth } = stack.pop()!;\n\n if (this.isRealNode(node.left)) stack.push({ node: node.left, depth: depth + 1 });\n if (this.isRealNode(node.right)) stack.push({ node: node.right, depth: depth + 1 });\n\n maxHeight = Math.max(maxHeight, depth);\n }\n\n return maxHeight;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The `getMinHeight` function calculates the minimum height of a binary tree using either a\n * recursive or iterative approach in TypeScript.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getMinHeight` function represents the starting node from which the minimum height of the binary\n * tree will be calculated. It is either a node in the binary tree or a reference to the root of the\n * tree. If not provided, the default value is the root\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getMinHeight` method\n * specifies the type of iteration to use when calculating the minimum height of a binary tree. It\n * can have two possible values:\n * @returns The `getMinHeight` method returns the minimum height of the binary tree starting from the\n * specified root node. The height is calculated based on the shortest path from the root node to a\n * leaf node in the tree. The method uses either a recursive approach or an iterative approach (using\n * a stack) based on the `iterationType` parameter.\n */\n getMinHeight(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return -1;\n\n if (iterationType === 'RECURSIVE') {\n const _getMinHeight = (cur: OptBTNOrNull<NODE>): number => {\n if (!this.isRealNode(cur)) return 0;\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return 0;\n const leftMinHeight = _getMinHeight(cur.left);\n const rightMinHeight = _getMinHeight(cur.right);\n return Math.min(leftMinHeight, rightMinHeight) + 1;\n };\n\n return _getMinHeight(beginRoot);\n } else {\n const stack: NODE[] = [];\n let node: OptBTNOrNull<NODE> = beginRoot,\n last: OptBTNOrNull<NODE> = null;\n const depths: Map<NODE, number> = new Map();\n\n while (stack.length > 0 || node) {\n if (this.isRealNode(node)) {\n stack.push(node);\n node = node.left;\n } else {\n node = stack[stack.length - 1];\n if (!this.isRealNode(node.right) || last === node.right) {\n node = stack.pop();\n if (this.isRealNode(node)) {\n const leftMinHeight = this.isRealNode(node.left) ? depths.get(node.left)! : -1;\n const rightMinHeight = this.isRealNode(node.right) ? depths.get(node.right)! : -1;\n depths.set(node, 1 + Math.min(leftMinHeight, rightMinHeight));\n last = node;\n node = null;\n }\n } else node = node.right;\n }\n }\n\n return depths.get(beginRoot)!;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n *\n * The function `getPathToRoot` in TypeScript retrieves the path from a given node to the root of a\n * tree structure, applying a specified callback function along the way.\n * @param {C} callback - The `callback` parameter is a function that is used to process each node in\n * the path to the root. It is expected to be a function that takes a node as an argument and returns\n * a value based on that node. The return type of the callback function is determined by the generic\n * type `C\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginNode - The `beginNode` parameter in the\n * `getPathToRoot` function can be either a key, a node, an entry, or any other value of type `R`.\n * @param [isReverse=true] - The `isReverse` parameter in the `getPathToRoot` function determines\n * whether the resulting path from the given `beginNode` to the root should be in reverse order or\n * not. If `isReverse` is set to `true`, the path will be reversed before being returned. If `is\n * @returns The function `getPathToRoot` returns an array of the return values of the callback\n * function `callback` applied to each node in the path from the `beginNode` to the root node. The\n * array is either in reverse order or in the original order based on the value of the `isReverse`\n * parameter.\n */\n getPathToRoot<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n isReverse = true\n ): ReturnType<C>[] {\n const result: ReturnType<C>[] = [];\n let beginNodeEnsured = this.ensureNode(beginNode);\n\n if (!beginNodeEnsured) return result;\n\n while (beginNodeEnsured.parent) {\n // Array.push + Array.reverse is more efficient than Array.unshift\n result.push(callback(beginNodeEnsured));\n beginNodeEnsured = beginNodeEnsured.parent;\n }\n result.push(callback(beginNodeEnsured));\n return isReverse ? result.reverse() : result;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getLeftMost` retrieves the leftmost node in a binary tree using either recursive or\n * tail-recursive iteration.\n * @param {C} callback - The `callback` parameter is a function that will be called with the leftmost\n * node of a binary tree or with `undefined` if the tree is empty. It is provided with a default\n * value of `_DEFAULT_BTN_CALLBACK` if not specified.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getLeftMost` function represents the starting point for finding the leftmost node in a binary\n * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific\n * starting point is provided, the function will default\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getLeftMost` function\n * specifies the type of iteration to be used when traversing the binary tree nodes. It can have two\n * possible values:\n * @returns The `getLeftMost` function returns the result of the callback function `C` applied to the\n * leftmost node in the binary tree starting from the `beginRoot` node. If the `beginRoot` node is\n * `NIL`, it returns the result of the callback function applied to `undefined`. If the `beginRoot`\n * node is not a real node, it returns the result of the callback\n */\n getLeftMost<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C> {\n if (this.isNIL(beginRoot)) return callback(undefined);\n beginRoot = this.ensureNode(beginRoot);\n\n if (!this.isRealNode(beginRoot)) return callback(beginRoot);\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE): NODE => {\n if (!this.isRealNode(cur.left)) return cur;\n return dfs(cur.left);\n };\n\n return callback(dfs(beginRoot));\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const dfs = trampoline((cur: NODE): NODE => {\n if (!this.isRealNode(cur.left)) return cur;\n return dfs.cont(cur.left);\n });\n\n return callback(dfs(beginRoot));\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getRightMost` retrieves the rightmost node in a binary tree using either recursive\n * or iterative traversal methods.\n * @param {C} callback - The `callback` parameter is a function that will be called with the result\n * of finding the rightmost node in a binary tree. It is of type `BTNCallback<OptBTNOrNull<NODE>>`,\n * which means it is a callback function that can accept either an optional binary tree node or null\n * as\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getRightMost` function represents the starting point for finding the rightmost node in a binary\n * tree. It can be either a key, a node, or an entry in the binary tree structure. If no specific\n * starting point is provided, the function will default\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getRightMost`\n * function specifies the type of iteration to be used when traversing the binary tree nodes. It can\n * have two possible values:\n * @returns The `getRightMost` function returns the result of the callback function `C`, which is\n * passed as a parameter to the function. The callback function is called with the rightmost node in\n * the binary tree structure, determined based on the specified iteration type ('RECURSIVE' or\n * other).\n */\n getRightMost<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C> {\n if (this.isNIL(beginRoot)) return callback(undefined);\n // TODO support get right most by passing key in\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return callback(beginRoot);\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE): NODE => {\n if (!this.isRealNode(cur.right)) return cur;\n return dfs(cur.right);\n };\n\n return callback(dfs(beginRoot));\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const dfs = trampoline((cur: NODE) => {\n if (!this.isRealNode(cur.right)) return cur;\n return dfs.cont(cur.right);\n });\n\n return callback(dfs(beginRoot));\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getPredecessor` in TypeScript returns the predecessor node of a given node in a\n * binary tree.\n * @param {NODE} node - The `getPredecessor` function you provided seems to be attempting to find the\n * predecessor of a given node in a binary tree. However, there seems to be a logical issue in the\n * while loop condition that might cause an infinite loop.\n * @returns The `getPredecessor` function returns the predecessor node of the input `NODE` parameter.\n * If the left child of the input node exists, it traverses to the rightmost node of the left subtree\n * to find the predecessor. If the left child does not exist, it returns the input node itself.\n */\n getPredecessor(node: NODE): NODE {\n if (this.isRealNode(node.left)) {\n let predecessor: OptBTNOrNull<NODE> = node.left;\n while (!this.isRealNode(predecessor) || (this.isRealNode(predecessor.right) && predecessor.right !== node)) {\n if (this.isRealNode(predecessor)) {\n predecessor = predecessor.right;\n }\n }\n return predecessor;\n } else {\n return node;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getSuccessor` in TypeScript returns the next node in an in-order traversal of a\n * binary tree.\n * @param {K | NODE | null} [x] - The `getSuccessor` function takes a parameter `x`, which can be of\n * type `K`, `NODE`, or `null`.\n * @returns The `getSuccessor` function returns the successor node of the input node `x`. If `x` has\n * a right child, the function returns the leftmost node in the right subtree of `x`. If `x` does not\n * have a right child, the function traverses up the parent nodes until it finds a node that is not\n * the right child of its parent, and returns that node\n */\n getSuccessor(x?: K | NODE | null): OptBTNOrNull<NODE> {\n x = this.ensureNode(x);\n if (!this.isRealNode(x)) return undefined;\n\n if (this.isRealNode(x.right)) {\n return this.getLeftMost(node => node, x.right);\n }\n\n let y: OptBTNOrNull<NODE> = x.parent;\n while (this.isRealNode(y) && x === y.right) {\n x = y;\n y = y.parent;\n }\n return y;\n }\n\n dfs<C extends BTNCallback<NODE>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType\n ): ReturnType<C>[];\n\n dfs<C extends BTNCallback<NODE | null>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: boolean\n ): ReturnType<C>[];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function `dfs` performs a depth-first search traversal on a binary tree structure based on the\n * specified parameters.\n * @param {C} callback - The `callback` parameter is a generic type `C` that extends the\n * `BTNCallback` interface with a type parameter of `OptBTNOrNull<NODE>`. It has a default value of\n * `this._DEFAULT_BTN_CALLBACK as C`.\n * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `dfs` method specifies the\n * order in which the Depth-First Search (DFS) algorithm should traverse the nodes in the tree. The\n * possible values for the `pattern` parameter are:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `dfs`\n * method is used to specify the starting point for the Depth-First Search traversal. It can be\n * either a `BTNKeyOrNodeOrEntry` object representing a key, node, or entry in the binary tree map,\n * or it can be a\n * @param {IterationType} iterationType - The `iterationType` parameter in the `dfs` method specifies\n * the type of iteration to be performed during the depth-first search traversal. It is used to\n * determine the order in which nodes are visited during the traversal.\n * @param [includeNull=false] - The `includeNull` parameter in the `dfs` method is a boolean flag\n * that determines whether null values should be included in the traversal or not. If `includeNull`\n * is set to `true`, then null values will be included in the traversal process. If it is set to\n * `false`,\n * @returns The `dfs` method is returning an array of the return type specified by the generic type\n * parameter `C`. The return type is determined by the callback function provided to the method.\n */\n dfs<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n return this._dfs(callback, pattern, beginRoot, iterationType, includeNull);\n }\n\n bfs<C extends BTNCallback<NODE>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n bfs<C extends BTNCallback<NODE | null>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: true\n ): ReturnType<C>[];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `bfs` function performs a breadth-first search traversal on a binary tree or binary search\n * tree, executing a specified callback function on each node visited.\n * @param {C} callback - The `callback` parameter in the `bfs` function is a function that will be\n * called on each node visited during the breadth-first search traversal. It is a generic type `C`\n * that extends the `BTNCallback` type, which takes a parameter of type `NODE` or `null`.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `bfs`\n * function represents the starting point for the breadth-first search traversal in a binary tree. It\n * can be specified as a key, node, or entry in the binary tree structure. If not provided, the\n * default value is the root node of the binary\n * @param {IterationType} iterationType - The `iterationType` parameter in the `bfs` function\n * determines the type of iteration to be performed on the binary tree nodes. It can have two\n * possible values:\n * @param [includeNull=false] - The `includeNull` parameter in the `bfs` function determines whether\n * to include `null` values in the breadth-first search traversal of a binary tree. If `includeNull`\n * is set to `true`, the traversal will include `null` values for nodes that do not have children\n * (left\n * @returns The `bfs` function returns an array of values that are the result of applying the\n * provided callback function to each node in the binary tree in a breadth-first search manner.\n */\n bfs<C extends BTNCallback<NODE | null>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n\n const ans: ReturnType<BTNCallback<NODE>>[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const queue: Queue<OptBTNOrNull<NODE>> = new Queue<OptBTNOrNull<NODE>>([beginRoot]);\n\n const dfs = (level: number) => {\n if (queue.size === 0) return;\n\n const current = queue.shift()!;\n ans.push(callback(current));\n\n if (includeNull) {\n if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (this.isRealNode(current.left)) queue.push(current.left);\n if (this.isRealNode(current.right)) queue.push(current.right);\n }\n\n dfs(level + 1);\n };\n\n dfs(0);\n } else {\n const queue = new Queue<OptBTNOrNull<NODE>>([beginRoot]);\n while (queue.size > 0) {\n const levelSize = queue.size;\n\n for (let i = 0; i < levelSize; i++) {\n const current = queue.shift()!;\n ans.push(callback(current));\n\n if (includeNull) {\n if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (this.isRealNode(current.left)) queue.push(current.left);\n if (this.isRealNode(current.right)) queue.push(current.right);\n }\n }\n }\n }\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `leaves` function in TypeScript returns an array of values from leaf nodes in a binary tree\n * structure based on a specified callback and iteration type.\n * @param {C} callback - The `callback` parameter is a function that will be called on each leaf node\n * in the binary tree. It is optional and defaults to a default callback function if not provided.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `leaves`\n * method is used to specify the starting point for finding and processing the leaves of a binary\n * tree. It can be provided as either a key, a node, or an entry in the binary tree structure. If not\n * explicitly provided, the default value\n * @param {IterationType} iterationType - The `iterationType` parameter in the `leaves` method\n * specifies the type of iteration to be performed when collecting the leaves of a binary tree. It\n * can have two possible values:\n * @returns The `leaves` method returns an array of values that are the result of applying the\n * provided callback function to each leaf node in the binary tree.\n */\n leaves<C extends BTNCallback<NODE | null>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n const leaves: ReturnType<BTNCallback<NODE>>[] = [];\n if (!this.isRealNode(beginRoot)) return [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n if (this.isLeaf(cur)) {\n leaves.push(callback(cur));\n }\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n };\n\n dfs(beginRoot);\n } else {\n const queue = new Queue([beginRoot]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (this.isRealNode(cur)) {\n if (this.isLeaf(cur)) {\n leaves.push(callback(cur));\n }\n if (this.isRealNode(cur.left)) queue.push(cur.left);\n if (this.isRealNode(cur.right)) queue.push(cur.right);\n }\n }\n }\n\n return leaves;\n }\n\n listLevels<C extends BTNCallback<NODE>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[][];\n\n listLevels<C extends BTNCallback<NODE | null>>(\n callback?: C,\n beginRoot?: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType?: IterationType,\n includeNull?: true\n ): ReturnType<C>[][];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `listLevels` function in TypeScript generates a list of nodes at each level of a binary tree,\n * using either recursive or iterative traversal based on the specified iteration type.\n * @param {C} callback - The `callback` parameter is a function that will be applied to each node in\n * the binary tree during the traversal. It is used to process each node and determine what\n * information to include in the output for each level of the tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `listLevels` function represents the starting point for traversing the binary tree. It can be\n * either a key, a node, or an entry in the binary tree. If not provided, the default value is the\n * root of the binary tree.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `listLevels` function\n * determines the type of iteration to be performed on the binary tree nodes. It can have two\n * possible values:\n * @param [includeNull=false] - The `includeNull` parameter in the `listLevels` method determines\n * whether or not to include null nodes in the traversal of the binary tree. If `includeNull` is set\n * to `true`, the traversal will include null nodes in the levels of the tree. If set to `false`,\n * null\n * @returns The `listLevels` method returns an array of arrays, where each inner array represents a\n * level in a binary tree. Each inner array contains the return value of the provided callback\n * function applied to the nodes at that level.\n */\n listLevels<C extends BTNCallback<NODE | null>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[][] {\n beginRoot = this.ensureNode(beginRoot);\n const levelsNodes: ReturnType<C>[][] = [];\n if (!beginRoot) return levelsNodes;\n\n if (iterationType === 'RECURSIVE') {\n const _recursive = (node: NODE | null, level: number) => {\n if (!levelsNodes[level]) levelsNodes[level] = [];\n levelsNodes[level].push(callback(node));\n if (includeNull) {\n if (node && this.isRealNodeOrNull(node.left)) _recursive(node.left, level + 1);\n if (node && this.isRealNodeOrNull(node.right)) _recursive(node.right, level + 1);\n } else {\n if (node && node.left) _recursive(node.left, level + 1);\n if (node && node.right) _recursive(node.right, level + 1);\n }\n };\n\n _recursive(beginRoot, 0);\n } else {\n const stack: [NODE | null, number][] = [[beginRoot, 0]];\n\n while (stack.length > 0) {\n const head = stack.pop()!;\n const [node, level] = head;\n\n if (!levelsNodes[level]) levelsNodes[level] = [];\n levelsNodes[level].push(callback(node));\n\n if (includeNull) {\n if (node && this.isRealNodeOrNull(node.right)) stack.push([node.right, level + 1]);\n if (node && this.isRealNodeOrNull(node.left)) stack.push([node.left, level + 1]);\n } else {\n if (node && node.right) stack.push([node.right, level + 1]);\n if (node && node.left) stack.push([node.left, level + 1]);\n }\n }\n }\n\n return levelsNodes;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `morris` function in TypeScript performs a Depth-First Search traversal on a binary tree using\n * Morris Traversal algorithm with different order patterns.\n * @param {C} callback - The `callback` parameter in the `morris` function is a function that will be\n * called on each node in the binary tree during the traversal. It is of type `C`, which extends the\n * `BTNCallback<NODE>` type. The default value for `callback` is `this._DEFAULT\n * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `morris` function specifies\n * the type of Depth-First Search (DFS) order pattern to traverse the binary tree. The possible\n * values for the `pattern` parameter are:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `morris`\n * function is the starting point for the Morris traversal algorithm. It represents the root node of\n * the binary tree or the node from which the traversal should begin. It can be provided as either a\n * key, a node, an entry, or a reference\n * @returns The `morris` function is returning an array of values that are the result of applying the\n * provided callback function to each node in the binary tree in the specified order pattern (IN,\n * PRE, or POST).\n */\n morris<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: ReturnType<BTNCallback<NODE>>[] = [];\n\n let cur: OptBTNOrNull<NODE> = beginRoot;\n const _reverseEdge = (node: OptBTNOrNull<NODE>) => {\n let pre: OptBTNOrNull<NODE> = null;\n let next: OptBTNOrNull<NODE> = null;\n while (node) {\n next = node.right;\n node.right = pre;\n pre = node;\n node = next;\n }\n return pre;\n };\n const _printEdge = (node: OptBTNOrNull<NODE>) => {\n const tail: OptBTNOrNull<NODE> = _reverseEdge(node);\n let cur: OptBTNOrNull<NODE> = tail;\n while (cur) {\n ans.push(callback(cur));\n cur = cur.right;\n }\n _reverseEdge(tail);\n };\n switch (pattern) {\n case 'IN':\n while (cur) {\n if (cur.left) {\n const predecessor = this.getPredecessor(cur);\n if (!predecessor.right) {\n predecessor.right = cur;\n cur = cur.left;\n continue;\n } else {\n predecessor.right = null;\n }\n }\n ans.push(callback(cur));\n cur = cur.right;\n }\n break;\n case 'PRE':\n while (cur) {\n if (cur.left) {\n const predecessor = this.getPredecessor(cur);\n if (!predecessor.right) {\n predecessor.right = cur;\n ans.push(callback(cur));\n cur = cur.left;\n continue;\n } else {\n predecessor.right = null;\n }\n } else {\n ans.push(callback(cur));\n }\n cur = cur.right;\n }\n break;\n case 'POST':\n while (cur) {\n if (cur.left) {\n const predecessor = this.getPredecessor(cur);\n if (predecessor.right === null) {\n predecessor.right = cur;\n cur = cur.left;\n continue;\n } else {\n predecessor.right = null;\n _printEdge(cur.left);\n }\n }\n cur = cur.right;\n }\n _printEdge(beginRoot);\n break;\n }\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `clone` function creates a deep copy of a tree structure by traversing it using breadth-first\n * search.\n * @returns The `clone()` method is returning a cloned copy of the tree with the same structure and\n * values as the original tree. The method creates a new tree, iterates over the nodes of the\n * original tree using breadth-first search (bfs), and adds the nodes to the new tree. If a node in\n * the original tree is null, a null node is added to the cloned tree. If a node\n */\n clone(): TREE {\n const cloned = this.createTree();\n this.bfs(\n node => {\n if (node === null) cloned.add(null);\n else cloned.add([node.key, node.value]);\n },\n this._root,\n this.iterationType,\n true\n );\n return cloned;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function iterates over key-value pairs in a tree data structure and creates a new\n * tree with elements that satisfy a given predicate.\n * @param predicate - The `predicate` parameter in the `filter` method is a function that will be\n * called with four arguments: the `value` of the current entry, the `key` of the current entry, the\n * `index` of the current entry in the iteration, and the reference to the tree itself (`\n * @param {any} [thisArg] - The `thisArg` parameter in the `filter` method allows you to specify the\n * value of `this` that should be used when executing the `predicate` function. This is useful when\n * the `predicate` function relies on the context of a specific object or value. By providing a\n * `thisArg\n * @returns The `filter` method is returning a new tree that contains entries that pass the provided\n * predicate function.\n */\n filter(predicate: EntryCallback<K, V | undefined, boolean>, thisArg?: any) {\n const newTree = this.createTree();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate.call(thisArg, value, key, index++, this)) {\n newTree.add([key, value]);\n }\n }\n return newTree;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function iterates over key-value pairs in a tree data structure, applies a callback\n * function to each value, and returns a new tree with the updated values.\n * @param callback - The `callback` parameter in the `map` method is a function that will be called\n * on each entry in the tree. It takes four arguments:\n * @param {any} [thisArg] - The `thisArg` parameter in the `map` function is an optional parameter\n * that specifies the value to be passed as `this` when executing the callback function. If provided,\n * the `thisArg` value will be used as the `this` value within the callback function. If `thisArg\n * @returns The `map` method is returning a new tree with the entries modified by the provided\n * callback function. Each entry in the original tree is passed to the callback function, and the\n * result of the callback function is added to the new tree.\n */\n map(callback: EntryCallback<K, V | undefined, V>, thisArg?: any) {\n const newTree = this.createTree();\n let index = 0;\n for (const [key, value] of this) {\n newTree.add([key, callback.call(thisArg, value, key, index++, this)]);\n }\n return newTree;\n }\n\n // // TODO Type error, need to return a TREE<NV> that is a value type only for callback function.\n // // map<NV>(callback: (entry: [K, V | undefined], tree: this) => NV) {\n // // const newTree = this.createTree();\n // // for (const [key, value] of this) {\n // // newTree.add(key, callback([key, value], this));\n // // }\n // // return newTree;\n // // }\n //\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `toVisual` in TypeScript overrides the visual representation of a binary tree with\n * customizable options for displaying undefined, null, and sentinel nodes.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `toVisual` method is used to specify the starting point for visualizing the binary tree structure.\n * It can be a node, key, entry, or the root of the tree. If no specific starting point is provided,\n * the default is set to the root\n * @param {BinaryTreePrintOptions} [options] - The `options` parameter in the `toVisual` method is an\n * object that contains the following properties:\n * @returns The `override toVisual` method returns a string that represents the visual display of the\n * binary tree based on the provided options for showing undefined, null, and Red-Black NIL nodes.\n * The method constructs the visual representation by calling the `_displayAux` method and appending\n * the lines to the output string. The final output string contains the visual representation of the\n * binary tree with the specified options.\n */\n override toVisual(\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n options?: BinaryTreePrintOptions\n ): string {\n const opts = { isShowUndefined: false, isShowNull: true, isShowRedBlackNIL: false, ...options };\n beginRoot = this.ensureNode(beginRoot);\n let output = '';\n if (!beginRoot) return output;\n\n if (opts.isShowUndefined) output += `U for undefined\\n`;\n if (opts.isShowNull) output += `N for null\\n`;\n if (opts.isShowRedBlackNIL) output += `S for Sentinel Node(NIL)\\n`;\n\n const display = (root: OptBTNOrNull<NODE>): void => {\n const [lines, , ,] = this._displayAux(root, opts);\n let paragraph = '';\n for (const line of lines) {\n paragraph += line + '\\n';\n }\n output += paragraph;\n };\n\n display(beginRoot);\n return output;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `print` in TypeScript overrides the default print behavior to log a visual\n * representation of the binary tree to the console.\n * @param {BinaryTreePrintOptions} [options] - The `options` parameter is used to specify the\n * printing options for the binary tree. It is an optional parameter that allows you to customize how\n * the binary tree is printed, such as choosing between different traversal orders or formatting\n * options.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `override print` method is used to specify the starting point for printing the binary tree. It can\n * be either a key, a node, an entry, or the root of the tree. If no specific starting point is\n * provided, the default value is set to\n */\n override print(options?: BinaryTreePrintOptions, beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root) {\n console.log(this.toVisual(beginRoot, options));\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `_dfs` function performs a depth-first search traversal on a binary tree structure based on\n * the specified order pattern and callback function.\n * @param {C} callback - The `callback` parameter in the `_dfs` method is a function that will be\n * called on each node visited during the depth-first search traversal. It is of type `C`, which\n * extends `BTNCallback<OptBTNOrNull<NODE>>`. The default value for this parameter is `this._DEFAULT\n * @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the\n * order in which the nodes are visited during the Depth-First Search traversal. It can have one of\n * the following values:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the `_dfs`\n * method is used to specify the starting point for the depth-first search traversal in a binary\n * tree. It can be provided as either a `BTNKeyOrNodeOrEntry` object or a reference to the root node\n * of the tree. If no specific\n * @param {IterationType} iterationType - The `iterationType` parameter in the `_dfs` method\n * specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal of a\n * binary tree. It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter in the `_dfs` method is a boolean flag\n * that determines whether null nodes should be included in the depth-first search traversal. If\n * `includeNull` is set to `true`, null nodes will be considered during the traversal process. If it\n * is set to `false`,\n * @param shouldVisitLeft - The `shouldVisitLeft` parameter is a function that takes a node as input\n * and returns a boolean value. It is used to determine whether the left child of a node should be\n * visited during the depth-first search traversal. By default, it checks if the node is truthy (not\n * null or undefined\n * @param shouldVisitRight - The `shouldVisitRight` parameter is a function that takes a node as an\n * argument and returns a boolean value. It is used to determine whether the right child of a node\n * should be visited during the depth-first search traversal. The default implementation checks if\n * the node is truthy before visiting the right child\n * @param shouldVisitRoot - The `shouldVisitRoot` parameter is a function that takes a node as an\n * argument and returns a boolean value. It is used to determine whether the root node should be\n * visited during the depth-first search traversal based on certain conditions. The default\n * implementation checks if the node is a real node or null based\n * @param shouldProcessRoot - The `shouldProcessRoot` parameter is a function that takes a node as an\n * argument and returns a boolean value indicating whether the node should be processed during the\n * depth-first search traversal. The default implementation checks if the node is a real node or null\n * based on the `includeNull` flag. If `\n * @returns The function `_dfs` returns an array of the return type of the callback function provided\n * as input.\n */\n protected _dfs<C extends BTNCallback<OptBTNOrNull<NODE>>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType,\n includeNull = false,\n shouldVisitLeft: (node: OptBTNOrNull<NODE>) => boolean = node => !!node,\n shouldVisitRight: (node: OptBTNOrNull<NODE>) => boolean = node => !!node,\n shouldVisitRoot: (node: OptBTNOrNull<NODE>) => boolean = node => {\n if (includeNull) return this.isRealNodeOrNull(node);\n return this.isRealNode(node);\n },\n shouldProcessRoot: (node: OptBTNOrNull<NODE>) => boolean = node => this.isRealNodeOrNull(node)\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: ReturnType<C>[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (node: OptBTNOrNull<NODE>) => {\n if (!shouldVisitRoot(node)) return;\n\n const visitLeft = () => {\n if (shouldVisitLeft(node)) dfs(node?.left);\n };\n const visitRight = () => {\n if (shouldVisitRight(node)) dfs(node?.right);\n };\n\n switch (pattern) {\n case 'IN':\n visitLeft();\n if (shouldProcessRoot(node)) ans.push(callback(node));\n visitRight();\n break;\n case 'PRE':\n if (shouldProcessRoot(node)) ans.push(callback(node));\n visitLeft();\n visitRight();\n break;\n case 'POST':\n visitLeft();\n visitRight();\n if (shouldProcessRoot(node)) ans.push(callback(node));\n break;\n }\n };\n\n dfs(beginRoot);\n } else {\n const stack: DFSStackItem<NODE>[] = [{ opt: DFSOperation.VISIT, node: beginRoot }];\n\n const pushLeft = (cur: DFSStackItem<NODE>) => {\n if (shouldVisitLeft(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.left });\n };\n const pushRight = (cur: DFSStackItem<NODE>) => {\n if (shouldVisitRight(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.right });\n };\n const pushRoot = (cur: DFSStackItem<NODE>) => {\n if (shouldVisitRoot(cur.node)) stack.push({ opt: DFSOperation.PROCESS, node: cur.node });\n };\n\n while (stack.length > 0) {\n const cur = stack.pop();\n if (cur === undefined) continue;\n if (!shouldVisitRoot(cur.node)) continue;\n if (cur.opt === DFSOperation.PROCESS) {\n if (shouldProcessRoot(cur.node)) ans.push(callback(cur.node));\n } else {\n switch (pattern) {\n case 'IN':\n pushRight(cur);\n pushRoot(cur);\n pushLeft(cur);\n break;\n case 'PRE':\n pushRight(cur);\n pushLeft(cur);\n pushRoot(cur);\n break;\n case 'POST':\n pushRoot(cur);\n pushRight(cur);\n pushLeft(cur);\n break;\n }\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_getIterator` returns an iterable iterator for a binary tree data structure, either\n * using an iterative approach or a recursive approach based on the specified iteration type.\n * @param node - The `node` parameter in the `_getIterator` method represents the current node being\n * processed during iteration. It is initially set to the root node of the data structure (or the\n * node passed as an argument), and then it is traversed through the data structure based on the\n * iteration type specified (`ITER\n * @returns The `_getIterator` method returns an IterableIterator containing key-value pairs of nodes\n * in a binary tree structure. The method uses an iterative approach to traverse the tree based on\n * the `iterationType` property. If the `iterationType` is set to 'ITERATIVE', the method uses a\n * stack to perform an in-order traversal of the tree. If the `iterationType` is not 'ITERATIVE\n */\n protected *_getIterator(node = this._root): IterableIterator<[K, V | undefined]> {\n if (!node) return;\n\n if (this.iterationType === 'ITERATIVE') {\n const stack: OptBTNOrNull<NODE>[] = [];\n let current: OptBTNOrNull<NODE> = node;\n\n while (current || stack.length > 0) {\n while (this.isRealNode(current)) {\n stack.push(current);\n current = current.left;\n }\n\n current = stack.pop();\n\n if (this.isRealNode(current)) {\n yield [current.key, current.value];\n current = current.right;\n }\n }\n } else {\n if (node.left && this.isRealNode(node)) {\n yield* this[Symbol.iterator](node.left);\n }\n yield [node.key, node.value];\n if (node.right && this.isRealNode(node)) {\n yield* this[Symbol.iterator](node.right);\n }\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `_displayAux` in TypeScript is responsible for generating the display layout of nodes\n * in a binary tree based on specified options.\n * @param node - The `node` parameter in the `_displayAux` function represents a node in a binary\n * tree. It can be either a valid node containing a key or a special type of node like null,\n * undefined, or a Red-Black tree NIL node. The function checks the type of the node and its\n * @param {BinaryTreePrintOptions} options - The `options` parameter in the `_displayAux` function\n * contains the following properties:\n * @returns The `_displayAux` function returns a `NodeDisplayLayout`, which is an array containing\n * information about how to display a node in a binary tree. The `NodeDisplayLayout` consists of four\n * elements:\n */\n protected _displayAux(node: OptBTNOrNull<NODE>, options: BinaryTreePrintOptions): NodeDisplayLayout {\n const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;\n const emptyDisplayLayout = <NodeDisplayLayout>[['─'], 1, 0, 0];\n\n // Check if node is null or undefined or key is NaN\n if (node === null && !isShowNull) {\n return emptyDisplayLayout;\n } else if (node === undefined && !isShowUndefined) {\n return emptyDisplayLayout;\n } else if (this.isNIL(node) && !isShowRedBlackNIL) {\n return emptyDisplayLayout;\n } else if (node !== null && node !== undefined) {\n // Display logic of normal nodes\n\n const key = node.key,\n line = this.isNIL(node) ? 'S' : String(key),\n width = line.length;\n\n return _buildNodeDisplay(\n line,\n width,\n this._displayAux(node.left, options),\n this._displayAux(node.right, options)\n );\n } else {\n // For cases where none of the conditions are met, null, undefined, and NaN nodes are not displayed\n const line = node === undefined ? 'U' : 'N',\n width = line.length;\n\n return _buildNodeDisplay(line, width, [[''], 1, 0, 0], [[''], 1, 0, 0]);\n }\n\n function _buildNodeDisplay(line: string, width: number, left: NodeDisplayLayout, right: NodeDisplayLayout) {\n const [leftLines, leftWidth, leftHeight, leftMiddle] = left;\n const [rightLines, rightWidth, rightHeight, rightMiddle] = right;\n const firstLine =\n ' '.repeat(Math.max(0, leftMiddle + 1)) +\n '_'.repeat(Math.max(0, leftWidth - leftMiddle - 1)) +\n line +\n '_'.repeat(Math.max(0, rightMiddle)) +\n ' '.repeat(Math.max(0, rightWidth - rightMiddle));\n\n const secondLine =\n (leftHeight > 0\n ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1)\n : ' '.repeat(leftWidth)) +\n ' '.repeat(width) +\n (rightHeight > 0\n ? ' '.repeat(rightMiddle) + '\\\\' + ' '.repeat(rightWidth - rightMiddle - 1)\n : ' '.repeat(rightWidth));\n\n const mergedLines = [firstLine, secondLine];\n\n for (let i = 0; i < Math.max(leftHeight, rightHeight); i++) {\n const leftLine = i < leftHeight ? leftLines[i] : ' '.repeat(leftWidth);\n const rightLine = i < rightHeight ? rightLines[i] : ' '.repeat(rightWidth);\n mergedLines.push(leftLine + ' '.repeat(width) + rightLine);\n }\n\n return <NodeDisplayLayout>[\n mergedLines,\n leftWidth + width + rightWidth,\n Math.max(leftHeight, rightHeight) + 2,\n leftWidth + Math.floor(width / 2)\n ];\n }\n }\n\n protected _DEFAULT_BTN_CALLBACK = (node: OptBTNOrNull<NODE>) => (node ? node.key : undefined);\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The _swapProperties function swaps key and value properties between two nodes in a binary tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} srcNode - The `srcNode` parameter in the\n * `_swapProperties` method can be either a BTNKeyOrNodeOrEntry object containing key and value\n * properties, or it can be of type R.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} destNode - The `destNode` parameter in the\n * `_swapProperties` method represents the node or entry where the properties will be swapped with\n * the `srcNode`. It can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>` or `R`. The method ensures that\n * both `srcNode\n * @returns The `_swapProperties` method returns either the `destNode` with its key and value swapped\n * with the `srcNode`, or `undefined` if either `srcNode` or `destNode` is falsy.\n */\n protected _swapProperties(\n srcNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n destNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R\n ): NODE | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n\n if (srcNode && destNode) {\n const { key, value } = destNode;\n const tempNode = this.createNode(key, value);\n\n if (tempNode) {\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The _replaceNode function replaces an old node with a new node in a binary tree structure.\n * @param {NODE} oldNode - The `oldNode` parameter represents the node that you want to replace in a\n * tree data structure.\n * @param {NODE} newNode - The `newNode` parameter in the `_replaceNode` function represents the node\n * that will replace the `oldNode` in a tree data structure. This function is responsible for\n * updating the parent, left child, right child, and root (if necessary) references when replacing a\n * node in the tree.\n * @returns The method `_replaceNode` is returning the `newNode` that was passed as a parameter after\n * replacing the `oldNode` with it in the binary tree structure.\n */\n protected _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n if (oldNode.parent) {\n if (oldNode.parent.left === oldNode) {\n oldNode.parent.left = newNode;\n } else if (oldNode.parent.right === oldNode) {\n oldNode.parent.right = newNode;\n }\n }\n newNode.left = oldNode.left;\n newNode.right = oldNode.right;\n newNode.parent = oldNode.parent;\n if (this._root === oldNode) {\n this._setRoot(newNode);\n }\n\n return newNode;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function _setRoot sets the root node of a data structure while updating the parent reference\n * of the previous root node.\n * @param v - The parameter `v` in the `_setRoot` method is of type `OptBTNOrNull<NODE>`, which means\n * it can either be an optional `NODE` type or `null`.\n */\n protected _setRoot(v: OptBTNOrNull<NODE>) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_ensurePredicate` in TypeScript ensures that the input is converted into a valid\n * predicate function for a binary tree node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} keyOrEntryOrRawOrPredicate - The\n * `_ensurePredicate` method in the provided code snippet is responsible for ensuring that the input\n * parameter `keyOrEntryOrRawOrPredicate` is transformed into a valid predicate function that can be\n * used for filtering nodes in a binary tree.\n * @returns A BTNPredicate<NODE> function is being returned.\n */\n protected _ensurePredicate(\n keyOrEntryOrRawOrPredicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>\n ): BTNPredicate<NODE> {\n if (keyOrEntryOrRawOrPredicate === null || keyOrEntryOrRawOrPredicate === undefined)\n return (node: NODE) => (node ? false : false);\n\n if (this._isPredicated(keyOrEntryOrRawOrPredicate)) return keyOrEntryOrRawOrPredicate;\n\n if (this.isRealNode(keyOrEntryOrRawOrPredicate)) return (node: NODE) => node === keyOrEntryOrRawOrPredicate;\n\n if (this.isEntry(keyOrEntryOrRawOrPredicate)) {\n const [key] = keyOrEntryOrRawOrPredicate;\n return (node: NODE) => node.key === key;\n }\n\n if (this.isKey(keyOrEntryOrRawOrPredicate)) return (node: NODE) => node.key === keyOrEntryOrRawOrPredicate;\n\n if (this._toEntryFn) {\n const [key] = this._toEntryFn(keyOrEntryOrRawOrPredicate);\n return (node: NODE) => node.key === key;\n }\n return (node: NODE) => node.key === keyOrEntryOrRawOrPredicate;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_isPredicated` checks if a given parameter is a function.\n * @param {any} p - The parameter `p` is a variable of type `any`, which means it can hold any type\n * of value. In this context, the function `_isPredicated` is checking if `p` is a function that\n * satisfies the type `BTNPredicate<NODE>`.\n * @returns The function is checking if the input `p` is a function and returning a boolean value\n * based on that check. If `p` is a function, it will return `true`, indicating that `p` is a\n * predicate function for a binary tree node. If `p` is not a function, it will return `false`.\n */\n protected _isPredicated(p: any): p is BTNPredicate<NODE> {\n return typeof p === 'function';\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n BSTNested,\n BSTNKeyOrNode,\n BSTNodeNested,\n BSTOptions,\n BTNCallback,\n BTNEntry,\n BTNKeyOrNodeOrEntry,\n BTNPredicate,\n Comparator,\n CP,\n DFSOrderPattern,\n IterationType,\n OptBSTN\n} from '../../types';\nimport { BinaryTree, BinaryTreeNode } from './binary-tree';\nimport { IBinaryTree } from '../../interfaces';\nimport { Queue } from '../queue';\nimport { isComparable } from '../../utils';\n\nexport class BSTNode<K = any, V = any, NODE extends BSTNode<K, V, NODE> = BSTNodeNested<K, V>> extends BinaryTreeNode<\n K,\n V,\n NODE\n> {\n override parent?: NODE;\n\n constructor(key: K, value?: V) {\n super(key, value);\n this.parent = undefined;\n this._left = undefined;\n this._right = undefined;\n }\n\n protected override _left?: NODE;\n\n /**\n * The function returns the value of the `_left` property.\n * @returns The `_left` property of the current object is being returned.\n */\n override get left(): OptBSTN<NODE> {\n return this._left;\n }\n\n /**\n * The function sets the left child of a node and updates the parent reference of the child.\n * @param {OptBSTN<NODE>} v - The parameter `v` is of type `OptBSTN<NODE>`. It can either be an\n * instance of the `NODE` class or `undefined`.\n */\n override set left(v: OptBSTN<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._left = v;\n }\n\n protected override _right?: NODE;\n\n /**\n * The function returns the right node of a binary tree or undefined if there is no right node.\n * @returns The method is returning the value of the `_right` property, which is of type `NODE` or\n * `undefined`.\n */\n override get right(): OptBSTN<NODE> {\n return this._right;\n }\n\n /**\n * The function sets the right child of a node and updates the parent reference of the child.\n * @param {OptBSTN<NODE>} v - The parameter `v` is of type `OptBSTN<NODE>`. It can either be a\n * `NODE` object or `undefined`.\n */\n override set right(v: OptBSTN<NODE>) {\n if (v) {\n v.parent = this as unknown as NODE;\n }\n this._right = v;\n }\n}\n\n/**\n * 1. Node Order: Each node's left child has a lesser value, and the right child has a greater value.\n * 2. Unique Keys: No duplicate keys in a standard BST.\n * 3. Efficient Search: Enables quick search, minimum, and maximum operations.\n * 4. Inorder Traversal: Yields nodes in ascending order.\n * 5. Logarithmic Operations: Ideal operations like insertion, deletion, and searching are O(log n) time-efficient.\n * 6. Balance Variability: Can become unbalanced; special types maintain balance.\n * 7. No Auto-Balancing: Standard BSTs don't automatically balance themselves.\n */\nexport class BST<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends BSTNode<K, V, NODE> = BSTNode<K, V, BSTNodeNested<K, V>>,\n TREE extends BST<K, V, R, NODE, TREE> = BST<K, V, R, NODE, BSTNested<K, V, R, NODE>>\n >\n extends BinaryTree<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * This is the constructor function for a Binary Search Tree class in TypeScript.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable that can contain either keys, nodes, entries, or raw elements. These elements will be\n * added to the binary search tree during the construction of the object.\n * @param [options] - An optional object that contains additional options for the Binary Search Tree.\n * It can include a comparator function that defines the order of the elements in the tree.\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: BSTOptions<K, V, R>\n ) {\n super([], options);\n\n if (options) {\n const { comparator } = options;\n if (comparator) this._comparator = comparator;\n }\n\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected override _root?: NODE = undefined;\n\n /**\n * The function returns the root node of a tree structure.\n * @returns The `_root` property of the object, which is of type `NODE` or `undefined`.\n */\n override get root(): OptBSTN<NODE> {\n return this._root;\n }\n\n /**\n * The function creates a new BSTNode with the given key and value and returns it.\n * @param {K} key - The key parameter is of type K, which represents the type of the key for the node\n * being created.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It represents the\n * value associated with the key in the node being created.\n * @returns The method is returning a new instance of the BSTNode class, casted as the NODE type.\n */\n override createNode(key: K, value?: V): NODE {\n return new BSTNode<K, V, NODE>(key, value) as NODE;\n }\n\n /**\n * The function creates a new binary search tree with the specified options.\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the `createTree` method. It accepts a partial `BSTOptions` object, which has the\n * following properties:\n * @returns a new instance of the BST class with the provided options.\n */\n override createTree(options?: BSTOptions<K, V, R>): TREE {\n return new BST<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function overrides a method and converts a key, value pair or entry or raw element to a node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - A variable that can be of\n * type R or BTNKeyOrNodeOrEntry<K, V, NODE>. It represents either a key, a node, an entry, or a raw\n * element.\n * @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the\n * value associated with a key in a key-value pair.\n * @returns either a NODE object or undefined.\n */\n override keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V\n ): OptBSTN<NODE> {\n return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value) ?? undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n *\n * The function ensures the existence of a node in a data structure and returns it, or undefined if\n * it doesn't exist.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept a value of type `R`, which represents the key, node,\n * entry, or raw element that needs to be ensured in the tree.\n * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional\n * parameter that specifies the type of iteration to be used when ensuring a node. It has a default\n * value of `'ITERATIVE'`.\n * @returns The method is returning either the node that was ensured or `undefined` if the node could\n * not be ensured.\n */\n override ensureNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n iterationType: IterationType = this.iterationType\n ): OptBSTN<NODE> {\n return super.ensureNode(keyOrNodeOrEntryOrRaw, iterationType) ?? undefined;\n }\n\n /**\n * The function checks if the input is an instance of the BSTNode class.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `BSTNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof BSTNode;\n }\n\n /**\n * The function \"override isKey\" checks if a key is comparable based on a given comparator.\n * @param {any} key - The `key` parameter is a value that will be checked to determine if it is of\n * type `K`.\n * @returns The `override isKey(key: any): key is K` function is returning a boolean value based on\n * the result of the `isComparable` function with the condition `this.comparator !==\n * this._DEFAULT_COMPARATOR`.\n */\n override isKey(key: any): key is K {\n return isComparable(key, this.comparator !== this._DEFAULT_COMPARATOR);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `add` function in TypeScript adds a new node to a binary search tree based on the key value.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that can be associated with the\n * key in the binary search tree. If provided, it will be stored in the node along with the key.\n * @returns a boolean value.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);\n if (newNode === undefined) return false;\n\n if (this._root === undefined) {\n this._setRoot(newNode);\n this._size++;\n return true;\n }\n\n let current = this._root;\n while (current !== undefined) {\n if (this.comparator(current.key, newNode.key) === 0) {\n this._replaceNode(current, newNode);\n return true;\n } else if (this.comparator(current.key, newNode.key) > 0) {\n if (current.left === undefined) {\n current.left = newNode;\n this._size++;\n return true;\n }\n current = current.left;\n } else {\n if (current.right === undefined) {\n current.right = newNode;\n this._size++;\n return true;\n }\n current = current.right;\n }\n }\n\n return false;\n }\n\n /**\n * Time Complexity: O(k log n)\n * Space Complexity: O(k + log n)\n *\n * The `addMany` function in TypeScript adds multiple keys or nodes to a data structure and returns\n * an array indicating whether each key or node was successfully inserted.\n * @param keysOrNodesOrEntriesOrRaws - An iterable containing keys, nodes, entries, or raw\n * elements to be added to the data structure.\n * @param [values] - An optional iterable of values to be associated with the keys or nodes being\n * added. If provided, the values will be assigned to the corresponding keys or nodes in the same\n * order. If not provided, undefined will be assigned as the value for each key or node.\n * @param [isBalanceAdd=true] - A boolean flag indicating whether the tree should be balanced after\n * adding the elements. If set to true, the tree will be balanced using a binary search tree\n * algorithm. If set to false, the elements will be added without balancing the tree. The default\n * value is true.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when adding multiple keys or nodes to the binary search\n * tree. It can have two possible values:\n * @returns The function `addMany` returns an array of booleans indicating whether each element was\n * successfully inserted into the data structure.\n */\n override addMany(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>>,\n values?: Iterable<V | undefined>,\n isBalanceAdd = true,\n iterationType: IterationType = this.iterationType\n ): boolean[] {\n const inserted: boolean[] = [];\n\n let valuesIterator: Iterator<V | undefined> | undefined;\n\n if (values) {\n valuesIterator = values[Symbol.iterator]();\n }\n\n if (!isBalanceAdd) {\n for (const kve of keysOrNodesOrEntriesOrRaws) {\n const value = valuesIterator?.next().value;\n inserted.push(this.add(kve, value));\n }\n return inserted;\n }\n\n const realBTNExemplars: {\n key: R | BTNKeyOrNodeOrEntry<K, V, NODE>;\n value: V | undefined;\n orgIndex: number;\n }[] = [];\n\n let i = 0;\n for (const kve of keysOrNodesOrEntriesOrRaws) {\n realBTNExemplars.push({ key: kve, value: valuesIterator?.next().value, orgIndex: i });\n i++;\n }\n\n let sorted: { key: R | BTNKeyOrNodeOrEntry<K, V, NODE>; value: V | undefined; orgIndex: number }[] = [];\n\n sorted = realBTNExemplars.sort(({ key: a }, { key: b }) => {\n let keyA: K | undefined | null, keyB: K | undefined | null;\n if (this.isEntry(a)) keyA = a[0];\n else if (this.isRealNode(a)) keyA = a.key;\n else if (this._toEntryFn) {\n keyA = this._toEntryFn(a as R)[0];\n } else {\n keyA = a as K;\n }\n\n if (this.isEntry(b)) keyB = b[0];\n else if (this.isRealNode(b)) keyB = b.key;\n else if (this._toEntryFn) {\n keyB = this._toEntryFn(b as R)[0];\n } else {\n keyB = b as K;\n }\n\n if (keyA !== undefined && keyA !== null && keyB !== undefined && keyB !== null) {\n return this.comparator(keyA, keyB);\n }\n return 0;\n });\n\n const _dfs = (arr: { key: R | BTNKeyOrNodeOrEntry<K, V, NODE>; value: V | undefined; orgIndex: number }[]) => {\n if (arr.length === 0) return;\n\n const mid = Math.floor((arr.length - 1) / 2);\n const { key, value, orgIndex } = arr[mid];\n inserted[orgIndex] = this.add(key, value);\n _dfs(arr.slice(0, mid));\n _dfs(arr.slice(mid + 1));\n };\n\n const _iterate = () => {\n const n = sorted.length;\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const { key, value, orgIndex } = sorted[m];\n inserted[orgIndex] = this.add(key, value);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n };\n\n if (iterationType === 'RECURSIVE') {\n _dfs(sorted);\n } else {\n _iterate();\n }\n\n return inserted;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(k + log n)\n *\n * The function `getNodes` in TypeScript overrides the base class method to retrieve nodes based on a\n * given predicate and iteration type.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter in the `getNodes` method is used to filter the nodes that will be returned. It can be a\n * key, a node, an entry, or a custom predicate function that determines whether a node should be\n * included in the result.\n * @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` method is a boolean flag that\n * determines whether to return only the first node that matches the predicate (`true`) or all nodes\n * that match the predicate (`false`). If `onlyOne` is set to `true`, the method will stop iterating\n * and\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the\n * `getNodes` method is used to specify the starting point for traversing the tree when searching for\n * nodes that match a given predicate. It represents the root node of the subtree where the search\n * should begin. If not explicitly provided, the default value for `begin\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` method\n * specifies the type of iteration to be performed when traversing the nodes of a binary tree. It can\n * have two possible values:\n * @returns The `getNodes` method returns an array of nodes that satisfy the given predicate.\n */\n override getNodes(\n predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n onlyOne = false,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): NODE[] {\n if (predicate === undefined) return [];\n if (predicate === null) return [];\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const callback = this._ensurePredicate(predicate);\n const ans: NODE[] = [];\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return;\n }\n\n if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;\n if (this.isKey(predicate)) {\n if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) dfs(cur.left);\n if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) dfs(cur.right);\n } else {\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n }\n };\n\n dfs(beginRoot);\n } else {\n const stack = [beginRoot];\n while (stack.length > 0) {\n const cur = stack.pop()!;\n if (callback(cur)) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n if (this.isKey(predicate)) {\n if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) stack.push(cur.right);\n if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) stack.push(cur.left);\n } else {\n if (this.isRealNode(cur.right)) stack.push(cur.right);\n if (this.isRealNode(cur.left)) stack.push(cur.left);\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * This function retrieves a node based on a given predicate within a binary search tree structure.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`\n * parameter can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>`, `R`, or `BTNPredicate<NODE>`.\n * @param {R | BSTNKeyOrNode<K, NODE>} beginRoot - The `beginRoot` parameter in the `getNode` method\n * is used to specify the starting point for searching nodes in the binary search tree. If no\n * specific starting point is provided, the default value is set to `this._root`, which is the root\n * node of the binary search tree.\n * @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is a\n * parameter that specifies the type of iteration to be used. It has a default value of\n * `this.iterationType`, which means it will use the iteration type defined in the class instance if\n * no value is provided when calling the method.\n * @returns The `getNode` method is returning an optional binary search tree node (`OptBSTN<NODE>`).\n * It is using the `getNodes` method to find the node based on the provided predicate, beginning at\n * the specified root node (`beginRoot`) and using the specified iteration type. The method then\n * returns the first node found or `undefined` if no node is found.\n */\n override getNode(\n predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,\n beginRoot: R | BSTNKeyOrNode<K, NODE> = this._root,\n iterationType: IterationType = this.iterationType\n ): OptBSTN<NODE> {\n return this.getNodes(predicate, true, beginRoot, iterationType)[0] ?? undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getNodeByKey` returns a node with a specific key from a tree data structure.\n * @param {K} key - The key parameter is the value used to search for a specific node in the tree. It\n * is typically a unique identifier or a value that can be used to determine the position of the node\n * in the tree structure.\n * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional\n * parameter that specifies the type of iteration to be used when searching for a node in the tree.\n * It has a default value of `'ITERATIVE'`.\n * @returns The method is returning a NODE object or undefined.\n */\n override getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptBSTN<NODE> {\n return this.getNode(key, this._root, iterationType);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the depth-first search method and returns an array of the return types of\n * the callback function.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * during the depth-first search traversal. It is an optional parameter and defaults to\n * `this._DEFAULT_BTN_CALLBACK`. The type `C` represents the type of the callback function.\n * @param {DFSOrderPattern} [pattern=IN] - The \"pattern\" parameter in the code snippet refers to the\n * order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can\n * take one of the following values:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for the depth-first search traversal. It can be either a root node, a key-value pair, or a\n * node entry. If not specified, the default value is the root of the tree.\n * @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the\n * type of iteration to be used during the Depth-First Search (DFS) traversal. It can have one of the\n * following values:\n * @returns The method is returning an array of the return type of the callback function.\n */\n override dfs<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n pattern: DFSOrderPattern = 'IN',\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n return super.dfs(callback, pattern, beginRoot, iterationType);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the breadth-first search method and returns an array of the return types of\n * the callback function.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * visited during the breadth-first search. It should take a single argument, which is the current\n * node being visited, and it can return a value of any type.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for the breadth-first search. It can be either a root node, a key-value pair, or an entry\n * object. If no value is provided, the default value is the root of the tree.\n * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type\n * of iteration to be performed during the breadth-first search (BFS) traversal. It can have one of\n * the following values:\n * @returns an array of the return type of the callback function.\n */\n override bfs<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n return super.bfs(callback, beginRoot, iterationType, false);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the listLevels method from the superclass and returns an array of arrays\n * containing the results of the callback function applied to each level of the tree.\n * @param {C} callback - The `callback` parameter is a generic type `C` that extends\n * `BTNCallback<NODE>`. It represents a callback function that will be called for each node in the\n * tree during the iteration process.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting\n * point for listing the levels of the binary tree. It can be either a root node of the tree, a\n * key-value pair representing a node in the tree, or a key representing a node in the tree. If no\n * value is provided, the root of\n * @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type\n * of iteration to be performed on the tree. It can have one of the following values:\n * @returns The method is returning a two-dimensional array of the return type of the callback\n * function.\n */\n override listLevels<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[][] {\n return super.listLevels(callback, beginRoot, iterationType, false);\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `lesserOrGreaterTraverse` function traverses a binary tree and applies a callback function to\n * each node that meets a certain condition based on a target node and a comparison value.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * that meets the condition specified by the `lesserOrGreater` parameter. It takes a single argument,\n * which is the current node being traversed, and returns a value of any type.\n * @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to\n * traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,\n * 0, or 1, where:\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} targetNode - The `targetNode` parameter is the node in\n * the binary tree that you want to start traversing from. It can be specified either by providing\n * the key of the node, the node itself, or an entry containing the key and value of the node. If no\n * `targetNode` is provided,\n * @param {IterationType} iterationType - The `iterationType` parameter determines the type of\n * traversal to be performed on the binary tree. It can have two possible values:\n * @returns The function `lesserOrGreaterTraverse` returns an array of values of type\n * `ReturnType<C>`, which is the return type of the callback function passed as an argument.\n */\n lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(\n callback: C = this._DEFAULT_BTN_CALLBACK as C,\n lesserOrGreater: CP = -1,\n targetNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,\n iterationType: IterationType = this.iterationType\n ): ReturnType<C>[] {\n const targetNodeEnsured = this.ensureNode(targetNode);\n const ans: ReturnType<BTNCallback<NODE>>[] = [];\n if (!this._root) return ans;\n if (!targetNodeEnsured) return ans;\n\n const targetKey = targetNodeEnsured.key;\n\n if (iterationType === 'RECURSIVE') {\n const dfs = (cur: NODE) => {\n const compared = this.comparator(cur.key, targetKey);\n if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));\n\n if (this.isRealNode(cur.left)) dfs(cur.left);\n if (this.isRealNode(cur.right)) dfs(cur.right);\n };\n\n dfs(this._root);\n return ans;\n } else {\n const queue = new Queue<NODE>([this._root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (this.isRealNode(cur)) {\n const compared = this.comparator(cur.key, targetKey);\n if (Math.sign(compared) === lesserOrGreater) ans.push(callback(cur));\n\n if (this.isRealNode(cur.left)) queue.push(cur.left);\n if (this.isRealNode(cur.right)) queue.push(cur.right);\n }\n }\n return ans;\n }\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `perfectlyBalance` function takes an optional `iterationType` parameter and returns `true` if\n * the binary search tree is perfectly balanced, otherwise it returns `false`.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when building a balanced binary search tree. It has a\n * default value of `this.iterationType`, which means it will use the iteration type specified in the\n * current instance of the class.\n * @returns The function `perfectlyBalance` returns a boolean value.\n */\n perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {\n const sorted = this.dfs(node => node, 'IN'),\n n = sorted.length;\n this.clear();\n\n if (sorted.length < 1) return false;\n if (iterationType === 'RECURSIVE') {\n const buildBalanceBST = (l: number, r: number) => {\n if (l > r) return;\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add([midNode.key, midNode.value]);\n buildBalanceBST(l, m - 1);\n buildBalanceBST(m + 1, r);\n };\n\n buildBalanceBST(0, n - 1);\n return true;\n } else {\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add([midNode.key, midNode.value]);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n return true;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `isAVLBalanced` checks if a binary tree is AVL balanced using either a recursive or\n * iterative approach.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when checking if the AVL tree is balanced. It has a default\n * value of `this.iterationType`, which means it will use the iteration type specified in the current\n * instance of the AVL tree.\n * @returns a boolean value.\n */\n isAVLBalanced(iterationType: IterationType = this.iterationType): boolean {\n if (!this._root) return true;\n\n let balanced = true;\n\n if (iterationType === 'RECURSIVE') {\n const _height = (cur: OptBSTN<NODE>): number => {\n if (!cur) return 0;\n const leftHeight = _height(cur.left),\n rightHeight = _height(cur.right);\n if (Math.abs(leftHeight - rightHeight) > 1) balanced = false;\n return Math.max(leftHeight, rightHeight) + 1;\n };\n _height(this._root);\n } else {\n const stack: NODE[] = [];\n let node: OptBSTN<NODE> = this._root,\n last: OptBSTN<NODE> = undefined;\n const depths: Map<NODE, number> = new Map();\n\n while (stack.length > 0 || node) {\n if (node) {\n stack.push(node);\n node = node.left;\n } else {\n node = stack[stack.length - 1];\n if (!node.right || last === node.right) {\n node = stack.pop();\n if (node) {\n const left = node.left ? depths.get(node.left)! : -1;\n const right = node.right ? depths.get(node.right)! : -1;\n if (Math.abs(left - right) > 1) return false;\n depths.set(node, 1 + Math.max(left, right));\n last = node;\n node = undefined;\n }\n } else node = node.right;\n }\n }\n }\n\n return balanced;\n }\n\n protected _DEFAULT_COMPARATOR = (a: K, b: K): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a > b) return 1;\n if (a < b) return -1;\n return 0;\n };\n\n protected _comparator: Comparator<K> = this._DEFAULT_COMPARATOR;\n\n /**\n * The function returns the value of the _comparator property.\n * @returns The `_comparator` property is being returned.\n */\n get comparator() {\n return this._comparator;\n }\n\n /**\n * The function sets the root of a tree-like structure and updates the parent property of the new\n * root.\n * @param {OptBSTN<NODE>} v - v is a parameter of type NODE or undefined.\n */\n protected override _setRoot(v: OptBSTN<NODE>) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport { getMSB } from '../../utils';\n\nexport class BinaryIndexedTree {\n protected readonly _freq: number;\n protected readonly _max: number;\n\n /**\n * The constructor initializes the properties of an object, including default frequency, maximum\n * value, a freqMap data structure, the most significant bit, and the count of negative frequencies.\n * @param - - `frequency`: The default frequency value. It is optional and has a default\n * value of 0.\n */\n constructor({ frequency = 0, max }: { frequency?: number; max: number }) {\n this._freq = frequency;\n this._max = max;\n this._freqMap = { 0: 0 };\n this._msb = getMSB(max);\n this._negativeCount = frequency < 0 ? max : 0;\n }\n\n protected _freqMap: Record<number, number>;\n\n /**\n * The function returns the frequency map of numbers.\n * @returns The `_freqMap` property, which is a record with number keys and number values, is being\n * returned.\n */\n get freqMap(): Record<number, number> {\n return this._freqMap;\n }\n\n protected _msb: number;\n\n /**\n * The function returns the value of the _msb property.\n * @returns The `_msb` property of the object.\n */\n get msb(): number {\n return this._msb;\n }\n\n protected _negativeCount: number;\n\n /**\n * The function returns the value of the _negativeCount property.\n * @returns The method is returning the value of the variable `_negativeCount`, which is of type\n * `number`.\n */\n get negativeCount(): number {\n return this._negativeCount;\n }\n\n /**\n * The above function returns the value of the protected variable `_freq`.\n * @returns The frequency value stored in the protected variable `_freq`.\n */\n get freq(): number {\n return this._freq;\n }\n\n /**\n * The above function returns the maximum value.\n * @returns The maximum value stored in the variable `_max`.\n */\n get max(): number {\n return this._max;\n }\n\n /**\n * The function \"readSingle\" reads a single number from a specified index.\n * @param {number} index - The `index` parameter is a number that represents the index of an element in a\n * collection or array.\n * @returns a number.\n */\n readSingle(index: number): number {\n this._checkIndex(index);\n return this._readSingle(index);\n }\n\n /**\n * The \"update\" function updates the value at a given index by adding a delta and triggers a callback\n * to notify of the change.\n * @param {number} position - The `index` parameter represents the index of the element that needs to be\n * updated in the data structure.\n * @param {number} change - The \"delta\" parameter represents the change in value that needs to be\n * applied to the frequency at the specified index.\n */\n update(position: number, change: number): void {\n this._checkIndex(position);\n const freqCur = this._readSingle(position);\n\n this._update(position, change);\n this._updateNegativeCount(freqCur, freqCur + change);\n }\n\n /**\n * The function \"writeSingle\" checks the index and writes a single value with a given frequency.\n * @param {number} index - The `index` parameter is a number that represents the index of an element. It\n * is used to identify the specific element that needs to be written.\n * @param {number} freq - The `freq` parameter represents the frequency value that needs to be\n * written.\n */\n writeSingle(index: number, freq: number): void {\n this._checkIndex(index);\n this._writeSingle(index, freq);\n }\n\n /**\n * The read function takes a count parameter, checks if it is an integer, and returns the result of\n * calling the _read function with the count parameter clamped between 0 and the maximum value.\n * @param {number} count - The `count` parameter is a number that represents the number of items to\n * read.\n * @returns a number.\n */\n read(count: number): number {\n if (!Number.isInteger(count)) {\n throw new Error('Invalid count');\n }\n return this._read(Math.max(Math.min(count, this.max), 0));\n }\n\n /**\n * The function returns the lower bound of a non-descending sequence that sums up to a given number.\n * @param {number} sum - The `sum` parameter is a number that represents the target sum that we want\n * to find in the sequence.\n * @returns The lowerBound function is returning a number.\n */\n lowerBound(sum: number): number {\n if (this.negativeCount > 0) {\n throw new Error('Sequence is not non-descending');\n }\n return this._binarySearch(sum, (x, y) => x < y);\n }\n\n /**\n * The upperBound function returns the index of the first element in a sequence that is greater than\n * or equal to a given sum.\n * @param {number} sum - The \"sum\" parameter is a number that represents the target sum that we want\n * to find in the sequence.\n * @returns The upperBound function is returning a number.\n */\n upperBound(sum: number): number {\n if (this.negativeCount > 0) {\n throw new Error('Must not be descending');\n }\n return this._binarySearch(sum, (x, y) => x <= y);\n }\n\n /**\n * The function calculates the prefix sum of an array using a binary indexed tree.\n * @param {number} i - The parameter \"i\" in the function \"getPrefixSum\" represents the index of the element in the\n * array for which we want to calculate the prefix sum.\n * @returns The function `getPrefixSum` returns the prefix sum of the elements in the binary indexed tree up to index\n * `i`.\n */\n getPrefixSum(i: number): number {\n this._checkIndex(i);\n i++; // Convert to 1-based index\n\n let sum = 0;\n while (i > 0) {\n sum += this._getFrequency(i);\n i -= i & -i;\n }\n\n return sum;\n }\n\n /**\n * The function returns the value of a specific index in a freqMap data structure, or a default value if\n * the index is not found.\n * @param {number} index - The `index` parameter is a number that represents the index of a node in a\n * freqMap data structure.\n * @returns a number.\n */\n protected _getFrequency(index: number): number {\n if (index in this.freqMap) {\n return this.freqMap[index];\n }\n\n return this.freq * (index & -index);\n }\n\n /**\n * The function _updateFrequency adds a delta value to the element at the specified index in the freqMap array.\n * @param {number} index - The index parameter is a number that represents the index of the freqMap\n * element that needs to be updated.\n * @param {number} delta - The `delta` parameter represents the change in value that needs to be\n * added to the freqMap at the specified `index`.\n */\n protected _updateFrequency(index: number, delta: number): void {\n this.freqMap[index] = this._getFrequency(index) + delta;\n }\n\n /**\n * The function checks if the given index is valid and within the range.\n * @param {number} index - The parameter \"index\" is of type number and represents the index value\n * that needs to be checked.\n */\n protected _checkIndex(index: number): void {\n if (!Number.isInteger(index)) {\n throw new Error('Invalid index: Index must be an integer.');\n }\n if (index < 0 || index >= this.max) {\n throw new Error('Index out of range: Index must be within the range [0, this.max).');\n }\n }\n\n /**\n * The function calculates the sum of elements in an array up to a given index using a binary indexed\n * freqMap.\n * @param {number} index - The `index` parameter is a number that represents the index of an element in a\n * data structure.\n * @returns a number.\n */\n protected _readSingle(index: number): number {\n index = index + 1;\n let sum = this._getFrequency(index);\n const z = index - (index & -index);\n\n index--;\n\n while (index !== z) {\n sum -= this._getFrequency(index);\n index -= index & -index;\n }\n\n return sum;\n }\n\n /**\n * The function `_updateNegativeCount` updates a counter based on changes in frequency values.\n * @param {number} freqCur - The current frequency value.\n * @param {number} freqNew - The freqNew parameter represents the new frequency value.\n */\n protected _updateNegativeCount(freqCur: number, freqNew: number): void {\n if (freqCur < 0 && freqNew >= 0) {\n this._negativeCount--;\n } else if (freqCur >= 0 && freqNew < 0) {\n this._negativeCount++;\n }\n }\n\n /**\n * The `_update` function updates the values in a binary indexed freqMap starting from a given index and\n * propagating the changes to its parent nodes.\n * @param {number} index - The `index` parameter is a number that represents the index of the element in\n * the data structure that needs to be updated.\n * @param {number} delta - The `delta` parameter represents the change in value that needs to be\n * applied to the elements in the data structure.\n */\n protected _update(index: number, delta: number): void {\n index = index + 1;\n\n while (index <= this.max) {\n this._updateFrequency(index, delta);\n index += index & -index;\n }\n }\n\n /**\n * The `_writeSingle` function updates the frequency at a specific index and triggers a callback if\n * the frequency has changed.\n * @param {number} index - The `index` parameter is a number that represents the index of the element\n * being modified or accessed.\n * @param {number} freq - The `freq` parameter represents the new frequency value that needs to be\n * written to the specified index `index`.\n */\n protected _writeSingle(index: number, freq: number): void {\n const freqCur = this._readSingle(index);\n\n this._update(index, freq - freqCur);\n this._updateNegativeCount(freqCur, freq);\n }\n\n /**\n * The `_read` function calculates the sum of values in a binary freqMap up to a given count.\n * @param {number} count - The `count` parameter is a number that represents the number of elements\n * to read from the freqMap.\n * @returns the sum of the values obtained from calling the `_getFrequency` method for each index in the\n * range from `count` to 1.\n */\n protected _read(count: number): number {\n let index = count;\n let sum = 0;\n while (index) {\n sum += this._getFrequency(index);\n index -= index & -index;\n }\n\n return sum;\n }\n\n /**\n * The function `_binarySearch` performs a binary search to find the largest number that satisfies a given\n * condition.\n * @param {number} sum - The sum parameter is a number that represents the target sum value.\n * @param before - The `before` parameter is a function that takes two numbers `x` and `y` as\n * arguments and returns a boolean value. It is used to determine if `x` is less than or equal to\n * `y`. The purpose of this function is to compare two numbers and determine their order.\n * @returns the value of the variable \"left\".\n */\n protected _binarySearch(sum: number, before: (x: number, y: number) => boolean): number {\n let left = 0;\n let right = this.msb << 1;\n let sumT = sum;\n\n while (right > left + 1) {\n const middle = (left + right) >> 1;\n const sumM = this._getFrequency(middle);\n\n if (middle <= this.max && before(sumM, sumT)) {\n sumT -= sumM;\n left = middle;\n } else {\n right = middle;\n }\n }\n return left;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type { SegmentTreeNodeVal } from '../../types';\n\nexport class SegmentTreeNode {\n /**\n * The constructor initializes the properties of a SegmentTreeNode object.\n * @param {number} start - The `start` parameter represents the starting index of the segment covered\n * by this node in a segment tree.\n * @param {number} end - The `end` parameter represents the end index of the segment covered by this\n * node in a segment tree.\n * @param {number} sum - The `sum` parameter represents the sum of the values in the range covered by\n * the segment tree node.\n * @param {SegmentTreeNodeVal | undefined} [value] - The `value` parameter is an optional parameter\n * of type `SegmentTreeNodeVal`. It represents the value associated with the segment tree node.\n */\n constructor(start: number, end: number, sum: number, value?: SegmentTreeNodeVal | undefined) {\n this._start = start;\n this._end = end;\n this._sum = sum;\n this._value = value || undefined;\n }\n\n protected _start = 0;\n\n /**\n * The function returns the value of the protected variable _start.\n * @returns The start value, which is of type number.\n */\n get start(): number {\n return this._start;\n }\n\n /**\n * The above function sets the value of the \"start\" property.\n * @param {number} value - The value parameter is of type number.\n */\n set start(value: number) {\n this._start = value;\n }\n\n protected _end = 0;\n\n /**\n * The function returns the value of the protected variable `_end`.\n * @returns The value of the protected property `_end`.\n */\n get end(): number {\n return this._end;\n }\n\n /**\n * The above function sets the value of the \"end\" property.\n * @param {number} value - The value parameter is a number that represents the new value for the end\n * property.\n */\n set end(value: number) {\n this._end = value;\n }\n\n protected _value: SegmentTreeNodeVal | undefined = undefined;\n\n /**\n * The function returns the value of a segment tree node.\n * @returns The value being returned is either a `SegmentTreeNodeVal` object or `undefined`.\n */\n get value(): SegmentTreeNodeVal | undefined {\n return this._value;\n }\n\n /**\n * The function sets the value of a segment tree node.\n * @param {SegmentTreeNodeVal | undefined} value - The `value` parameter is of type\n * `SegmentTreeNodeVal` or `undefined`.\n */\n set value(value: SegmentTreeNodeVal | undefined) {\n this._value = value;\n }\n\n protected _sum = 0;\n\n /**\n * The function returns the value of the sum property.\n * @returns The method is returning the value of the variable `_sum`.\n */\n get sum(): number {\n return this._sum;\n }\n\n /**\n * The above function sets the value of the sum property.\n * @param {number} value - The parameter \"value\" is of type \"number\".\n */\n set sum(value: number) {\n this._sum = value;\n }\n\n protected _left: SegmentTreeNode | undefined = undefined;\n\n /**\n * The function returns the left child of a segment tree node.\n * @returns The `left` property of the `SegmentTreeNode` object is being returned. It is of type\n * `SegmentTreeNode` or `undefined`.\n */\n get left(): SegmentTreeNode | undefined {\n return this._left;\n }\n\n /**\n * The function sets the value of the left property of a SegmentTreeNode object.\n * @param {SegmentTreeNode | undefined} value - The value parameter is of type SegmentTreeNode or\n * undefined.\n */\n set left(value: SegmentTreeNode | undefined) {\n this._left = value;\n }\n\n protected _right: SegmentTreeNode | undefined = undefined;\n\n /**\n * The function returns the right child of a segment tree node.\n * @returns The `getRight()` method is returning a value of type `SegmentTreeNode` or `undefined`.\n */\n get right(): SegmentTreeNode | undefined {\n return this._right;\n }\n\n /**\n * The function sets the right child of a segment tree node.\n * @param {SegmentTreeNode | undefined} value - The `value` parameter is of type `SegmentTreeNode |\n * undefined`. This means that it can accept either a `SegmentTreeNode` object or `undefined` as its\n * value.\n */\n set right(value: SegmentTreeNode | undefined) {\n this._right = value;\n }\n}\n\nexport class SegmentTree {\n /**\n * The constructor initializes the values, start, end, and root properties of an object.\n * @param {number[]} values - An array of numbers that will be used to build a binary search tree.\n * @param {number} [start] - The `start` parameter is the index of the first element in the `values` array that should\n * be included in the range. If no value is provided for `start`, it defaults to 0, which means the range starts from\n * the beginning of the array.\n * @param {number} [end] - The \"end\" parameter is the index of the last element in the \"values\" array that should be\n * included in the range. If not provided, it defaults to the index of the last element in the \"values\" array.\n */\n constructor(values: number[], start?: number, end?: number) {\n start = start || 0;\n end = end || values.length - 1;\n this._values = values;\n this._start = start;\n this._end = end;\n\n if (values.length > 0) {\n this._root = this.build(start, end);\n } else {\n this._root = undefined;\n this._values = [];\n }\n }\n\n protected _values: number[] = [];\n\n /**\n * The function returns an array of numbers.\n * @returns An array of numbers is being returned.\n */\n get values(): number[] {\n return this._values;\n }\n\n protected _start = 0;\n\n /**\n * The function returns the value of the protected variable _start.\n * @returns The start value, which is of type number.\n */\n get start(): number {\n return this._start;\n }\n\n protected _end: number;\n\n /**\n * The function returns the value of the protected variable `_end`.\n * @returns The value of the protected property `_end`.\n */\n get end(): number {\n return this._end;\n }\n\n protected _root: SegmentTreeNode | undefined;\n\n /**\n * The function returns the root node of a segment tree.\n * @returns The `root` property of the class `SegmentTreeNode` or `undefined` if it is not defined.\n */\n get root(): SegmentTreeNode | undefined {\n return this._root;\n }\n\n /**\n * The build function creates a segment tree by recursively dividing the given range into smaller segments and assigning\n * the sum of values to each segment.\n * @param {number} start - The `start` parameter represents the starting index of the segment or range for which we are\n * building the segment tree.\n * @param {number} end - The \"end\" parameter represents the ending index of the segment or range for which we want to\n * build a segment tree.\n * @returns a SegmentTreeNode object.\n */\n build(start: number, end: number): SegmentTreeNode {\n if (start > end) {\n return new SegmentTreeNode(start, end, 0);\n }\n if (start === end) return new SegmentTreeNode(start, end, this._values[start]);\n\n const mid = start + Math.floor((end - start) / 2);\n const left = this.build(start, mid);\n const right = this.build(mid + 1, end);\n const cur = new SegmentTreeNode(start, end, left.sum + right.sum);\n cur.left = left;\n cur.right = right;\n return cur;\n }\n\n /**\n * The function updates the value of a node in a segment tree and recalculates the sum of its children if they exist.\n * @param {number} index - The index parameter represents the index of the node in the segment tree that needs to be\n * updated.\n * @param {number} sum - The `sum` parameter represents the new value that should be assigned to the `sum` property of\n * the `SegmentTreeNode` at the specified `index`.\n * @param {SegmentTreeNodeVal} [value] - The `value` parameter is an optional value that can be assigned to the `value`\n * property of the `SegmentTreeNode` object. It is not currently used in the code, but you can uncomment the line `//\n * cur.value = value;` and pass a value for `value` in the\n * @returns The function does not return anything.\n */\n updateNode(index: number, sum: number, value?: SegmentTreeNodeVal) {\n const root = this.root || undefined;\n if (!root) {\n return;\n }\n const dfs = (cur: SegmentTreeNode, index: number, sum: number, value?: SegmentTreeNodeVal) => {\n if (cur.start === cur.end && cur.start === index) {\n cur.sum = sum;\n if (value !== undefined) cur.value = value;\n return;\n }\n const mid = cur.start + Math.floor((cur.end - cur.start) / 2);\n if (index <= mid) {\n if (cur.left) {\n dfs(cur.left, index, sum, value);\n }\n } else {\n if (cur.right) {\n dfs(cur.right, index, sum, value);\n }\n }\n if (cur.left && cur.right) {\n cur.sum = cur.left.sum + cur.right.sum;\n }\n };\n\n dfs(root, index, sum, value);\n }\n\n /**\n * The function `querySumByRange` calculates the sum of values within a given range in a segment tree.\n * @param {number} indexA - The starting index of the range for which you want to calculate the sum.\n * @param {number} indexB - The parameter `indexB` represents the ending index of the range for which you want to\n * calculate the sum.\n * @returns The function `querySumByRange` returns a number.\n */\n querySumByRange(indexA: number, indexB: number): number {\n const root = this.root || undefined;\n if (!root) {\n return 0;\n }\n\n if (indexA < 0 || indexB >= this.values.length || indexA > indexB) {\n return NaN;\n }\n\n const dfs = (cur: SegmentTreeNode, i: number, j: number): number => {\n if (i <= cur.start && j >= cur.end) {\n // The range [i, j] completely covers the current node's range [cur.start, cur.end]\n return cur.sum;\n }\n const mid = cur.start + Math.floor((cur.end - cur.start) / 2);\n if (j <= mid) {\n if (cur.left) {\n return dfs(cur.left, i, j);\n } else {\n return NaN;\n }\n } else if (i > mid) {\n if (cur.right) {\n return dfs(cur.right, i, j);\n } else {\n return NaN;\n }\n } else {\n // Query both left and right subtrees\n let leftSum = 0;\n let rightSum = 0;\n if (cur.left) {\n leftSum = dfs(cur.left, i, mid);\n }\n if (cur.right) {\n rightSum = dfs(cur.right, mid + 1, j);\n }\n return leftSum + rightSum;\n }\n };\n return dfs(root, indexA, indexB);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport { BST, BSTNode } from './bst';\nimport type {\n AVLTreeNested,\n AVLTreeNodeNested,\n AVLTreeOptions,\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNKeyOrNodeOrEntry,\n BTNEntry\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class AVLTreeNode<\n K = any,\n V = any,\n NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNodeNested<K, V>\n> extends BSTNode<K, V, NODE> {\n /**\n * The constructor function initializes a new instance of a class with a key and an optional value,\n * and sets the height property to 0.\n * @param {K} key - The \"key\" parameter is of type K, which represents the type of the key for the\n * constructor. It is used to initialize the key property of the object being created.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It represents the\n * value associated with the key in the constructor.\n */\n constructor(key: K, value?: V) {\n super(key, value);\n this._height = 0;\n }\n\n protected _height: number;\n\n /**\n * The function returns the value of the height property.\n * @returns The height of the object.\n */\n get height(): number {\n return this._height;\n }\n\n /**\n * The above function sets the value of the height property.\n * @param {number} value - The value parameter is a number that represents the new height value to be\n * set.\n */\n set height(value: number) {\n this._height = value;\n }\n}\n\n/**\n * 1. Height-Balanced: Each node's left and right subtrees differ in height by no more than one.\n * 2. Automatic Rebalancing: AVL trees rebalance themselves automatically during insertions and deletions.\n * 3. Rotations for Balancing: Utilizes rotations (single or double) to maintain balance after updates.\n * 4. Order Preservation: Maintains the binary search tree property where left child values are less than the parent, and right child values are greater.\n * 5. Efficient Lookups: Offers O(log n) search time, where 'n' is the number of nodes, due to its balanced nature.\n * 6. Complex Insertions and Deletions: Due to rebalancing, these operations are more complex than in a regular BST.\n * 7. Path Length: The path length from the root to any leaf is longer compared to an unbalanced BST, but shorter than a linear chain of nodes.\n */\nexport class AVLTree<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends AVLTreeNode<K, V, NODE> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>,\n TREE extends AVLTree<K, V, R, NODE, TREE> = AVLTree<K, V, R, NODE, AVLTreeNested<K, V, R, NODE>>\n >\n extends BST<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * This is a constructor function for an AVLTree class that initializes the tree with keys, nodes,\n * entries, or raw elements.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable object that can contain either keys, nodes, entries, or raw elements. These elements will\n * be used to initialize the AVLTree.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the AVLTree. It can include properties such as `compareFn` (a function used to compare\n * keys), `allowDuplicates` (a boolean indicating whether duplicate keys are allowed), and\n * `nodeBuilder` (\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: AVLTreeOptions<K, V, R>\n ) {\n super([], options);\n if (keysOrNodesOrEntriesOrRaws) super.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n /**\n * The function creates a new AVL tree node with the given key and value.\n * @param {K} key - The key parameter is of type K, which represents the key of the node being\n * created.\n * @param {V} [value] - The \"value\" parameter is an optional parameter of type V. It represents the\n * value associated with the key in the node being created.\n * @returns The method is returning a new instance of the AVLTreeNode class, casted as the generic\n * type NODE.\n */\n override createNode(key: K, value?: V): NODE {\n return new AVLTreeNode<K, V, NODE>(key, value) as NODE;\n }\n\n /**\n * The function creates a new AVL tree with the specified options and returns it.\n * @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be\n * passed to the `createTree` function. It is used to customize the behavior of the AVL tree that is\n * being created.\n * @returns a new AVLTree object.\n */\n override createTree(options?: AVLTreeOptions<K, V, R>): TREE {\n return new AVLTree<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function checks if the input is an instance of AVLTreeNode.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `AVLTreeNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof AVLTreeNode;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the add method of a class and inserts a key-value pair into a data\n * structure, then balances the path.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept values of type `R`, `BTNKeyOrNodeOrEntry<K, V, NODE>`, or\n * `RawElement`.\n * @param {V} [value] - The `value` parameter is an optional value that you want to associate with\n * the key or node being added to the data structure.\n * @returns The method is returning a boolean value.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n if (keyOrNodeOrEntryOrRaw === null) return false;\n const inserted = super.add(keyOrNodeOrEntryOrRaw, value);\n if (inserted) this._balancePath(keyOrNodeOrEntryOrRaw);\n return inserted;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the delete method in a TypeScript class, performs deletion, and then\n * balances the tree if necessary.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `override delete` method can be one of the following types:\n * @returns The `delete` method is being overridden in this code snippet. It first calls the `delete`\n * method from the superclass (presumably a parent class) with the provided `predicate`, which could\n * be a key, node, entry, or a custom predicate. The result of this deletion operation is stored in\n * `deletedResults`, which is an array of `BinaryTreeDeleteResult` objects.\n */\n override delete(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): BinaryTreeDeleteResult<NODE>[] {\n const deletedResults = super.delete(keyOrNodeOrEntryOrRaw);\n for (const { needBalanced } of deletedResults) {\n if (needBalanced) {\n this._balancePath(needBalanced);\n }\n }\n return deletedResults;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_swapProperties` function swaps the key, value, and height properties between two nodes in a\n * binary search tree.\n * @param {R | BSTNKeyOrNode<K, NODE>} srcNode - The `srcNode` parameter represents either a node\n * object (`NODE`) or a key-value pair (`R`) that is being swapped with another node.\n * @param {R | BSTNKeyOrNode<K, NODE>} destNode - The `destNode` parameter is either an instance of\n * `R` or an instance of `BSTNKeyOrNode<K, NODE>`.\n * @returns The method is returning the `destNodeEnsured` object if both `srcNodeEnsured` and\n * `destNodeEnsured` are truthy. Otherwise, it returns `undefined`.\n */\n protected override _swapProperties(\n srcNode: R | BSTNKeyOrNode<K, NODE>,\n destNode: R | BSTNKeyOrNode<K, NODE>\n ): NODE | undefined {\n const srcNodeEnsured = this.ensureNode(srcNode);\n const destNodeEnsured = this.ensureNode(destNode);\n\n if (srcNodeEnsured && destNodeEnsured) {\n const { key, value, height } = destNodeEnsured;\n const tempNode = this.createNode(key, value);\n\n if (tempNode) {\n tempNode.height = height;\n\n destNodeEnsured.key = srcNodeEnsured.key;\n destNodeEnsured.value = srcNodeEnsured.value;\n destNodeEnsured.height = srcNodeEnsured.height;\n\n srcNodeEnsured.key = tempNode.key;\n srcNodeEnsured.value = tempNode.value;\n srcNodeEnsured.height = tempNode.height;\n }\n\n return destNodeEnsured;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function calculates the balance factor of a node in a binary tree.\n * @param {NODE} node - The parameter \"node\" is of type \"NODE\", which likely represents a node in a\n * binary tree data structure.\n * @returns the balance factor of a given node. The balance factor is calculated by subtracting the\n * height of the left subtree from the height of the right subtree.\n */\n protected _balanceFactor(node: NODE): number {\n if (!node.right)\n // node has no right subtree\n return -node.height;\n else if (!node.left)\n // node has no left subtree\n return +node.height;\n else return node.right.height - node.left.height;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function updates the height of a node in a binary tree based on the heights of its left and\n * right children.\n * @param {NODE} node - The parameter \"node\" represents a node in a binary tree data structure.\n */\n protected _updateHeight(node: NODE): void {\n if (!node.left && !node.right) node.height = 0;\n else if (!node.left) {\n const rightHeight = node.right ? node.right.height : 0;\n node.height = 1 + rightHeight;\n } else if (!node.right) node.height = 1 + node.left.height;\n else node.height = 1 + Math.max(node.right.height, node.left.height);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_balanceLL` function performs a left-left rotation to balance a binary search tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceLL(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.left;\n A.parent = B;\n if (B && B.right) {\n B.right.parent = A;\n }\n if (B) B.parent = parentOfA;\n if (A === this.root) {\n if (B) this._setRoot(B);\n } else {\n if (parentOfA?.left === A) {\n parentOfA.left = B;\n } else {\n if (parentOfA) parentOfA.right = B;\n }\n }\n\n if (B) {\n A.left = B.right;\n B.right = A;\n }\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_balanceLR` function performs a left-right rotation to balance a binary tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceLR(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.left;\n let C = undefined;\n if (B) {\n C = B.right;\n }\n if (A) A.parent = C;\n if (B) B.parent = C;\n\n if (C) {\n if (C.left) {\n C.left.parent = B;\n }\n if (C.right) {\n C.right.parent = A;\n }\n C.parent = parentOfA;\n }\n\n if (A === this.root) {\n if (C) this._setRoot(C);\n } else {\n if (parentOfA) {\n if (parentOfA.left === A) {\n parentOfA.left = C;\n } else {\n parentOfA.right = C;\n }\n }\n }\n\n if (C) {\n A.left = C.right;\n if (B) B.right = C.left;\n C.left = B;\n C.right = A;\n }\n\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n if (C) this._updateHeight(C);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_balanceRR` performs a right-right rotation to balance a binary tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceRR(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.right;\n A.parent = B;\n if (B) {\n if (B.left) {\n B.left.parent = A;\n }\n B.parent = parentOfA;\n }\n\n if (A === this.root) {\n if (B) this._setRoot(B);\n } else {\n if (parentOfA) {\n if (parentOfA.left === A) {\n parentOfA.left = B;\n } else {\n parentOfA.right = B;\n }\n }\n }\n\n if (B) {\n A.right = B.left;\n B.left = A;\n }\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_balanceRL` performs a right-left rotation to balance a binary tree.\n * @param {NODE} A - A is a node in a binary tree.\n */\n protected _balanceRL(A: NODE): void {\n const parentOfA = A.parent;\n const B = A.right;\n let C = undefined;\n if (B) {\n C = B.left;\n }\n\n A.parent = C;\n if (B) B.parent = C;\n\n if (C) {\n if (C.left) {\n C.left.parent = A;\n }\n if (C.right) {\n C.right.parent = B;\n }\n C.parent = parentOfA;\n }\n\n if (A === this.root) {\n if (C) this._setRoot(C);\n } else {\n if (parentOfA) {\n if (parentOfA.left === A) {\n parentOfA.left = C;\n } else {\n parentOfA.right = C;\n }\n }\n }\n\n if (C) A.right = C.left;\n if (B && C) B.left = C.right;\n if (C) C.left = A;\n if (C) C.right = B;\n\n this._updateHeight(A);\n if (B) this._updateHeight(B);\n if (C) this._updateHeight(C);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_balancePath` function is used to update the heights of nodes and perform rotation operations\n * to restore balance in an AVL tree after inserting a node.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} node - The `node` parameter can be of type `R` or\n * `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n */\n protected _balancePath(node: BTNKeyOrNodeOrEntry<K, V, NODE> | R): void {\n node = this.ensureNode(node);\n const path = this.getPathToRoot(node => node, node, false); // first O(log n) + O(log n)\n for (let i = 0; i < path.length; i++) {\n // second O(log n)\n const A = path[i];\n if (A) {\n // Update Heights: After inserting a node, backtrack from the insertion point to the root node, updating the height of each node along the way.\n this._updateHeight(A); // first O(1)\n // Check Balance: Simultaneously with height updates, check if each node violates the balance property of an AVL tree.\n // Balance Restoration: If a balance issue is discovered after inserting a node, it requires balance restoration operations. Balance restoration includes four basic cases where rotation operations need to be performed to fix the balance:\n switch (\n this._balanceFactor(A) // second O(1)\n ) {\n case -2:\n if (A && A.left) {\n if (this._balanceFactor(A.left) <= 0) {\n // second O(1)\n // Left Rotation (LL Rotation): When the inserted node is in the left subtree of the left subtree, causing an imbalance.\n this._balanceLL(A);\n } else {\n // Left-Right Rotation (LR Rotation): When the inserted node is in the right subtree of the left subtree, causing an imbalance.\n this._balanceLR(A);\n }\n }\n break;\n case +2:\n if (A && A.right) {\n if (this._balanceFactor(A.right) >= 0) {\n // Right Rotation (RR Rotation): When the inserted node is in the right subtree of the right subtree, causing an imbalance.\n this._balanceRR(A);\n } else {\n // Right-Left Rotation (RL Rotation): When the inserted node is in the left subtree of the right subtree, causing an imbalance.\n this._balanceRL(A);\n }\n }\n }\n // TODO So far, no sure if this is necessary that Recursive Repair: Once rotation operations are executed, it may cause imbalance issues at higher levels of the tree. Therefore, you need to recursively check and repair imbalance problems upwards until you reach the root node.\n }\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node and sets the height of the new node to be the\n * same as the old node.\n * @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in\n * the data structure.\n * @param {NODE} newNode - The `newNode` parameter is the new node that will replace the `oldNode` in\n * the data structure.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, with the `oldNode` and `newNode` as arguments.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.height = oldNode.height;\n\n return super._replaceNode(oldNode, newNode);\n }\n}\n","import type {\n BinaryTreeDeleteResult,\n BTNKeyOrNodeOrEntry,\n CRUD,\n OptBSTN,\n RBTNColor,\n RBTreeOptions,\n RedBlackTreeNested,\n RedBlackTreeNodeNested,\n BTNEntry\n} from '../../types';\nimport { BST, BSTNode } from './bst';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class RedBlackTreeNode<\n K = any,\n V = any,\n NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNodeNested<K, V>\n> extends BSTNode<K, V, NODE> {\n /**\n * The constructor function initializes a Red-Black Tree Node with a key, an optional value, and a\n * color.\n * @param {K} key - The key parameter is of type K and represents the key of the node in the\n * Red-Black Tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the Red-Black Tree Node. It is not required and can be omitted when\n * creating a new instance of the Red-Black Tree Node.\n * @param {RBTNColor} color - The `color` parameter is used to specify the color of the Red-Black\n * Tree Node. It is an optional parameter with a default value of `'BLACK'`.\n */\n constructor(key: K, value?: V, color: RBTNColor = 'BLACK') {\n super(key, value);\n this._color = color;\n }\n\n protected _color: RBTNColor;\n\n /**\n * The function returns the color value of a variable.\n * @returns The color value stored in the private variable `_color`.\n */\n get color(): RBTNColor {\n return this._color;\n }\n\n /**\n * The function sets the color property to the specified value.\n * @param {RBTNColor} value - The value parameter is of type RBTNColor.\n */\n set color(value: RBTNColor) {\n this._color = value;\n }\n}\n\nexport class RedBlackTree<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends RedBlackTreeNode<K, V, NODE> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>,\n TREE extends RedBlackTree<K, V, R, NODE, TREE> = RedBlackTree<K, V, R, NODE, RedBlackTreeNested<K, V, R, NODE>>\n >\n extends BST<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * This is the constructor function for a Red-Black Tree data structure in TypeScript.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable object that can contain either keys, nodes, entries, or raw elements. It is used to\n * initialize the RBTree with the provided elements.\n * @param [options] - The `options` parameter is an optional object that can be passed to the\n * constructor. It is of type `RBTreeOptions<K, V, R>`. This object can contain various options for\n * configuring the behavior of the Red-Black Tree. The specific properties and their meanings would\n * depend on the implementation\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: RBTreeOptions<K, V, R>\n ) {\n super([], options);\n\n this._root = this.NIL;\n\n if (keysOrNodesOrEntriesOrRaws) {\n this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n }\n\n protected override _root: NODE | undefined;\n\n /**\n * The function returns the root node of a tree or undefined if there is no root.\n * @returns The root node of the tree structure, or undefined if there is no root node.\n */\n override get root(): NODE | undefined {\n return this._root;\n }\n\n /**\n * The function creates a new Red-Black Tree node with the specified key, value, and color.\n * @param {K} key - The key parameter represents the key value of the node being created. It is of\n * type K, which is a generic type that can be replaced with any specific type when using the\n * function.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the node. It is not required and can be omitted if you only need to\n * create a node with a key.\n * @param {RBTNColor} [color=BLACK] - The \"color\" parameter is used to specify the color of the node\n * in a Red-Black Tree. It can have two possible values: \"RED\" or \"BLACK\". By default, the color is\n * set to \"BLACK\" if not specified.\n * @returns A new instance of a RedBlackTreeNode with the specified key, value, and color is being\n * returned.\n */\n override createNode(key: K, value?: V, color: RBTNColor = 'BLACK'): NODE {\n return new RedBlackTreeNode<K, V, NODE>(key, value, color) as NODE;\n }\n\n /**\n * The function creates a new Red-Black Tree with the specified options.\n * @param [options] - The `options` parameter is an optional object that contains additional\n * configuration options for creating the Red-Black Tree. It has the following properties:\n * @returns a new instance of a RedBlackTree object.\n */\n override createTree(options?: RBTreeOptions<K, V, R>): TREE {\n return new RedBlackTree<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function checks if the input is an instance of the RedBlackTreeNode class.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `RedBlackTreeNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof RedBlackTreeNode;\n }\n\n // /**\n // * Time Complexity: O(1)\n // * Space Complexity: O(1)\n // */\n //\n // /**\n // * Time Complexity: O(1)\n // * Space Complexity: O(1)\n // *\n // * The function `keyValueOrEntryOrRawElementToNode` takes a key, value, or entry and returns a node if it is\n // * valid, otherwise it returns undefined.\n // * @param {BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRaw - The key, value, or entry to convert.\n // * @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntryOrRaw` is a key).\n // * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.\n // */\n // override keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): NODE | undefined {\n //\n // if (keyOrNodeOrEntryOrRaw === null || keyOrNodeOrEntryOrRaw === undefined) return;\n // if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n //\n // if (this._toEntryFn) {\n // const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n // if (this.isKey(key)) return this.createNode(key, entryValue ?? value, 'RED');\n // }\n //\n // if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n // const [key, value] = keyOrNodeOrEntryOrRaw;\n // if (key === undefined || key === null) return;\n // else return this.createNode(key, value, 'RED');\n // }\n //\n // if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'RED');\n //\n // return ;\n // }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The \"clear\" function sets the root node of a data structure to a sentinel value and resets the\n * size counter to zero.\n */\n override clear() {\n super.clear();\n this._root = this.NIL;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function adds a new node to a binary search tree and returns true if the node was successfully\n * added.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that you want to associate with\n * the key in the data structure. It represents the value that you want to add or update in the data\n * structure.\n * @returns The method is returning a boolean value. If a new node is successfully added to the tree,\n * the method returns true. If the node already exists and its value is updated, the method also\n * returns true. If the node cannot be added or updated, the method returns false.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);\n if (!this.isRealNode(newNode)) return false;\n\n const insertStatus = this._insert(newNode);\n\n if (insertStatus === 'CREATED') {\n // Ensure the root is black\n if (this.isRealNode(this._root)) {\n this._root.color = 'BLACK';\n } else {\n return false;\n }\n this._size++;\n return true;\n } else return insertStatus === 'UPDATED';\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the delete method in a binary tree data structure to remove a node based on\n * a given predicate and maintain the binary search tree properties.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `keyOrNodeOrEntryOrRaw`\n * parameter in the `override delete` method is used to specify the condition or key based on which a\n * node should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate\n * function that determines which node(s) should be deleted.\n * @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<NODE>`\n * objects. Each object in the array contains information about the deleted node and whether\n * balancing is needed.\n */\n override delete(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): BinaryTreeDeleteResult<NODE>[] {\n if (keyOrNodeOrEntryOrRaw === null) return [];\n\n const results: BinaryTreeDeleteResult<NODE>[] = [];\n let nodeToDelete: OptBSTN<NODE>;\n if (this._isPredicated(keyOrNodeOrEntryOrRaw)) nodeToDelete = this.getNode(keyOrNodeOrEntryOrRaw);\n else\n nodeToDelete = this.isRealNode(keyOrNodeOrEntryOrRaw)\n ? keyOrNodeOrEntryOrRaw\n : this.getNode(keyOrNodeOrEntryOrRaw);\n\n if (!nodeToDelete) {\n return results;\n }\n\n let originalColor = nodeToDelete.color;\n let replacementNode: NODE | undefined;\n\n if (!this.isRealNode(nodeToDelete.left)) {\n replacementNode = nodeToDelete.right;\n this._transplant(nodeToDelete, nodeToDelete.right);\n } else if (!this.isRealNode(nodeToDelete.right)) {\n replacementNode = nodeToDelete.left;\n this._transplant(nodeToDelete, nodeToDelete.left);\n } else {\n const successor = this.getLeftMost(node => node, nodeToDelete.right);\n if (successor) {\n originalColor = successor.color;\n replacementNode = successor.right;\n\n if (successor.parent === nodeToDelete) {\n if (this.isRealNode(replacementNode)) {\n replacementNode.parent = successor;\n }\n } else {\n this._transplant(successor, successor.right);\n successor.right = nodeToDelete.right;\n if (this.isRealNode(successor.right)) {\n successor.right.parent = successor;\n }\n }\n\n this._transplant(nodeToDelete, successor);\n successor.left = nodeToDelete.left;\n if (this.isRealNode(successor.left)) {\n successor.left.parent = successor;\n }\n successor.color = nodeToDelete.color;\n }\n }\n this._size--;\n\n // If the original color was black, fix the tree\n if (originalColor === 'BLACK') {\n this._deleteFixup(replacementNode);\n }\n\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n\n return results;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function sets the root of a tree-like structure and updates the parent property of the new\n * root.\n * @param {NODE | undefined} v - v is a parameter of type NODE or undefined.\n */\n protected override _setRoot(v: NODE | undefined) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node while preserving the color of the old node.\n * @param {NODE} oldNode - The `oldNode` parameter represents the node that needs to be replaced in\n * the data structure.\n * @param {NODE} newNode - The `newNode` parameter is of type `NODE`, which represents a node in a\n * data structure.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, with the `oldNode` and `newNode` parameters.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.color = oldNode.color;\n\n return super._replaceNode(oldNode, newNode);\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_insert` function inserts a node into a binary search tree and performs necessary fix-ups to\n * maintain the red-black tree properties.\n * @param {NODE} node - The `node` parameter represents the node that needs to be inserted into the\n * binary search tree.\n * @returns a string value indicating the result of the insertion operation. It can return either\n * 'UPDATED' if the node with the same key already exists and was updated, or 'CREATED' if a new node\n * was created and inserted into the tree.\n */\n protected _insert(node: NODE): CRUD {\n let current = this.root;\n let parent: NODE | undefined = undefined;\n\n while (this.isRealNode(current)) {\n parent = current;\n const compared = this.comparator(node.key, current.key);\n if (compared < 0) {\n current = current.left ?? this.NIL;\n } else if (compared > 0) {\n current = current.right ?? this.NIL;\n } else {\n this._replaceNode(current, node);\n return 'UPDATED';\n }\n }\n\n node.parent = parent;\n\n if (!parent) {\n this._setRoot(node);\n } else if (node.key < parent.key) {\n parent.left = node;\n } else {\n parent.right = node;\n }\n\n node.left = this.NIL;\n node.right = this.NIL;\n node.color = 'RED';\n\n this._insertFixup(node);\n return 'CREATED';\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function `_transplant` is used to replace a node `u` with another node `v` in a binary tree.\n * @param {NODE} u - The parameter \"u\" represents a node in a binary tree.\n * @param {NODE | undefined} v - The parameter `v` is of type `NODE | undefined`, which means it can\n * either be a `NODE` object or `undefined`.\n */\n protected _transplant(u: NODE, v: NODE | undefined): void {\n if (!u.parent) {\n this._setRoot(v);\n } else if (u === u.parent.left) {\n u.parent.left = v;\n } else {\n u.parent.right = v;\n }\n\n if (v) {\n v.parent = u.parent;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_insertFixup` function is used to fix the Red-Black Tree after inserting a new node.\n * @param {NODE | undefined} z - The parameter `z` represents a node in the Red-Black Tree data\n * structure. It can either be a valid node or `undefined`.\n */\n protected _insertFixup(z: NODE | undefined): void {\n // Continue fixing the tree as long as the parent of z is red\n while (z?.parent?.color === 'RED') {\n // Check if the parent of z is the left child of its parent\n if (z.parent === z.parent.parent?.left) {\n // Case 1: The uncle (y) of z is red\n const y = z.parent.parent.right;\n if (y?.color === 'RED') {\n // Set colors to restore properties of Red-Black Tree\n z.parent.color = 'BLACK';\n y.color = 'BLACK';\n z.parent.parent.color = 'RED';\n // Move up the tree to continue fixing\n z = z.parent.parent;\n } else {\n // Case 2: The uncle (y) of z is black, and z is a right child\n if (z === z.parent.right) {\n // Perform a left rotation to transform the case into Case 3\n z = z.parent;\n this._leftRotate(z);\n }\n\n // Case 3: The uncle (y) of z is black, and z is a left child\n // Adjust colors and perform a right rotation\n if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {\n z.parent.color = 'BLACK';\n z.parent.parent.color = 'RED';\n this._rightRotate(z.parent.parent);\n }\n }\n } else {\n // Symmetric case for the right child (left and right exchanged)\n // Follow the same logic as above with left and right exchanged\n const y: NODE | undefined = z?.parent?.parent?.left;\n if (y?.color === 'RED') {\n z.parent.color = 'BLACK';\n y.color = 'BLACK';\n z.parent.parent!.color = 'RED';\n z = z.parent.parent;\n } else {\n if (z === z.parent.left) {\n z = z.parent;\n this._rightRotate(z);\n }\n\n if (z && this.isRealNode(z.parent) && this.isRealNode(z.parent.parent)) {\n z.parent.color = 'BLACK';\n z.parent.parent.color = 'RED';\n this._leftRotate(z.parent.parent);\n }\n }\n }\n }\n\n // Ensure that the root is black after fixing\n if (this.isRealNode(this._root)) this._root.color = 'BLACK';\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The `_deleteFixup` function is used to fix the red-black tree after a node deletion by adjusting\n * the colors and performing rotations.\n * @param {NODE | undefined} node - The `node` parameter represents a node in a binary tree. It can\n * be either a valid node object or `undefined`.\n * @returns The function does not return any value. It has a return type of `void`, which means it\n * does not return anything.\n */\n protected _deleteFixup(node: NODE | undefined): void {\n // Early exit condition\n if (!node || node === this.root || node.color === 'BLACK') {\n if (node) {\n node.color = 'BLACK'; // Ensure the final node is black\n }\n return;\n }\n\n while (node && node !== this.root && node.color === 'BLACK') {\n const parent: NODE | undefined = node.parent;\n\n if (!parent) {\n break; // Ensure the loop terminates if there's an issue with the tree structure\n }\n\n if (node === parent.left) {\n let sibling = parent.right;\n\n // Cases 1 and 2: Sibling is red or both children of sibling are black\n if (sibling?.color === 'RED') {\n sibling.color = 'BLACK';\n parent.color = 'RED';\n this._leftRotate(parent);\n sibling = parent.right;\n }\n\n // Case 3: Sibling's left child is black\n if ((sibling?.left?.color ?? 'BLACK') === 'BLACK') {\n if (sibling) sibling.color = 'RED';\n node = parent;\n } else {\n // Case 4: Adjust colors and perform a right rotation\n if (sibling?.left) sibling.left.color = 'BLACK';\n if (sibling) sibling.color = parent.color;\n parent.color = 'BLACK';\n this._rightRotate(parent);\n node = this.root;\n }\n } else {\n // Symmetric case for the right child (left and right exchanged)\n let sibling = parent.left;\n\n // Cases 1 and 2: Sibling is red or both children of sibling are black\n if (sibling?.color === 'RED') {\n sibling.color = 'BLACK';\n if (parent) parent.color = 'RED';\n this._rightRotate(parent);\n if (parent) sibling = parent.left;\n }\n\n // Case 3: Sibling's left child is black\n if ((sibling?.right?.color ?? 'BLACK') === 'BLACK') {\n if (sibling) sibling.color = 'RED';\n node = parent;\n } else {\n // Case 4: Adjust colors and perform a left rotation\n if (sibling?.right) sibling.right.color = 'BLACK';\n if (sibling) sibling.color = parent.color;\n if (parent) parent.color = 'BLACK';\n this._leftRotate(parent);\n node = this.root;\n }\n }\n }\n\n // Ensure that the final node (possibly the root) is black\n if (node) {\n node.color = 'BLACK';\n }\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_leftRotate` function performs a left rotation on a given node in a binary tree.\n * @param {NODE | undefined} x - The parameter `x` is of type `NODE | undefined`. It represents a\n * node in a binary tree or `undefined` if there is no node.\n * @returns void, which means it does not return any value.\n */\n protected _leftRotate(x: NODE | undefined): void {\n if (!x || !x.right) {\n return;\n }\n\n const y = x.right;\n x.right = y.left;\n\n if (this.isRealNode(y.left)) {\n y.left.parent = x;\n }\n\n y.parent = x.parent;\n\n if (!x.parent) {\n this._setRoot(y);\n } else if (x === x.parent.left) {\n x.parent.left = y;\n } else {\n x.parent.right = y;\n }\n\n y.left = x;\n x.parent = y;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_rightRotate` function performs a right rotation on a given node in a binary tree.\n * @param {NODE | undefined} y - The parameter `y` is of type `NODE | undefined`. It represents a\n * node in a binary tree or `undefined` if there is no node.\n * @returns void, which means it does not return any value.\n */\n protected _rightRotate(y: NODE | undefined): void {\n if (!y || !y.left) {\n return;\n }\n\n const x = y.left;\n y.left = x.right;\n\n if (this.isRealNode(x.right)) {\n x.right.parent = y;\n }\n\n x.parent = y.parent;\n\n if (!y.parent) {\n this._setRoot(x);\n } else if (y === y.parent.left) {\n y.parent.left = x;\n } else {\n y.parent.right = x;\n }\n\n x.right = y;\n y.parent = x;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n AVLTreeMultiMapNested,\n AVLTreeMultiMapNodeNested,\n AVLTreeMultiMapOptions,\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNKeyOrNodeOrEntry,\n IterationType,\n BTNEntry\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { AVLTree, AVLTreeNode } from './avl-tree';\n\nexport class AVLTreeMultiMapNode<\n K = any,\n V = any,\n NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNodeNested<K, V>\n> extends AVLTreeNode<K, V, NODE> {\n /**\n * The constructor function initializes a BinaryTreeNode object with a key, value, and count.\n * @param {K} key - The `key` parameter is of type `K` and represents the unique identifier\n * of the binary tree node.\n * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the value of the binary\n * tree node. If no value is provided, it will be `undefined`.\n * @param {number} [count=1] - The `count` parameter is a number that represents the number of times a particular value\n * occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`\n * parameter when creating a new instance of the `BinaryTreeNode` class.\n */\n constructor(key: K, value?: V, count = 1) {\n super(key, value);\n this.count = count;\n }\n\n protected _count: number = 1;\n\n /**\n * The function returns the value of the protected variable _count.\n * @returns The count property of the object, which is of type number.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * The above function sets the value of the count property.\n * @param {number} value - The value parameter is of type number, which means it can accept any\n * numeric value.\n */\n set count(value: number) {\n this._count = value;\n }\n}\n\n/**\n * The only distinction between a AVLTreeMultiMap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.\n */\nexport class AVLTreeMultiMap<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends AVLTreeMultiMapNode<K, V, NODE> = AVLTreeMultiMapNode<K, V, AVLTreeMultiMapNodeNested<K, V>>,\n TREE extends AVLTreeMultiMap<K, V, R, NODE, TREE> = AVLTreeMultiMap<\n K,\n V,\n R,\n NODE,\n AVLTreeMultiMapNested<K, V, R, NODE>\n >\n >\n extends AVLTree<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * The constructor initializes a new AVLTreeMultiMap object with optional initial elements.\n * @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an\n * iterable object that can contain either keys, nodes, entries, or raw elements.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the AVLTreeMultiMap. It can include properties such as `compareKeys` and\n * `compareValues` functions to define custom comparison logic for keys and values, respectively.\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: AVLTreeMultiMapOptions<K, V, R>\n ) {\n super([], options);\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected _count = 0;\n\n /**\n * The function calculates the sum of the count property of all nodes in a tree using depth-first\n * search.\n * @returns the sum of the count property of all nodes in the tree.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function calculates the sum of the count property of all nodes in a tree using depth-first\n * search.\n * @returns the sum of the count property of all nodes in the tree.\n */\n getComputedCount(): number {\n let sum = 0;\n this.dfs(node => (sum += node.count));\n return sum;\n }\n\n /**\n * The function creates a new AVLTreeMultiMapNode with the specified key, value, and count.\n * @param {K} key - The key parameter represents the key of the node being created. It is of type K,\n * which is a generic type that can be replaced with any specific type when using the function.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the node. It is of type `V`, which can be any data type.\n * @param {number} [count] - The `count` parameter represents the number of occurrences of a\n * key-value pair in the AVLTreeMultiMapNode. It is an optional parameter, so it can be omitted when\n * calling the `createNode` method. If provided, it specifies the initial count for the node.\n * @returns a new instance of the AVLTreeMultiMapNode class, casted as NODE.\n */\n override createNode(key: K, value?: V, count?: number): NODE {\n return new AVLTreeMultiMapNode(key, value, count) as NODE;\n }\n\n /**\n * The function creates a new AVLTreeMultiMap object with the specified options and returns it.\n * @param [options] - The `options` parameter is an optional object that contains additional\n * configuration options for creating the AVLTreeMultiMap. It can have the following properties:\n * @returns a new instance of the AVLTreeMultiMap class, with the specified options, as a TREE\n * object.\n */\n override createTree(options?: AVLTreeMultiMapOptions<K, V, R>): TREE {\n return new AVLTreeMultiMap<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function checks if the input is an instance of AVLTreeMultiMapNode.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `AVLTreeMultiMapNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof AVLTreeMultiMapNode;\n }\n\n /**\n * The function `keyValueOrEntryOrRawElementToNode` converts a key, value, entry, or raw element into\n * a node object.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyOrNodeOrEntryOrRaw` parameter can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `override` function. It represents the value associated with the key in the data structure. If no\n * value is provided, it will default to `undefined`.\n * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of\n * times the key-value pair should be added to the data structure. If not provided, it defaults to 1.\n * @returns either a NODE object or undefined.\n */\n override keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V,\n count = 1\n ): NODE | undefined {\n if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return;\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const [key, entryValue] = keyOrNodeOrEntryOrRaw;\n if (key === undefined || key === null) return;\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count);\n }\n\n if (this._toEntryFn) {\n const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count);\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, count);\n\n return;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the add method of a TypeScript class to add a new node to a data structure\n * and update the count.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyOrNodeOrEntryOrRaw` parameter can accept a value of type `R`, which can be any type. It\n * can also accept a value of type `BTNKeyOrNodeOrEntry<K, V, NODE>`, which represents a key, node,\n * entry, or raw element\n * @param {V} [value] - The `value` parameter represents the value associated with the key in the\n * data structure. It is an optional parameter, so it can be omitted if not needed.\n * @param [count=1] - The `count` parameter represents the number of times the key-value pair should\n * be added to the data structure. By default, it is set to 1, meaning that the key-value pair will\n * be added once. However, you can specify a different value for `count` if you want to add\n * @returns a boolean value.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V, count = 1): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count);\n if (newNode === undefined) return false;\n\n const orgNodeCount = newNode?.count || 0;\n const inserted = super.add(newNode);\n if (inserted) {\n this._count += orgNodeCount;\n }\n return true;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the delete method in a binary tree data structure, handling deletion of\n * nodes and maintaining balance in the tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `predicate`\n * parameter in the `delete` method is used to specify the condition for deleting a node from the\n * binary tree. It can be a key, node, or entry that determines which\n * node(s) should be deleted.\n * @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a\n * boolean flag that determines whether to ignore the count of the node being deleted. If\n * `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If\n * `ignoreCount` is set to\n * @returns The `delete` method overrides the default delete behavior in a binary tree data\n * structure. It takes a predicate or node to be deleted and an optional flag to ignore count. The\n * method returns an array of `BinaryTreeDeleteResult` objects, each containing information about the\n * deleted node and whether balancing is needed in the tree.\n */\n override delete(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n ignoreCount = false\n ): BinaryTreeDeleteResult<NODE>[] {\n const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];\n if (!this.root) return deletedResult;\n\n const curr: NODE | undefined = this.getNode(keyOrNodeOrEntryOrRaw) ?? undefined;\n if (!curr) return deletedResult;\n\n const parent: NODE | undefined = curr?.parent ? curr.parent : undefined;\n let needBalanced: NODE | undefined = undefined,\n orgCurrent: NODE | undefined = curr;\n\n if (curr.count > 1 && !ignoreCount) {\n curr.count--;\n this._count--;\n } else {\n if (!curr.left) {\n if (!parent) {\n if (curr.right !== undefined) this._setRoot(curr.right);\n } else {\n const { familyPosition: fp } = curr;\n if (fp === 'LEFT' || fp === 'ROOT_LEFT') {\n parent.left = curr.right;\n } else if (fp === 'RIGHT' || fp === 'ROOT_RIGHT') {\n parent.right = curr.right;\n }\n needBalanced = parent;\n }\n } else {\n const leftSubTreeRightMost = curr.left ? this.getRightMost(node => node, curr.left) : undefined;\n if (leftSubTreeRightMost) {\n const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;\n orgCurrent = this._swapProperties(curr, leftSubTreeRightMost);\n if (parentOfLeftSubTreeMax) {\n if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {\n parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;\n } else {\n parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;\n }\n needBalanced = parentOfLeftSubTreeMax;\n }\n }\n }\n this._size = this._size - 1;\n // TODO How to handle when the count of target node is lesser than current node's count\n if (orgCurrent) this._count -= orgCurrent.count;\n }\n\n deletedResult.push({ deleted: orgCurrent, needBalanced });\n\n if (needBalanced) {\n this._balancePath(needBalanced);\n }\n\n return deletedResult;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The \"clear\" function overrides the parent class's \"clear\" function and also resets the count to\n * zero.\n */\n override clear() {\n super.clear();\n this._count = 0;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(log n)\n * The `perfectlyBalance` function takes a sorted array of nodes and builds a balanced binary search\n * tree using either a recursive or iterative approach.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when building the balanced binary search tree. It has a\n * default value of `this.iterationType`, which means it will use the iteration type currently set in\n * the object.\n * @returns The function `perfectlyBalance` returns a boolean value. It returns `true` if the\n * balancing operation is successful, and `false` if there are no nodes to balance.\n */\n override perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {\n const sorted = this.dfs(node => node, 'IN'),\n n = sorted.length;\n if (sorted.length < 1) return false;\n\n this.clear();\n\n if (iterationType === 'RECURSIVE') {\n const buildBalanceBST = (l: number, r: number) => {\n if (l > r) return;\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n buildBalanceBST(l, m - 1);\n buildBalanceBST(m + 1, r);\n };\n\n buildBalanceBST(0, n - 1);\n return true;\n } else {\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n return true;\n }\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the clone method to create a deep copy of a tree object.\n * @returns The `clone()` method is returning a cloned instance of the `TREE` object.\n */\n override clone(): TREE {\n const cloned = this.createTree();\n this.bfs(node => cloned.add(node.key, node.value, node.count));\n return cloned;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_swapProperties` function swaps the properties (key, value, count, height) between two nodes\n * in a binary search tree.\n * @param {R | BSTNKeyOrNode<K, NODE>} srcNode - The `srcNode` parameter represents the source node\n * that will be swapped with the `destNode`.\n * @param {R | BSTNKeyOrNode<K, NODE>} destNode - The `destNode` parameter represents the destination\n * node where the properties will be swapped with the source node.\n * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.\n * If either `srcNode` or `destNode` is undefined, it returns `undefined`.\n */\n protected override _swapProperties(\n srcNode: R | BSTNKeyOrNode<K, NODE>,\n destNode: R | BSTNKeyOrNode<K, NODE>\n ): NODE | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n if (srcNode && destNode) {\n const { key, value, count, height } = destNode;\n const tempNode = this.createNode(key, value, count);\n if (tempNode) {\n tempNode.height = height;\n\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n destNode.count = srcNode.count;\n destNode.height = srcNode.height;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n srcNode.count = tempNode.count;\n srcNode.height = tempNode.height;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node and updates the count property of the new node.\n * @param {NODE} oldNode - The oldNode parameter represents the node that needs to be replaced in the\n * data structure. It is of type NODE.\n * @param {NODE} newNode - The `newNode` parameter is an instance of the `NODE` class.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, which is of type `NODE`.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.count = oldNode.count + newNode.count;\n return super._replaceNode(oldNode, newNode);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type {\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNKeyOrNodeOrEntry,\n IterationType,\n OptBSTN,\n RBTNColor,\n TreeMultiMapNested,\n TreeMultiMapNodeNested,\n TreeMultiMapOptions,\n BTNEntry\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { RedBlackTree, RedBlackTreeNode } from './rb-tree';\n\nexport class TreeMultiMapNode<\n K = any,\n V = any,\n NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNodeNested<K, V>\n> extends RedBlackTreeNode<K, V, NODE> {\n /**\n * The constructor function initializes a Red-Black Tree node with a key, value, count, and color.\n * @param {K} key - The key parameter represents the key of the node in the Red-Black Tree. It is\n * used to identify and locate the node within the tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the Red-Black Tree node. It is not required and can be omitted when\n * creating a new node.\n * @param [count=1] - The `count` parameter represents the number of occurrences of a particular key\n * in the Red-Black Tree. It is an optional parameter with a default value of 1.\n * @param {RBTNColor} [color=BLACK] - The `color` parameter is used to specify the color of the node\n * in a Red-Black Tree. It is optional and has a default value of `'BLACK'`.\n */\n constructor(key: K, value?: V, count = 1, color: RBTNColor = 'BLACK') {\n super(key, value, color);\n this.count = count;\n }\n\n protected _count: number = 1;\n\n /**\n * The function returns the value of the private variable _count.\n * @returns The count property of the object, which is of type number.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * The above function sets the value of the count property.\n * @param {number} value - The value parameter is of type number, which means it can accept any\n * numeric value.\n */\n set count(value: number) {\n this._count = value;\n }\n}\n\nexport class TreeMultiMap<\n K = any,\n V = any,\n R = BTNEntry<K, V>,\n NODE extends TreeMultiMapNode<K, V, NODE> = TreeMultiMapNode<K, V, TreeMultiMapNodeNested<K, V>>,\n TREE extends TreeMultiMap<K, V, R, NODE, TREE> = TreeMultiMap<K, V, R, NODE, TreeMultiMapNested<K, V, R, NODE>>\n >\n extends RedBlackTree<K, V, R, NODE, TREE>\n implements IBinaryTree<K, V, R, NODE, TREE>\n{\n /**\n * The constructor function initializes a TreeMultiMap object with optional initial data.\n * @param keysOrNodesOrEntriesOrRaws - The parameter `keysOrNodesOrEntriesOrRaws` is an\n * iterable that can contain keys, nodes, entries, or raw elements. It is used to initialize the\n * TreeMultiMap with initial data.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the `TreeMultiMap` constructor. It can include properties such as `compareKeys` and\n * `compareValues`, which are functions used to compare keys and values respectively.\n */\n constructor(\n keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE>> = [],\n options?: TreeMultiMapOptions<K, V, R>\n ) {\n super([], options);\n if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);\n }\n\n protected _count = 0;\n\n // TODO the _count is not accurate after nodes count modified\n /**\n * The function calculates the sum of the count property of all nodes in a tree structure.\n * @returns the sum of the count property of all nodes in the tree.\n */\n get count(): number {\n return this._count;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function calculates the sum of the count property of all nodes in a tree using depth-first\n * search.\n * @returns the sum of the count property of all nodes in the tree.\n */\n getComputedCount(): number {\n let sum = 0;\n this.dfs(node => (sum += node.count));\n return sum;\n }\n\n /**\n * The function creates a new TreeMultiMapNode with the specified key, value, color, and count.\n * @param {K} key - The key parameter represents the key of the node being created. It is of type K,\n * which is a generic type representing the type of keys in the tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the key in the node. It is of type `V`, which can be any data type.\n * @param {RBTNColor} [color=BLACK] - The color parameter is used to specify the color of the node in\n * a Red-Black Tree. It can have two possible values: 'RED' or 'BLACK'. The default value is 'BLACK'.\n * @param {number} [count] - The `count` parameter represents the number of occurrences of a key in\n * the tree. It is an optional parameter and is used to keep track of the number of values associated\n * with a key in the tree.\n * @returns A new instance of the TreeMultiMapNode class, casted as NODE.\n */\n override createNode(key: K, value?: V, color: RBTNColor = 'BLACK', count?: number): NODE {\n return new TreeMultiMapNode(key, value, count, color) as NODE;\n }\n\n /**\n * The function creates a new instance of a TreeMultiMap with the specified options and returns it.\n * @param [options] - The `options` parameter is an optional object that contains additional\n * configuration options for creating the `TreeMultiMap`. It is of type `TreeMultiMapOptions<K, V,\n * R>`.\n * @returns a new instance of the `TreeMultiMap` class, with the provided options merged with the\n * existing `iterationType` property. The returned value is casted as `TREE`.\n */\n override createTree(options?: TreeMultiMapOptions<K, V, R>): TREE {\n return new TreeMultiMap<K, V, R, NODE, TREE>([], {\n iterationType: this.iterationType,\n comparator: this._comparator,\n toEntryFn: this._toEntryFn,\n ...options\n }) as TREE;\n }\n\n /**\n * The function `keyValueOrEntryOrRawElementToNode` takes in a key, value, and count and returns a\n * node based on the input.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @param {V} [value] - The `value` parameter is an optional value that represents the value\n * associated with the key in the node. It is used when creating a new node or updating the value of\n * an existing node.\n * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of\n * times the key-value pair should be added to the data structure. If not provided, it defaults to 1.\n * @returns either a NODE object or undefined.\n */\n override keyValueOrEntryOrRawElementToNode(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n value?: V,\n count = 1\n ): NODE | undefined {\n if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return;\n\n if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;\n\n if (this.isEntry(keyOrNodeOrEntryOrRaw)) {\n const [key, entryValue] = keyOrNodeOrEntryOrRaw;\n if (key === undefined || key === null) return;\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count);\n }\n\n if (this._toEntryFn) {\n const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);\n if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count);\n }\n\n if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'BLACK', count);\n\n return;\n }\n\n /**\n * The function checks if the input is an instance of the TreeMultiMapNode class.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter\n * `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.\n * @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is\n * an instance of the `TreeMultiMapNode` class.\n */\n override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {\n return keyOrNodeOrEntryOrRaw instanceof TreeMultiMapNode;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function overrides the add method of a class and adds a new node to a data structure, updating\n * the count and returning a boolean indicating success.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The\n * `keyOrNodeOrEntryOrRaw` parameter can accept one of the following types:\n * @param {V} [value] - The `value` parameter represents the value associated with the key in the\n * data structure. It is an optional parameter, so it can be omitted if not needed.\n * @param [count=1] - The `count` parameter represents the number of times the key-value pair should\n * be added to the data structure. By default, it is set to 1, meaning that if no value is provided\n * for `count`, the key-value pair will be added once.\n * @returns The method is returning a boolean value. It returns true if the addition of the new node\n * was successful, and false otherwise.\n */\n override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V, count = 1): boolean {\n const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count);\n const orgCount = newNode?.count || 0;\n const isSuccessAdded = super.add(newNode);\n\n if (isSuccessAdded) {\n this._count += orgCount;\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `delete` in TypeScript overrides the deletion operation in a binary tree data\n * structure, handling cases where nodes have children and maintaining balance in the tree.\n * @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The `predicate`\n * parameter in the `delete` method is used to specify the condition or key based on which a node\n * should be deleted from the binary tree. It can be a key, a node, or an entry.\n * @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a\n * boolean flag that determines whether to ignore the count of nodes when performing deletion. If\n * `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If\n * `ignoreCount` is `false\n * @returns The `override delete` method returns an array of `BinaryTreeDeleteResult<NODE>` objects.\n */\n override delete(\n keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,\n ignoreCount = false\n ): BinaryTreeDeleteResult<NODE>[] {\n if (keyOrNodeOrEntryOrRaw === null) return [];\n\n const results: BinaryTreeDeleteResult<NODE>[] = [];\n\n let nodeToDelete: OptBSTN<NODE>;\n if (this._isPredicated(keyOrNodeOrEntryOrRaw)) nodeToDelete = this.getNode(keyOrNodeOrEntryOrRaw);\n else\n nodeToDelete = this.isRealNode(keyOrNodeOrEntryOrRaw)\n ? keyOrNodeOrEntryOrRaw\n : this.getNode(keyOrNodeOrEntryOrRaw);\n\n if (!nodeToDelete) {\n return results;\n }\n\n let originalColor = nodeToDelete.color;\n let replacementNode: NODE | undefined;\n\n if (!this.isRealNode(nodeToDelete.left)) {\n replacementNode = nodeToDelete.right;\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(nodeToDelete, nodeToDelete.right);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n } else if (!this.isRealNode(nodeToDelete.right)) {\n replacementNode = nodeToDelete.left;\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(nodeToDelete, nodeToDelete.left);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n } else {\n const successor = this.getLeftMost(node => node, nodeToDelete.right);\n if (successor) {\n originalColor = successor.color;\n replacementNode = successor.right;\n\n if (successor.parent === nodeToDelete) {\n if (this.isRealNode(replacementNode)) {\n replacementNode.parent = successor;\n }\n } else {\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(successor, successor.right);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n successor.right = nodeToDelete.right;\n if (this.isRealNode(successor.right)) {\n successor.right.parent = successor;\n }\n }\n if (ignoreCount || nodeToDelete.count <= 1) {\n this._transplant(nodeToDelete, successor);\n this._count -= nodeToDelete.count;\n } else {\n nodeToDelete.count--;\n this._count--;\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n return results;\n }\n successor.left = nodeToDelete.left;\n if (this.isRealNode(successor.left)) {\n successor.left.parent = successor;\n }\n successor.color = nodeToDelete.color;\n }\n }\n this._size--;\n\n // If the original color was black, fix the tree\n if (originalColor === 'BLACK') {\n this._deleteFixup(replacementNode);\n }\n\n results.push({ deleted: nodeToDelete, needBalanced: undefined });\n\n return results;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The \"clear\" function overrides the parent class's \"clear\" function and also resets the count to\n * zero.\n */\n override clear() {\n super.clear();\n this._count = 0;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(log n)\n *\n * The `perfectlyBalance` function takes a sorted array of nodes and builds a balanced binary search\n * tree using either a recursive or iterative approach.\n * @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that\n * specifies the type of iteration to use when building the balanced binary search tree. It has a\n * default value of `this.iterationType`, which means it will use the iteration type specified by the\n * `iterationType` property of the current object.\n * @returns The function `perfectlyBalance` returns a boolean value. It returns `true` if the\n * balancing operation is successful, and `false` if there are no nodes to balance.\n */\n override perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {\n const sorted = this.dfs(node => node, 'IN'),\n n = sorted.length;\n if (sorted.length < 1) return false;\n\n this.clear();\n\n if (iterationType === 'RECURSIVE') {\n const buildBalanceBST = (l: number, r: number) => {\n if (l > r) return;\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n buildBalanceBST(l, m - 1);\n buildBalanceBST(m + 1, r);\n };\n\n buildBalanceBST(0, n - 1);\n return true;\n } else {\n const stack: [[number, number]] = [[0, n - 1]];\n while (stack.length > 0) {\n const popped = stack.pop();\n if (popped) {\n const [l, r] = popped;\n if (l <= r) {\n const m = l + Math.floor((r - l) / 2);\n const midNode = sorted[m];\n this.add(midNode.key, midNode.value, midNode.count);\n stack.push([m + 1, r]);\n stack.push([l, m - 1]);\n }\n }\n }\n return true;\n }\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The function overrides the clone method to create a deep copy of a tree object.\n * @returns The `clone()` method is returning a cloned instance of the `TREE` object.\n */\n override clone(): TREE {\n const cloned = this.createTree();\n this.bfs(node => cloned.add(node.key, node.value, node.count));\n return cloned;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `_swapProperties` function swaps the properties (key, value, count, color) between two nodes\n * in a binary search tree.\n * @param {R | BSTNKeyOrNode<K, NODE>} srcNode - The `srcNode` parameter represents the source node\n * that will be swapped with the `destNode`. It can be either an instance of the `R` class or an\n * instance of the `BSTNKeyOrNode<K, NODE>` class.\n * @param {R | BSTNKeyOrNode<K, NODE>} destNode - The `destNode` parameter represents the destination\n * node where the properties will be swapped with the source node.\n * @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.\n * If either `srcNode` or `destNode` is undefined, it returns undefined.\n */\n protected override _swapProperties(\n srcNode: R | BSTNKeyOrNode<K, NODE>,\n destNode: R | BSTNKeyOrNode<K, NODE>\n ): NODE | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n if (srcNode && destNode) {\n const { key, value, count, color } = destNode;\n const tempNode = this.createNode(key, value, color, count);\n if (tempNode) {\n tempNode.color = color;\n\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n destNode.count = srcNode.count;\n destNode.color = srcNode.color;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n srcNode.count = tempNode.count;\n srcNode.color = tempNode.color;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function replaces an old node with a new node and updates the count property of the new node.\n * @param {NODE} oldNode - The `oldNode` parameter is the node that you want to replace in the data\n * structure.\n * @param {NODE} newNode - The `newNode` parameter is an instance of the `NODE` class.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, which is of type `NODE`.\n */\n protected override _replaceNode(oldNode: NODE, newNode: NODE): NODE {\n newNode.count = oldNode.count + newNode.count;\n return super._replaceNode(oldNode, newNode);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, PriorityQueueOptions } from '../../types';\nimport { Heap } from '../heap';\n\n/**\n * 1. Element Priority: In a PriorityQueue, elements are sorted according to their priority. Each dequeue (element removal) operation removes the element with the highest priority. The priority can be determined based on the natural ordering of the elements or through a provided comparator (Comparator).\n * 2. Heap-Based Implementation: PriorityQueue is typically implemented using a binary heap, allowing both insertion and removal operations to be completed in O(log n) time, where n is the number of elements in the queue.\n * 3. Task Scheduling: In systems where tasks need to be processed based on the urgency of tasks rather than the order of arrival.\n * 4. Dijkstra's Algorithm: In shortest path algorithms for graphs, used to select the next shortest edge to visit.\n * 5. Huffman Coding: Used to select the smallest node combination when constructing a Huffman tree.\n * 6. Kth Largest Element in a Data Stream: Used to maintain a min-heap of size K for quickly finding the Kth largest element in stream data\n */\nexport class PriorityQueue<E = any, R = any> extends Heap<E, R> {\n /**\n * The constructor initializes a priority queue with optional elements and options.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the priority queue. It is an optional parameter, and if not provided, the\n * priority queue will be initialized as empty.\n * @param [options] - The `options` parameter is an optional object that can be used to customize the\n * behavior of the priority queue. It can contain the following properties:\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: PriorityQueueOptions<E, R>) {\n super(elements, options);\n }\n\n /**\n * The `clone` function returns a new instance of the `PriorityQueue` class with the same comparator\n * and toElementFn as the original instance.\n * @returns The method is returning a new instance of the `PriorityQueue` class with the same\n * elements and properties as the current instance.\n */\n override clone(): PriorityQueue<E, R> {\n return new PriorityQueue<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new PriorityQueue object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `PriorityQueue` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(callback: ElementCallback<E, R, boolean, PriorityQueue<E, R>>, thisArg?: any): PriorityQueue<E, R> {\n const filteredPriorityQueue = new PriorityQueue<E, R>([], {\n toElementFn: this.toElementFn,\n comparator: this.comparator\n });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredPriorityQueue.add(current);\n }\n index++;\n }\n return filteredPriorityQueue;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `PriorityQueue` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, PriorityQueue<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): PriorityQueue<EM, RM> {\n const mappedPriorityQueue: PriorityQueue<EM, RM> = new PriorityQueue<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedPriorityQueue.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedPriorityQueue;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MinPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {\n /**\n * The constructor initializes a PriorityQueue with optional elements and options, including a\n * comparator function.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the priority queue. It is optional and defaults to an empty array if not\n * provided.\n * @param options - The `options` parameter is an object that contains additional configuration\n * options for the priority queue. In this case, it has a property called `comparator,` which is a\n * function used to compare elements in the priority queue. The `comparator` function takes two\n * parameters `a` and `b`\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: PriorityQueueOptions<E, R>) {\n super(elements, options);\n }\n\n /**\n * The `clone` function returns a new instance of the `MinPriorityQueue` class with the same\n * comparator and toElementFn as the original instance.\n * @returns The method is returning a new instance of the `MinPriorityQueue` class with the same\n * properties as the current instance.\n */\n override clone(): MinPriorityQueue<E, R> {\n return new MinPriorityQueue<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MinPriorityQueue object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MinPriorityQueue` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(\n callback: ElementCallback<E, R, boolean, MinPriorityQueue<E, R>>,\n thisArg?: any\n ): MinPriorityQueue<E, R> {\n const filteredPriorityQueue = new MinPriorityQueue<E, R>([], {\n toElementFn: this.toElementFn,\n comparator: this.comparator\n });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredPriorityQueue.add(current);\n }\n index++;\n }\n return filteredPriorityQueue;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MinPriorityQueue` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MinPriorityQueue<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MinPriorityQueue<EM, RM> {\n const mappedPriorityQueue: MinPriorityQueue<EM, RM> = new MinPriorityQueue<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedPriorityQueue.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedPriorityQueue;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Kirk Qi\n * @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>\n * @license MIT License\n */\nimport type { Comparator, ElementCallback, PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MaxPriorityQueue<E = any, R = any> extends PriorityQueue<E, R> {\n /**\n * The constructor initializes a PriorityQueue with optional elements and options, including a\n * comparator function.\n * @param elements - The `elements` parameter is an iterable object that contains the initial\n * elements to be added to the priority queue. It is optional and defaults to an empty array if not\n * provided.\n * @param options - The `options` parameter is an object that contains additional configuration\n * options for the priority queue. In this case, it has a property called `comparator,` which is a\n * function used to compare elements in the priority queue.\n */\n constructor(elements: Iterable<E> | Iterable<R> = [], options?: PriorityQueueOptions<E, R>) {\n super(elements, {\n comparator: (a: E, b: E): number => {\n if (typeof a === 'object' || typeof b === 'object') {\n throw TypeError(\n `When comparing object types, a custom comparator must be defined in the constructor's options parameter.`\n );\n }\n if (a < b) return 1;\n if (a > b) return -1;\n return 0;\n },\n ...options\n });\n }\n\n /**\n * The `clone` function returns a new instance of the `MaxPriorityQueue` class with the same\n * comparator and toElementFn as the current instance.\n * @returns The method is returning a new instance of the MaxPriorityQueue class with the same\n * comparator and toElementFn as the current instance.\n */\n override clone(): MaxPriorityQueue<E, R> {\n return new MaxPriorityQueue<E, R>(this, { comparator: this.comparator, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function creates a new MaxPriorityQueue object containing elements that pass a given callback\n * function.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: the current element, the index of the current element, and the\n * heap itself. The callback function should return a boolean value indicating whether the current\n * element should be included in the filtered list\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that specifies the value\n * to be used as `this` when executing the `callback` function. If `thisArg` is provided, it will be\n * passed as the `this` value to the `callback` function. If `thisArg` is\n * @returns The `filter` method is returning a new `MaxPriorityQueue` object that contains the elements that pass\n * the filter condition specified by the `callback` function.\n */\n override filter(\n callback: ElementCallback<E, R, boolean, MaxPriorityQueue<E, R>>,\n thisArg?: any\n ): MaxPriorityQueue<E, R> {\n const filteredPriorityQueue = new MaxPriorityQueue<E, R>([], {\n toElementFn: this.toElementFn,\n comparator: this.comparator\n });\n let index = 0;\n for (const current of this) {\n if (callback.call(thisArg, current, index, this)) {\n filteredPriorityQueue.add(current);\n }\n index++;\n }\n return filteredPriorityQueue;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new heap by applying a callback function to each element of the\n * original heap.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the heap. It takes three arguments: `el` (the current element), `index` (the index of the current\n * element), and `this` (the heap itself). The callback function should return a value of\n * @param comparator - The `comparator` parameter is a function that defines the order of the\n * elements in the heap. It takes two elements `a` and `b` as arguments and returns a negative number\n * if `a` should be placed before `b`, a positive number if `a` should be placed after\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that converts the raw\n * element `RR` to the desired type `T`. It takes a single argument `rawElement` of type `RR` and\n * returns a value of type `T`. This function is used to transform the elements of the original\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new instance of the `MaxPriorityQueue` class with the mapped elements.\n */\n override map<EM, RM>(\n callback: ElementCallback<E, R, EM, MaxPriorityQueue<E, R>>,\n comparator: Comparator<EM>,\n toElementFn?: (rawElement: RM) => EM,\n thisArg?: any\n ): MaxPriorityQueue<EM, RM> {\n const mappedPriorityQueue = new MaxPriorityQueue<EM, RM>([], { comparator, toElementFn });\n let index = 0;\n for (const el of this) {\n mappedPriorityQueue.add(callback.call(thisArg, el, index, this));\n index++;\n }\n return mappedPriorityQueue;\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { MatrixOptions } from '../../types';\n\nexport class Matrix {\n /**\n * The constructor function initializes a matrix object with the provided data and options, or with\n * default values if no options are provided.\n * @param {number[][]} data - A 2D array of numbers representing the data for the matrix.\n * @param [options] - The `options` parameter is an optional object that can contain the following\n * properties:\n */\n constructor(data: number[][], options?: MatrixOptions) {\n if (options) {\n const { rows, cols, addFn, subtractFn, multiplyFn } = options;\n if (typeof rows === 'number' && rows > 0) this._rows = rows;\n else this._rows = data.length;\n if (typeof cols === 'number' && cols > 0) this._cols = cols;\n else this._cols = data[0]?.length || 0;\n if (addFn) this._addFn = addFn;\n if (subtractFn) this._subtractFn = subtractFn;\n if (multiplyFn) this._multiplyFn = multiplyFn;\n } else {\n this._rows = data.length;\n this._cols = data[0]?.length ?? 0;\n }\n\n if (data.length > 0) {\n this._data = data;\n } else {\n this._data = [];\n for (let i = 0; i < this.rows; i++) {\n this._data[i] = new Array(this.cols).fill(0);\n }\n }\n }\n\n protected _rows: number = 0;\n\n /**\n * The function returns the number of rows.\n * @returns The number of rows.\n */\n get rows(): number {\n return this._rows;\n }\n\n protected _cols: number = 0;\n\n /**\n * The function returns the value of the protected variable _cols.\n * @returns The number of columns.\n */\n get cols(): number {\n return this._cols;\n }\n\n protected _data: number[][];\n\n /**\n * The function returns a two-dimensional array of numbers.\n * @returns The data property, which is a two-dimensional array of numbers.\n */\n get data(): number[][] {\n return this._data;\n }\n\n /**\n * The above function returns the value of the _addFn property.\n * @returns The value of the property `_addFn` is being returned.\n */\n get addFn() {\n return this._addFn;\n }\n\n /**\n * The function returns the value of the _subtractFn property.\n * @returns The `_subtractFn` property is being returned.\n */\n get subtractFn() {\n return this._subtractFn;\n }\n\n /**\n * The function returns the value of the _multiplyFn property.\n * @returns The `_multiplyFn` property is being returned.\n */\n get multiplyFn() {\n return this._multiplyFn;\n }\n\n /**\n * The `get` function returns the value at the specified row and column index if it is a valid index.\n * @param {number} row - The `row` parameter represents the row index of the element you want to\n * retrieve from the data array.\n * @param {number} col - The parameter \"col\" represents the column number of the element you want to\n * retrieve from the data array.\n * @returns The `get` function returns a number if the provided row and column indices are valid.\n * Otherwise, it returns `undefined`.\n */\n get(row: number, col: number): number | undefined {\n if (this.isValidIndex(row, col)) {\n return this.data[row][col];\n }\n }\n\n /**\n * The set function updates the value at a specified row and column in a two-dimensional array.\n * @param {number} row - The \"row\" parameter represents the row index of the element in a\n * two-dimensional array or matrix. It specifies the row where the value will be set.\n * @param {number} col - The \"col\" parameter represents the column index of the element in a\n * two-dimensional array.\n * @param {number} value - The value parameter represents the number that you want to set at the\n * specified row and column in the data array.\n * @returns a boolean value. It returns true if the index (row, col) is valid and the value is\n * successfully set in the data array. It returns false if the index is invalid and the value is not\n * set.\n */\n set(row: number, col: number, value: number): boolean {\n if (this.isValidIndex(row, col)) {\n this.data[row][col] = value;\n return true;\n }\n return false;\n }\n\n /**\n * The function checks if the dimensions of the given matrix match the dimensions of the current\n * matrix.\n * @param {Matrix} matrix - The parameter `matrix` is of type `Matrix`.\n * @returns a boolean value.\n */\n isMatchForCalculate(matrix: Matrix): boolean {\n return this.rows === matrix.rows && this.cols === matrix.cols;\n }\n\n /**\n * The `add` function adds two matrices together, returning a new matrix with the result.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.\n * @returns The `add` method returns a new `Matrix` object that represents the result of adding the\n * current matrix with the provided `matrix` parameter.\n */\n add(matrix: Matrix): Matrix | undefined {\n if (!this.isMatchForCalculate(matrix)) {\n throw new Error('Matrix dimensions must match for addition.');\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < this.cols; j++) {\n const a = this.get(i, j),\n b = matrix.get(i, j);\n if (a !== undefined && b !== undefined) {\n const added = this._addFn(a, b);\n if (added) {\n resultData[i][j] = added;\n }\n }\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The `subtract` function performs element-wise subtraction between two matrices and returns a new\n * matrix with the result.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class. It\n * represents the matrix that you want to subtract from the current matrix.\n * @returns a new Matrix object with the result of the subtraction operation.\n */\n subtract(matrix: Matrix): Matrix | undefined {\n if (!this.isMatchForCalculate(matrix)) {\n throw new Error('Matrix dimensions must match for subtraction.');\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < this.cols; j++) {\n const a = this.get(i, j),\n b = matrix.get(i, j);\n if (a !== undefined && b !== undefined) {\n const subtracted = this._subtractFn(a, b);\n if (subtracted) {\n resultData[i][j] = subtracted;\n }\n }\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The `multiply` function performs matrix multiplication between two matrices and returns the result\n * as a new matrix.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.\n * @returns a new Matrix object.\n */\n multiply(matrix: Matrix): Matrix | undefined {\n if (this.cols !== matrix.rows) {\n throw new Error('Matrix dimensions must be compatible for multiplication (A.cols = B.rows).');\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < matrix.cols; j++) {\n let sum: number | undefined;\n for (let k = 0; k < this.cols; k++) {\n const a = this.get(i, k),\n b = matrix.get(k, j);\n if (a !== undefined && b !== undefined) {\n const multiplied = this.multiplyFn(a, b);\n if (multiplied !== undefined) {\n sum = this.addFn(sum, multiplied);\n }\n }\n }\n if (sum !== undefined) resultData[i][j] = sum;\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: matrix.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The transpose function takes a matrix and returns a new matrix that is the transpose of the\n * original matrix.\n * @returns The transpose() function returns a new Matrix object with the transposed data.\n */\n transpose(): Matrix {\n if (this.data.some(row => row.length !== this.rows)) {\n throw new Error('Matrix must be rectangular for transposition.');\n }\n\n const resultData: number[][] = [];\n\n for (let j = 0; j < this.cols; j++) {\n resultData[j] = [];\n for (let i = 0; i < this.rows; i++) {\n const trans = this.get(i, j);\n if (trans !== undefined) resultData[j][i] = trans;\n }\n }\n\n return new Matrix(resultData, {\n rows: this.cols,\n cols: this.rows,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The `inverse` function calculates the inverse of a square matrix using Gaussian elimination.\n * @returns a Matrix object, which represents the inverse of the original matrix.\n */\n inverse(): Matrix | undefined {\n // Check if the matrix is square\n if (this.rows !== this.cols) {\n throw new Error('Matrix must be square for inversion.');\n }\n\n // Create an augmented matrix [this | I]\n const augmentedMatrixData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n augmentedMatrixData[i] = this.data[i].slice(); // Copy the original matrix\n for (let j = 0; j < this.cols; j++) {\n augmentedMatrixData[i][this.cols + j] = i === j ? 1 : 0; // Append the identity matrix\n }\n }\n\n const augmentedMatrix = new Matrix(augmentedMatrixData, {\n rows: this.rows,\n cols: this.cols * 2,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n\n // Apply Gaussian elimination to transform the left half into the identity matrix\n for (let i = 0; i < this.rows; i++) {\n // Find pivot\n let pivotRow = i;\n while (pivotRow < this.rows && augmentedMatrix.get(pivotRow, i) === 0) {\n pivotRow++;\n }\n\n if (pivotRow === this.rows) {\n // Matrix is singular, and its inverse does not exist\n throw new Error('Matrix is singular, and its inverse does not exist.');\n }\n\n // Swap rows to make the pivot the current row\n augmentedMatrix._swapRows(i, pivotRow);\n\n // Scale the pivot row to make the pivot element 1\n const pivotElement = augmentedMatrix.get(i, i) ?? 1;\n\n if (pivotElement === 0) {\n // Handle division by zero\n throw new Error('Matrix is singular, and its inverse does not exist (division by zero).');\n }\n\n augmentedMatrix._scaleRow(i, 1 / pivotElement);\n\n // Eliminate other rows to make elements in the current column zero\n for (let j = 0; j < this.rows; j++) {\n if (j !== i) {\n let factor = augmentedMatrix.get(j, i);\n if (factor === undefined) factor = 0;\n\n augmentedMatrix._addScaledRow(j, i, -factor);\n }\n }\n }\n\n // Extract the right half of the augmented matrix as the inverse\n const inverseData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n inverseData[i] = augmentedMatrix.data[i].slice(this.cols);\n }\n\n return new Matrix(inverseData, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The dot function calculates the dot product of two matrices and returns a new matrix.\n * @param {Matrix} matrix - The `matrix` parameter is an instance of the `Matrix` class.\n * @returns a new Matrix object.\n */\n dot(matrix: Matrix): Matrix | undefined {\n if (this.cols !== matrix.rows) {\n throw new Error(\n 'Number of columns in the first matrix must be equal to the number of rows in the second matrix for dot product.'\n );\n }\n\n const resultData: number[][] = [];\n for (let i = 0; i < this.rows; i++) {\n resultData[i] = [];\n for (let j = 0; j < matrix.cols; j++) {\n let sum: number | undefined;\n for (let k = 0; k < this.cols; k++) {\n const a = this.get(i, k),\n b = matrix.get(k, j);\n if (a !== undefined && b !== undefined) {\n const multiplied = this.multiplyFn(a, b);\n if (multiplied !== undefined) {\n sum = this.addFn(sum, multiplied);\n }\n }\n }\n if (sum !== undefined) resultData[i][j] = sum;\n }\n }\n\n return new Matrix(resultData, {\n rows: this.rows,\n cols: matrix.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n /**\n * The function checks if a given row and column index is valid within a specified range.\n * @param {number} row - The `row` parameter represents the row index of a two-dimensional array or\n * matrix. It is a number that indicates the specific row in the matrix.\n * @param {number} col - The \"col\" parameter represents the column index in a two-dimensional array\n * or grid. It is used to check if the given column index is valid within the bounds of the grid.\n * @returns A boolean value is being returned.\n */\n isValidIndex(row: number, col: number): boolean {\n return row >= 0 && row < this.rows && col >= 0 && col < this.cols;\n }\n\n /**\n * The `clone` function returns a new instance of the Matrix class with the same data and properties\n * as the original instance.\n * @returns The `clone()` method is returning a new instance of the `Matrix` class with the same data\n * and properties as the current instance.\n */\n clone(): Matrix {\n return new Matrix(this.data, {\n rows: this.rows,\n cols: this.cols,\n addFn: this.addFn,\n subtractFn: this.subtractFn,\n multiplyFn: this.multiplyFn\n });\n }\n\n protected _addFn(a: number | undefined, b: number): number | undefined {\n if (a === undefined) return b;\n return a + b;\n }\n\n protected _subtractFn(a: number, b: number) {\n return a - b;\n }\n\n protected _multiplyFn(a: number, b: number) {\n return a * b;\n }\n\n /**\n * The function `_swapRows` swaps the positions of two rows in an array.\n * @param {number} row1 - The `row1` parameter is the index of the first row that you want to swap.\n * @param {number} row2 - The `row2` parameter is the index of the second row that you want to swap\n * with the first row.\n */\n protected _swapRows(row1: number, row2: number): void {\n const temp = this.data[row1];\n this.data[row1] = this.data[row2];\n this.data[row2] = temp;\n }\n\n /**\n * The function scales a specific row in a matrix by a given scalar value.\n * @param {number} row - The `row` parameter represents the index of the row in the matrix that you\n * want to scale. It is a number that indicates the position of the row within the matrix.\n * @param {number} scalar - The scalar parameter is a number that is used to multiply each element in\n * a specific row of a matrix.\n */\n protected _scaleRow(row: number, scalar: number): void {\n for (let j = 0; j < this.cols; j++) {\n let multiplied = this.multiplyFn(this.data[row][j], scalar);\n if (multiplied === undefined) multiplied = 0;\n this.data[row][j] = multiplied;\n }\n }\n\n /**\n * The function `_addScaledRow` multiplies a row in a matrix by a scalar value and adds it to another\n * row.\n * @param {number} targetRow - The targetRow parameter represents the index of the row in which the\n * scaled values will be added.\n * @param {number} sourceRow - The sourceRow parameter represents the index of the row from which the\n * values will be scaled and added to the targetRow.\n * @param {number} scalar - The scalar parameter is a number that is used to scale the values in the\n * source row before adding them to the target row.\n */\n protected _addScaledRow(targetRow: number, sourceRow: number, scalar: number): void {\n for (let j = 0; j < this.cols; j++) {\n let multiplied = this.multiplyFn(this.data[sourceRow][j], scalar);\n if (multiplied === undefined) multiplied = 0;\n const scaledValue = multiplied;\n let added = this.addFn(this.data[targetRow][j], scaledValue);\n if (added === undefined) added = 0;\n this.data[targetRow][j] = added;\n }\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { Direction, NavigatorParams, Turning } from '../../types';\n\nexport class Character {\n direction: Direction;\n turn: () => Character;\n\n /**\n * The constructor function takes in a direction and turning object and sets the direction and turn properties of the\n * Character class.\n * @param {Direction} direction - The direction parameter is used to specify the current direction of the character. It\n * can be any value that represents a direction, such as \"north\", \"south\", \"east\", or \"west\".\n * @param {Turning} turning - The `turning` parameter is an object that maps each direction to the corresponding\n * turning direction. It is used to determine the new direction when the character turns.\n */\n constructor(direction: Direction, turning: Turning) {\n this.direction = direction;\n this.turn = () => new Character(turning[direction], turning);\n }\n}\n\nexport class Navigator<T = number> {\n onMove: (cur: [number, number]) => void;\n protected readonly _matrix: T[][];\n protected readonly _cur: [number, number];\n protected _character: Character;\n protected readonly _VISITED: T;\n\n /**\n * The constructor initializes the Navigator object with the given parameters and sets the current position as visited\n * in the matrix.\n * @param - - `matrix`: a 2D array representing the grid or map\n */\n constructor({ matrix, turning, onMove, init: { cur, charDir, VISITED } }: NavigatorParams<T>) {\n this._matrix = matrix;\n this._cur = cur;\n this._character = new Character(charDir, turning);\n this.onMove = onMove;\n if (this.onMove) this.onMove(this._cur);\n this._VISITED = VISITED;\n this._matrix[this._cur[0]][this._cur[1]] = this._VISITED;\n }\n\n /**\n * The \"start\" function moves the character in its current direction until it encounters an obstacle, then it turns the\n * character and repeats the process.\n */\n start() {\n while (this.check(this._character.direction) || this.check(this._character.turn().direction)) {\n const { direction } = this._character;\n if (this.check(direction)) {\n this.move(direction);\n } else if (this.check(this._character.turn().direction)) {\n this._character = this._character.turn();\n }\n }\n }\n\n /**\n * The function checks if there is a valid move in the specified direction in a matrix.\n * @param {Direction} direction - The direction parameter is a string that represents the direction in which to check.\n * It can be one of the following values: 'up', 'right', 'down', or 'left'.\n * @returns a boolean value.\n */\n check(direction: Direction) {\n let forward: T | undefined, row: T[] | undefined;\n const matrix = this._matrix;\n const [i, j] = this._cur;\n switch (direction) {\n case 'up':\n row = matrix[i - 1];\n if (!row) return false;\n forward = row[j];\n break;\n case 'right':\n forward = matrix[i][j + 1];\n break;\n case 'down':\n row = matrix[i + 1];\n if (!row) return false;\n forward = row[j];\n break;\n case 'left':\n forward = matrix[i][j - 1];\n break;\n }\n return forward !== undefined && forward !== this._VISITED;\n }\n\n /**\n * The `move` function updates the current position based on the given direction and updates the matrix accordingly.\n * @param {Direction} direction - The `direction` parameter is a string that represents the direction in which to move.\n * It can have one of the following values: 'up', 'right', 'down', or 'left'.\n */\n move(direction: Direction) {\n switch (direction) {\n case 'up':\n this._cur[0]--;\n break;\n case 'right':\n this._cur[1]++;\n break;\n case 'down':\n this._cur[0]++;\n break;\n case 'left':\n this._cur[1]--;\n break;\n }\n\n const [i, j] = this._cur;\n this._matrix[i][j] = this._VISITED;\n if (this.onMove) this.onMove(this._cur);\n }\n}\n","/**\n * data-structure-typed\n *\n * @author Pablo Zeng\n * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback, TrieOptions } from '../../types';\nimport { IterableElementBase } from '../base';\n\n/**\n * TrieNode represents a node in the Trie data structure. It holds a character key, a map of children nodes,\n * and a flag indicating whether it's the end of a word.\n */\nexport class TrieNode {\n constructor(key: string) {\n this._key = key;\n this._isEnd = false;\n this._children = new Map<string, TrieNode>();\n }\n\n protected _key: string;\n\n /**\n * The function returns the value of the protected variable _key.\n * @returns The value of the `_key` property, which is a string.\n */\n get key(): string {\n return this._key;\n }\n\n /**\n * The above function sets the value of a protected variable called \"key\".\n * @param {string} value - The value parameter is a string that represents the value to be assigned\n * to the key.\n */\n set key(value: string) {\n this._key = value;\n }\n\n protected _children: Map<string, TrieNode>;\n\n /**\n * The function returns the children of a TrieNode as a Map.\n * @returns The `children` property of the TrieNode object, which is a Map containing string keys and\n * TrieNode values.\n */\n get children(): Map<string, TrieNode> {\n return this._children;\n }\n\n /**\n * The function sets the value of the `_children` property of a TrieNode object.\n * @param value - The value parameter is a Map object that represents the children of a TrieNode. The\n * keys of the map are strings, which represent the characters that are associated with each child\n * TrieNode. The values of the map are TrieNode objects, which represent the child nodes of the\n * current TrieNode.\n */\n set children(value: Map<string, TrieNode>) {\n this._children = value;\n }\n\n protected _isEnd: boolean;\n\n /**\n * The function returns a boolean value indicating whether a certain condition is met.\n * @returns The method is returning a boolean value, specifically the value of the variable `_isEnd`.\n */\n get isEnd(): boolean {\n return this._isEnd;\n }\n\n /**\n * The function sets the value of the \"_isEnd\" property.\n * @param {boolean} value - The value parameter is a boolean value that indicates whether the current\n * state is the end state or not.\n */\n set isEnd(value: boolean) {\n this._isEnd = value;\n }\n}\n\n/**\n * 1. Node Structure: Each node in a Trie represents a string (or a part of a string). The root node typically represents an empty string.\n * 2. Child Node Relationship: Each node's children represent the strings that can be formed by adding one character to the string at the current node. For example, if a node represents the string 'ca', one of its children might represent 'cat'.\n * 3. Fast Retrieval: Trie allows retrieval in O(m) time complexity, where m is the length of the string to be searched.\n * 4. Space Efficiency: Trie can store a large number of strings very space-efficiently, especially when these strings share common prefixes.\n * 5. Autocomplete and Prediction: Trie can be used for implementing autocomplete and word prediction features, as it can quickly find all strings with a common prefix.\n * 6. Sorting: Trie can be used to sort a set of strings in alphabetical order.\n * 7. String Retrieval: For example, searching for a specific string in a large set of strings.\n * 8. Autocomplete: Providing recommended words or phrases as a user types.\n * 9. Spell Check: Checking the spelling of words.\n * 10. IP Routing: Used in certain types of IP routing algorithms.\n * 11. Text Word Frequency Count: Counting and storing the frequency of words in a large amount of text data.\n */\nexport class Trie<R = any> extends IterableElementBase<string, R, Trie<R>> {\n /**\n * The constructor function for the Trie class.\n * @param words: Iterable string Initialize the trie with a set of words\n * @param options?: TrieOptions Allow the user to pass in options for the trie\n * @return This\n */\n constructor(words: Iterable<string> | Iterable<R> = [], options?: TrieOptions<R>) {\n super(options);\n if (options) {\n const { caseSensitive } = options;\n if (caseSensitive !== undefined) this._caseSensitive = caseSensitive;\n }\n if (words) {\n for (const word of words) {\n if (this.toElementFn) {\n this.add(this.toElementFn(word as R));\n } else {\n this.add(word as string);\n }\n }\n }\n }\n\n protected _size: number = 0;\n\n /**\n * The size function returns the size of the stack.\n * @return The number of elements in the list\n */\n get size(): number {\n return this._size;\n }\n\n protected _caseSensitive: boolean = true;\n\n /**\n * The caseSensitive function is a getter that returns the value of the protected _caseSensitive property.\n * @return The value of the _caseSensitive protected variable\n */\n get caseSensitive(): boolean {\n return this._caseSensitive;\n }\n\n protected _root: TrieNode = new TrieNode('');\n\n /**\n * The root function returns the root node of the tree.\n * @return The root node\n */\n get root() {\n return this._root;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the word being added.\n * Space Complexity: O(l) - Each character in the word adds a TrieNode.\n *\n * Add a word to the Trie structure.\n * @param {string} word - The word to add.\n * @returns {boolean} True if the word was successfully added.\n */\n add(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n let isNewWord = false;\n for (const c of word) {\n let nodeC = cur.children.get(c);\n if (!nodeC) {\n nodeC = new TrieNode(c);\n cur.children.set(c, nodeC);\n }\n cur = nodeC;\n }\n if (!cur.isEnd) {\n isNewWord = true;\n cur.isEnd = true;\n this._size++;\n }\n return isNewWord;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input word.\n * Space Complexity: O(1) - Constant space.\n *\n * Check if the Trie contains a given word.\n * @param {string} word - The word to check for.\n * @returns {boolean} True if the word is present in the Trie.\n */\n override has(word: string): boolean {\n word = this._caseProcess(word);\n let cur = this.root;\n for (const c of word) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return cur.isEnd;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The isEmpty function checks if the size of the queue is 0.\n * @return True if the size of the queue is 0\n */\n isEmpty(): boolean {\n return this._size === 0;\n }\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The clear function resets the size of the Trie to 0 and creates a new root TrieNode.\n */\n clear(): void {\n this._size = 0;\n this._root = new TrieNode('');\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the word being deleted.\n * Space Complexity: O(n) - Due to the recursive DFS approach.\n *\n * Remove a word from the Trie structure.\n * @param{string} word - The word to delete.\n * @returns {boolean} True if the word was successfully removed.\n */\n delete(word: string): boolean {\n word = this._caseProcess(word);\n let isDeleted = false;\n const dfs = (cur: TrieNode, i: number): boolean => {\n const char = word[i];\n const child = cur.children.get(char);\n if (child) {\n if (i === word.length - 1) {\n if (child.isEnd) {\n if (child.children.size > 0) {\n child.isEnd = false;\n } else {\n cur.children.delete(char);\n }\n isDeleted = true;\n return true;\n }\n return false;\n }\n const res = dfs(child, i + 1);\n if (res && !cur.isEnd && child.children.size === 0) {\n cur.children.delete(char);\n return true;\n }\n return false;\n }\n return false;\n };\n\n dfs(this.root, 0);\n if (isDeleted) {\n this._size--;\n }\n return isDeleted;\n }\n\n /**\n * Time Complexity: O(n), where n is the total number of nodes in the trie.\n * Space Complexity: O(1) - Constant space.\n *\n */\n getHeight(): number {\n const beginRoot = this.root;\n let maxDepth = 0;\n if (beginRoot) {\n const bfs = (node: TrieNode, level: number) => {\n if (level > maxDepth) {\n maxDepth = level;\n }\n const { children } = node;\n if (children) {\n for (const child of children.entries()) {\n bfs(child[1], level + 1);\n }\n }\n };\n bfs(beginRoot, 0);\n }\n return maxDepth;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n *\n * Check if a given input string has an absolute prefix in the Trie, meaning it's not a complete word.\n * @param {string} input - The input string to check.\n * @returns {boolean} True if it's an absolute prefix in the Trie.\n */\n hasPurePrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return !cur.isEnd;\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n *\n * Check if a given input string is a prefix of any existing word in the Trie, whether as an absolute prefix or a complete word.\n * @param {string} input - The input string representing the prefix to check.\n * @returns {boolean} True if it's a prefix in the Trie.\n */\n hasPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let cur = this.root;\n for (const c of input) {\n const nodeC = cur.children.get(c);\n if (!nodeC) return false;\n cur = nodeC;\n }\n return true;\n }\n\n /**\n * Time Complexity: O(n), where n is the total number of nodes in the trie.\n * Space Complexity: O(l), where l is the length of the input prefix.\n *\n * Check if the input string is a common prefix in the Trie, meaning it's a prefix shared by all words in the Trie.\n * @param {string} input - The input string representing the common prefix to check for.\n * @returns {boolean} True if it's a common prefix in the Trie.\n */\n hasCommonPrefix(input: string): boolean {\n input = this._caseProcess(input);\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (commonPre === input) return;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre === input;\n }\n\n /**\n * Time Complexity: O(n), where n is the total number of nodes in the trie.\n * Space Complexity: O(l), where l is the length of the longest common prefix.\n *\n * Get the longest common prefix among all the words stored in the Trie.\n * @returns {string} The longest common prefix found in the Trie.\n */\n getLongestCommonPrefix(): string {\n let commonPre = '';\n const dfs = (cur: TrieNode) => {\n commonPre += cur.key;\n if (cur.isEnd) return;\n if (cur && cur.children && cur.children.size === 1) dfs(Array.from(cur.children.values())[0]);\n else return;\n };\n dfs(this.root);\n return commonPre;\n }\n\n /**\n * Time Complexity: O(w * l), where w is the number of words retrieved, and l is the average length of the words.\n * Space Complexity: O(w * l) - The space required for the output array.\n *\n * The `getAll` function returns an array of all words in a Trie data structure that start with a given prefix.\n * @param {string} prefix - The `prefix` parameter is a string that represents the prefix that we want to search for in the\n * trie. It is an optional parameter, so if no prefix is provided, it will default to an empty string.\n * @param {number} max - The max count of words will be found\n * @param isAllWhenEmptyPrefix - If true, when the prefix provided as '', returns all the words in the trie.\n * @returns {string[]} an array of strings.\n */\n getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false): string[] {\n prefix = this._caseProcess(prefix);\n const words: string[] = [];\n let found = 0;\n\n function dfs(node: TrieNode, word: string) {\n for (const char of node.children.keys()) {\n const charNode = node.children.get(char);\n if (charNode !== undefined) {\n dfs(charNode, word.concat(char));\n }\n }\n if (node.isEnd) {\n if (found > max - 1) return;\n words.push(word);\n found++;\n }\n }\n\n let startNode = this.root;\n\n if (prefix) {\n for (const c of prefix) {\n const nodeC = startNode.children.get(c);\n if (nodeC) {\n startNode = nodeC;\n } else {\n // Early return if the whole prefix is not found\n return [];\n }\n }\n }\n\n if (isAllWhenEmptyPrefix || startNode !== this.root) dfs(startNode, prefix);\n\n return words;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `clone` function returns a new instance of the Trie class with the same values and case\n * sensitivity as the original Trie.\n * @returns A new instance of the Trie class is being returned.\n */\n clone(): Trie<R> {\n return new Trie<R>(this, { caseSensitive: this.caseSensitive, toElementFn: this.toElementFn });\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `filter` function takes a predicate function and returns a new array containing all the\n * elements for which the predicate function returns true.\n * @param predicate - The `predicate` parameter is a callback function that takes three arguments:\n * `word`, `index`, and `this`. It should return a boolean value indicating whether the current\n * element should be included in the filtered results or not.\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the `predicate` function. It is used when you want to bind a\n * specific object as the context for the `predicate` function. If `thisArg` is provided, it will be\n * @returns The `filter` method is returning an array of strings (`string[]`).\n */\n filter(predicate: ElementCallback<string, R, boolean, Trie<R>>, thisArg?: any): Trie<R> {\n const results = new Trie<R>([], { toElementFn: this.toElementFn, caseSensitive: this.caseSensitive });\n let index = 0;\n for (const word of this) {\n if (predicate.call(thisArg, word, index, this)) {\n results.add(word);\n }\n index++;\n }\n return results;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new Trie by applying a callback function to each element in the\n * current Trie.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * Trie. It takes four arguments:\n * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to\n * convert the raw element (`RM`) into a string representation. This can be useful if the raw element\n * is not already a string or if you want to customize how the element is converted into a string. If\n * this parameter is\n * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to\n * specify the value of `this` within the callback function. It is used to set the context or scope\n * in which the callback function will be executed. If `thisArg` is provided, it will be used as the\n * value of\n * @returns a new Trie object.\n */\n map<RM>(\n callback: ElementCallback<string, R, string, Trie<R>>,\n toElementFn?: (rawElement: RM) => string,\n thisArg?: any\n ): Trie<RM> {\n const newTrie = new Trie<RM>([], { toElementFn, caseSensitive: this.caseSensitive });\n let index = 0;\n for (const word of this) {\n newTrie.add(callback.call(thisArg, word, index, this));\n index++;\n }\n return newTrie;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The function `_getIterator` returns an iterable iterator that performs a depth-first search on a\n * trie data structure and yields all the paths to the end nodes.\n */\n protected *_getIterator(): IterableIterator<string> {\n function* _dfs(node: TrieNode, path: string): IterableIterator<string> {\n if (node.isEnd) {\n yield path;\n }\n for (const [char, childNode] of node.children) {\n yield* _dfs(childNode, path + char);\n }\n }\n\n yield* _dfs(this.root, '');\n }\n\n /**\n * Time Complexity: O(l), where l is the length of the input string.\n * Space Complexity: O(1) - Constant space.\n *\n * @param str\n * @protected\n */\n protected _caseProcess(str: string) {\n if (!this._caseSensitive) {\n str = str.toLowerCase(); // Convert str to lowercase if case-insensitive\n }\n return str;\n }\n}\n","export class TreeNode<V = any> {\n /**\n * The constructor function initializes a TreeNode object with a key, optional value, and optional\n * children.\n * @param {string} key - A string representing the key of the tree node.\n * @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the\n * value associated with the node. If no value is provided, it defaults to `undefined`.\n * @param {TreeNode<V>[]} [children] - The `children` parameter is an optional array of `TreeNode<V>`\n * objects. It represents the child nodes of the current node. If no children are provided, the\n * default value is an empty array.\n */\n constructor(key: string, value?: V, children?: TreeNode<V>[]) {\n this._key = key;\n this._value = value || undefined;\n if (children) this._children = children;\n }\n\n protected _key: string;\n\n /**\n * The function returns the value of the protected variable _key.\n * @returns The value of the `_key` property, which is a string.\n */\n get key(): string {\n return this._key;\n }\n\n /**\n * The above function sets the value of a protected variable called \"key\".\n * @param {string} value - The value parameter is a string that represents the value to be assigned\n * to the key.\n */\n set key(value: string) {\n this._key = value;\n }\n\n protected _value?: V | undefined;\n\n /**\n * The function returns the value stored in a variable, or undefined if the variable is empty.\n * @returns The value of the variable `_value` is being returned.\n */\n get value(): V | undefined {\n return this._value;\n }\n\n /**\n * The function sets the value of a variable.\n * @param {V | undefined} value - The parameter \"value\" is of type \"V | undefined\", which means it\n * can accept a value of type \"V\" or it can be undefined.\n */\n set value(value: V | undefined) {\n this._value = value;\n }\n\n protected _children?: TreeNode<V>[] | undefined;\n\n /**\n * The function returns an array of TreeNode objects or undefined.\n * @returns The `children` property is being returned. It is of type `TreeNode<V>[] | undefined`,\n * which means it can either be an array of `TreeNode<V>` objects or `undefined`.\n */\n get children(): TreeNode<V>[] | undefined {\n return this._children;\n }\n\n /**\n * The function sets the value of the children property of a TreeNode object.\n * @param {TreeNode<V>[] | undefined} value - The value parameter is of type TreeNode<V>[] |\n * undefined. This means that it can accept an array of TreeNode objects or undefined.\n */\n set children(value: TreeNode<V>[] | undefined) {\n this._children = value;\n }\n\n /**\n * The function `addChildren` adds one or more child nodes to the current node.\n * @param {TreeNode<V> | TreeNode<V>[]} children - The `children` parameter can be either a single\n * `TreeNode<V>` object or an array of `TreeNode<V>` objects.\n */\n addChildren(children: TreeNode<V> | TreeNode<V>[]) {\n if (!this._children) {\n this._children = [];\n }\n if (children instanceof TreeNode) {\n this._children.push(children);\n } else {\n this._children = this._children.concat(children);\n }\n }\n\n /**\n * The function `getHeight()` calculates the maximum depth of a tree structure by performing a\n * breadth-first search.\n * @returns the maximum depth or height of the tree.\n */\n getHeight() {\n let maxDepth = 0;\n if (this) {\n const bfs = (node: TreeNode<V>, level: number) => {\n if (level > maxDepth) {\n maxDepth = level;\n }\n const { _children } = node;\n if (_children) {\n for (let i = 0, len = _children.length; i < len; i++) {\n bfs(_children[i], level + 1);\n }\n }\n };\n bfs(this, 0);\n }\n return maxDepth;\n }\n}\n"],"mappings":"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","names":["src_exports","__export","AVLTree","AVLTreeMultiMap","AVLTreeMultiMapNode","AVLTreeNode","AbstractEdge","AbstractGraph","AbstractVertex","BST","BSTNode","BinaryIndexedTree","BinaryTree","BinaryTreeNode","Character","DFSOperation","Deque","DirectedEdge","DirectedGraph","DirectedVertex","DoublyLinkedList","DoublyLinkedListNode","FibonacciHeap","FibonacciHeapNode","HashMap","Heap","IterableElementBase","IterableEntryBase","LinkedHashMap","LinkedListQueue","MapEdge","MapGraph","MapVertex","Matrix","MaxHeap","MaxPriorityQueue","MinHeap","MinPriorityQueue","Navigator","PriorityQueue","Queue","RedBlackTree","RedBlackTreeNode","SegmentTree","SegmentTreeNode","SinglyLinkedList","SinglyLinkedListNode","SkipList","SkipListNode","Stack","THUNK_SYMBOL","TreeMultiMap","TreeMultiMapNode","TreeNode","Trie","TrieNode","UndirectedEdge","UndirectedGraph","UndirectedVertex","arrayRemove","calcMinUnitsRequired","getMSB","isComparable","isThunk","isWeakKey","rangeCheck","roundFixed","throwRangeError","toBinaryString","toThunk","trampoline","trampolineAsync","uuidV4","IterableEntryBase","args","__yieldStar","item","predicate","thisArg","index","callbackfn","key","value","itemKey","elementValue","initialValue","accumulator","IterableElementBase","options","__publicField","toElementFn","args","__yieldStar","item","predicate","thisArg","index","callbackfn","element","ele","initialValue","accumulator","uuidV4","c","r","arrayRemove","array","predicate","i","len","result","value","THUNK_SYMBOL","isThunk","fnOrValue","toThunk","fn","thunk","trampoline","args","trampolineAsync","__async","getMSB","rangeCheck","index","min","max","message","throwRangeError","isWeakKey","input","inputType","calcMinUnitsRequired","totalQuantity","unitSize","roundFixed","num","digit","multiplier","isPrimitiveComparable","valueType","tryObjectToPrimitive","obj","valueOfResult","stringResult","isComparable","isForceObjectComparable","comparableValue","toBinaryString","num","digit","binaryString","HashMap","_HashMap","IterableEntryBase","entryOrRawElements","options","__publicField","key","hashFn","toEntryFn","rawElement","value","strKey","results","rawEle","item","_a","callbackfn","thisArg","resultMap","index","predicate","filteredMap","node","keyType","LinkedHashMap","_LinkedHashMap","objHashFn","isNewKey","isWeakKey","hash","rangeCheck","cloned","entry","callback","mappedMap","newValue","prev","next","SinglyLinkedListNode","value","__publicField","SinglyLinkedList","_SinglyLinkedList","IterableElementBase","elements","options","el","_a","data","singlyLinkedList","item","element","newNode","current","removedNode","index","i","prevNode","valueOrNode","prev","array","next","existingValueOrNode","newValue","existingValue","existingNode","count","callback","thisArg","filteredList","toElementFn","mappedList","DoublyLinkedListNode","value","__publicField","DoublyLinkedList","_DoublyLinkedList","IterableElementBase","elements","options","el","_a","data","element","newNode","removedNode","index","current","i","prevNode","nextNode","existingValueOrNode","newValue","existingNode","valOrNode","node","callback","next","array","thisArg","filteredList","toElementFn","mappedList","SkipListNode","key","value","level","__publicField","SkipList","elements","options","maxLevel","probability","firstNode","current","i","newNode","update","nextNode","lastLess","Stack","_Stack","IterableElementBase","elements","options","__publicField","el","element","index","predicate","thisArg","newStack","callback","toElementFn","i","Queue","_Queue","IterableElementBase","elements","options","__publicField","autoCompactRatio","el","v","element","first","index","predicate","thisArg","newDeque","callback","toElementFn","item","LinkedListQueue","_LinkedListQueue","SinglyLinkedList","Deque","_Deque","IterableElementBase","elements","options","__publicField","bucketSize","maxLen","_size","calcMinUnitsRequired","i","needBucketNum","el","element","index","pos","rangeCheck","bucketIndex","indexInBucket","num","length","arr","isCutSelf","newDeque","curBucket","curPointer","nextBucket","nextPointer","size","oldElement","bucket","_bucketFirst","_bucketLast","_firstInBucket","_lastInBucket","prev","cur","comparator","newBuckets","predicate","thisArg","callback","toElementFn","addBucketNum","overallIndex","Heap","_Heap","IterableElementBase","elements","options","__publicField","a","b","comparator","el","_a","element","value","last","index","order","result","_dfs","left","right","visitedNode","cloned","top","results","i","callback","thisArg","filteredList","current","toElementFn","mappedHeap","parent","parentItem","halfLength","minItem","FibonacciHeapNode","degree","FibonacciHeap","node","head","flag","z","heapToMerge","thisRoot","otherRoot","thisRootRight","otherRootLeft","y","x","A","d","t","MaxHeap","_MaxHeap","Heap","elements","options","__spreadValues","a","b","callback","thisArg","filteredList","index","current","comparator","toElementFn","mappedHeap","el","MinHeap","_MinHeap","Heap","elements","options","callback","thisArg","filteredList","index","current","comparator","toElementFn","mappedHeap","el","AbstractVertex","key","value","__publicField","AbstractEdge","weight","uuidV4","AbstractGraph","IterableEntryBase","v","vertexKey","vertexOrKey","keyOrVertex","newVertex","potentialKey","potentialKeyType","vertexMap","removed","v1","v2","srcOrEdge","dest","newEdge","srcOrKey","destOrKey","edge","limit","paths","vertex1","vertex2","stack","vertex","path","neighbors","neighbor","newPath","_a","sum","isWeight","allPaths","min","visited","queue","Queue","cost","i","cur","isDFS","_b","minIndex","index","pathSumWeight","minPath","dfs","visiting","src","getMinDist","genPaths","minDist","minDest","distMap","seen","preMap","srcVertex","destVertex","getMinOfNoSeen","minV","getPaths","parent","reversed","curFromMap","neighborFromMap","d","heap","Heap","a","b","curHeapNode","dist","distSrcToNeighbor","scanNegativeCycle","getMin","genPath","hasNegativeCycle","numOfVertices","edgeMap","numOfEdges","j","ends","s","sWeight","dWeight","idAndVertices","n","costs","predecessor","k","isInclude2Cycle","cycles","currentPath","uniqueCycles","cycle","sorted","cycleString","predicate","thisArg","filtered","callback","mapped","DirectedVertex","AbstractVertex","key","value","DirectedEdge","AbstractEdge","src","dest","weight","__publicField","DirectedGraph","_DirectedGraph","AbstractGraph","v","srcOrKey","destOrKey","edgeMap","srcOutEdges","edge","removed","arrayRemove","destInEdges","edgeOrSrcVertexKey","destVertexKey","vertexOrKey","vertexKey","vertex","neighbors","neighbor","v1","v2","v1ToV2","v2ToV1","target","destinations","outgoingEdges","outEdge","child","propertyName","statusMap","entry","sorted","hasCycle","dfs","cur","children","childStatus","outEdges","cloned","dfnMap","lowMap","SCCs","time","stack","inStack","SCC","poppedVertex","srcVertex","destVertex","UndirectedVertex","AbstractVertex","key","value","UndirectedEdge","AbstractEdge","v1","v2","weight","__publicField","UndirectedGraph","_UndirectedGraph","AbstractGraph","v","_a","edgeMap","vertex1","vertex2","e","v1Edges","removed","arrayRemove","v2Edges","edgeOrOneSideVertexKey","otherSideVertexKey","oneSide","otherSide","vertexOrKey","vertexKey","vertex","neighbors","neighbor","neighborEdges","restEdges","edge","edgeSet","cloned","dfnMap","lowMap","bridges","cutVertices","time","dfs","parent","childCount","end","endVertex","MapVertex","DirectedVertex","key","value","lat","long","__publicField","MapEdge","DirectedEdge","src","dest","weight","MapGraph","_MapGraph","DirectedGraph","originCoord","bottomRight","cloned","DFSOperation","BinaryTreeNode","key","value","__publicField","v","that","BinaryTree","_BinaryTree","IterableEntryBase","keysOrNodesOrEntriesOrRaws","options","node","iterationType","toEntryFn","__spreadValues","keyOrNodeOrEntryOrRaw","entryValue","isComparable","newNode","queue","Queue","potentialParent","cur","values","inserted","valuesIterator","valueResult","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","keyOrNodeOrEntryOrRawOrPredicate","onlyOne","beginRoot","callback","ans","dfs","stack","_a","min","max","numKey","isStandardBST","isInverseBST","checkBST","checkMax","prev","dist","distEnsured","beginRootEnsured","depth","_getMaxHeight","leftHeight","rightHeight","maxHeight","_getMinHeight","leftMinHeight","rightMinHeight","last","depths","beginNode","isReverse","result","beginNodeEnsured","trampoline","predecessor","x","y","pattern","includeNull","level","current","levelSize","i","leaves","levelsNodes","_recursive","head","_reverseEdge","pre","next","_printEdge","tail","cloned","predicate","thisArg","newTree","index","opts","output","root","lines","paragraph","line","shouldVisitLeft","shouldVisitRight","shouldVisitRoot","shouldProcessRoot","visitLeft","visitRight","pushLeft","pushRight","pushRoot","__yieldStar","isShowNull","isShowUndefined","isShowRedBlackNIL","emptyDisplayLayout","width","_buildNodeDisplay","left","right","leftLines","leftWidth","leftMiddle","rightLines","rightWidth","rightMiddle","firstLine","secondLine","mergedLines","leftLine","rightLine","srcNode","destNode","tempNode","oldNode","keyOrEntryOrRawOrPredicate","p","BSTNode","BinaryTreeNode","key","value","__publicField","v","BST","_BST","BinaryTree","keysOrNodesOrEntriesOrRaws","options","a","b","comparator","__spreadValues","keyOrNodeOrEntryOrRaw","_a","iterationType","isComparable","newNode","current","values","isBalanceAdd","inserted","valuesIterator","kve","realBTNExemplars","i","sorted","keyA","keyB","_dfs","arr","mid","orgIndex","stack","popped","l","r","m","predicate","onlyOne","beginRoot","callback","ans","dfs","cur","pattern","lesserOrGreater","targetNode","targetNodeEnsured","targetKey","compared","queue","Queue","node","n","buildBalanceBST","midNode","balanced","_height","leftHeight","rightHeight","last","depths","left","right","BinaryIndexedTree","frequency","max","__publicField","getMSB","index","position","change","freqCur","freq","count","sum","x","y","i","delta","z","freqNew","before","left","right","sumT","middle","sumM","SegmentTreeNode","start","end","sum","value","__publicField","SegmentTree","values","mid","left","right","cur","index","root","dfs","indexA","indexB","i","j","leftSum","rightSum","AVLTreeNode","BSTNode","key","value","__publicField","AVLTree","_AVLTree","BST","keysOrNodesOrEntriesOrRaws","options","__spreadValues","keyOrNodeOrEntryOrRaw","inserted","deletedResults","needBalanced","srcNode","destNode","srcNodeEnsured","destNodeEnsured","height","tempNode","node","rightHeight","A","parentOfA","B","C","path","i","oldNode","newNode","RedBlackTreeNode","BSTNode","key","value","color","__publicField","RedBlackTree","_RedBlackTree","BST","keysOrNodesOrEntriesOrRaws","options","__spreadValues","keyOrNodeOrEntryOrRaw","newNode","insertStatus","results","nodeToDelete","originalColor","replacementNode","successor","node","v","oldNode","_a","_b","current","parent","compared","u","z","_c","_d","y","sibling","x","AVLTreeMultiMapNode","AVLTreeNode","key","value","count","__publicField","AVLTreeMultiMap","_AVLTreeMultiMap","AVLTree","keysOrNodesOrEntriesOrRaws","options","sum","node","__spreadValues","keyOrNodeOrEntryOrRaw","entryValue","newNode","orgNodeCount","ignoreCount","_a","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","iterationType","sorted","n","buildBalanceBST","l","r","m","midNode","stack","popped","cloned","srcNode","destNode","height","tempNode","oldNode","TreeMultiMapNode","RedBlackTreeNode","key","value","count","color","__publicField","TreeMultiMap","_TreeMultiMap","RedBlackTree","keysOrNodesOrEntriesOrRaws","options","sum","node","__spreadValues","keyOrNodeOrEntryOrRaw","entryValue","newNode","orgCount","ignoreCount","results","nodeToDelete","originalColor","replacementNode","successor","iterationType","sorted","n","buildBalanceBST","l","r","m","midNode","stack","popped","cloned","srcNode","destNode","tempNode","oldNode","PriorityQueue","_PriorityQueue","Heap","elements","options","callback","thisArg","filteredPriorityQueue","index","current","comparator","toElementFn","mappedPriorityQueue","el","MinPriorityQueue","_MinPriorityQueue","PriorityQueue","elements","options","callback","thisArg","filteredPriorityQueue","index","current","comparator","toElementFn","mappedPriorityQueue","el","MaxPriorityQueue","_MaxPriorityQueue","PriorityQueue","elements","options","__spreadValues","a","b","callback","thisArg","filteredPriorityQueue","index","current","comparator","toElementFn","mappedPriorityQueue","el","Matrix","_Matrix","data","options","__publicField","_a","_b","_c","rows","cols","addFn","subtractFn","multiplyFn","i","row","col","value","matrix","resultData","j","a","b","added","subtracted","sum","k","multiplied","trans","augmentedMatrixData","augmentedMatrix","pivotRow","pivotElement","factor","inverseData","row1","row2","temp","scalar","targetRow","sourceRow","scaledValue","Character","_Character","direction","turning","__publicField","Navigator","matrix","onMove","cur","charDir","VISITED","forward","row","j","i","TrieNode","key","__publicField","value","Trie","_Trie","IterableElementBase","words","options","caseSensitive","word","cur","isNewWord","c","nodeC","isDeleted","dfs","i","char","child","beginRoot","maxDepth","bfs","node","level","children","input","commonPre","prefix","max","isAllWhenEmptyPrefix","found","charNode","startNode","predicate","thisArg","results","index","callback","toElementFn","newTrie","_dfs","path","childNode","__yieldStar","str","TreeNode","_TreeNode","key","value","children","__publicField","maxDepth","bfs","node","level","_children","i","len"]}