data-structure-typed 1.49.3 → 1.49.4
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.
- package/CHANGELOG.md +1 -1
- package/README.md +69 -66
- package/README_zh-CN.md +43 -48
- package/benchmark/report.html +16 -16
- package/benchmark/report.json +187 -187
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/graph/abstract-graph.d.ts +1 -10
- package/dist/cjs/data-structures/graph/abstract-graph.js +0 -17
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/directed-graph.js +4 -0
- package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
- package/dist/cjs/data-structures/linked-list/singly-linked-list.js.map +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +1 -1
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +1 -1
- package/dist/mjs/data-structures/graph/abstract-graph.d.ts +1 -10
- package/dist/mjs/data-structures/graph/abstract-graph.js +0 -17
- package/dist/mjs/data-structures/graph/directed-graph.js +4 -0
- package/dist/umd/data-structure-typed.js +5 -18
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/binary-tree/binary-tree.ts +1 -1
- package/src/data-structures/graph/abstract-graph.ts +1 -13
- package/src/data-structures/graph/directed-graph.ts +7 -3
- package/src/data-structures/graph/undirected-graph.ts +1 -1
- package/src/data-structures/linked-list/singly-linked-list.ts +1 -2
- package/test/performance/data-structures/comparison/comparison.test.ts +12 -12
- package/test/performance/data-structures/linked-list/doubly-linked-list.test.ts +16 -27
- package/test/performance/data-structures/linked-list/singly-linked-list.test.ts +4 -12
- package/test/performance/data-structures/queue/deque.test.ts +8 -8
- package/test/performance/data-structures/queue/queue.test.ts +5 -5
- package/test/performance/data-structures/stack/stack.test.ts +11 -11
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +15 -0
- package/test/unit/data-structures/graph/abstract-graph.test.ts +11 -0
- package/test/unit/data-structures/graph/directed-graph.test.ts +15 -2
- package/test/unit/data-structures/graph/undirected-graph.test.ts +13 -0
- package/test/unit/data-structures/hash/hash-map.test.ts +21 -0
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +27 -0
- package/test/utils/big-o.ts +14 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/data-structures/hash/hash-table.ts","../../src/data-structures/base/iterable-base.ts","../../src/utils/utils.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/types/data-structures/binary-tree/rb-tree.ts","../../src/types/common.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/tree-multimap.ts","../../src/data-structures/tree/tree.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/vector2d.ts","../../src/data-structures/matrix/matrix2d.ts","../../src/data-structures/matrix/navigator.ts","../../src/data-structures/trie/trie.ts"],"sourcesContent":["export * from './data-structures';\nexport * from './utils';\nexport * from './interfaces';\nexport * from './types';\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 */\n\nimport type { HashFunction } from '../../types';\n\nexport class HashTableNode<K = any, V = any> {\n key: K;\n value: V;\n next: HashTableNode<K, V> | undefined;\n\n constructor(key: K, value: V) {\n this.key = key;\n this.value = value;\n this.next = undefined;\n }\n}\n\nexport class HashTable<K = any, V = any> {\n protected static readonly DEFAULT_CAPACITY = 16;\n protected static readonly LOAD_FACTOR = 0.75;\n\n constructor(capacity: number = HashTable.DEFAULT_CAPACITY, hashFn?: HashFunction<K>) {\n this._hashFn = hashFn || this._defaultHashFn;\n this._capacity = Math.max(capacity, HashTable.DEFAULT_CAPACITY);\n this._size = 0;\n this._buckets = new Array<HashTableNode<K, V> | undefined>(this._capacity).fill(undefined);\n }\n\n protected _capacity: number;\n\n get capacity(): number {\n return this._capacity;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n protected _buckets: Array<HashTableNode<K, V> | undefined>;\n\n get buckets(): Array<HashTableNode<K, V> | undefined> {\n return this._buckets;\n }\n\n protected _hashFn: HashFunction<K>;\n\n get hashFn(): HashFunction<K> {\n return this._hashFn;\n }\n\n /**\n * The set function adds a key-value pair to the hash table, handling collisions and resizing if necessary.\n * @param {K} key - The key parameter represents the key of the key-value pair that you want to insert into the hash\n * table. It is of type K, which is a generic type representing the key's data type.\n * @param {V} value - The parameter `value` represents the value that you want to associate with the given key in the hash\n * table.\n * @returns Nothing is being returned. The return type of the `put` method is `void`, which means it does not return any\n * value.\n */\n set(key: K, value: V): void {\n const index = this._hash(key);\n const newNode = new HashTableNode<K, V>(key, value);\n\n if (!this._buckets[index]) {\n this._buckets[index] = newNode;\n } else {\n // Handle collisions, consider using open addressing, etc.\n let currentNode = this._buckets[index]!;\n while (currentNode) {\n if (currentNode.key === key) {\n // If the key already exists, update the value\n currentNode.value = value;\n return;\n }\n if (!currentNode.next) {\n break;\n }\n currentNode = currentNode.next;\n }\n // Add to the end of the linked list\n currentNode.next = newNode;\n }\n this._size++;\n\n // If the load factor is too high, resize the hash table\n if (this._size / this._capacity >= HashTable.LOAD_FACTOR) {\n this._expand();\n }\n }\n\n /**\n * The `get` function retrieves the value associated with a given key from a hash table.\n * @param {K} key - The `key` parameter represents the key of the element that we want to retrieve from the data\n * structure.\n * @returns The method is returning the value associated with the given key if it exists in the hash table. If the key is\n * not found, it returns `undefined`.\n */\n get(key: K): V | undefined {\n const index = this._hash(key);\n let currentNode = this._buckets[index];\n\n while (currentNode) {\n if (currentNode.key === key) {\n return currentNode.value;\n }\n currentNode = currentNode.next;\n }\n return undefined; // Key not found\n }\n\n /**\n * The delete function removes a key-value pair from a hash table.\n * @param {K} key - The `key` parameter represents the key of the key-value pair that needs to be removed from the hash\n * table.\n * @returns Nothing is being returned. The `delete` method has a return type of `void`, which means it does not return\n * any value.\n */\n delete(key: K): void {\n const index = this._hash(key);\n let currentNode = this._buckets[index];\n let prevNode: HashTableNode<K, V> | undefined = undefined;\n\n while (currentNode) {\n if (currentNode.key === key) {\n if (prevNode) {\n prevNode.next = currentNode.next;\n } else {\n this._buckets[index] = currentNode.next;\n }\n this._size--;\n currentNode.next = undefined; // Release memory\n return;\n }\n prevNode = currentNode;\n currentNode = currentNode.next;\n }\n }\n\n * [Symbol.iterator](): Generator<[K, V], void, undefined> {\n for (const bucket of this._buckets) {\n let currentNode = bucket;\n while (currentNode) {\n yield [currentNode.key, currentNode.value];\n currentNode = currentNode.next;\n }\n }\n }\n\n forEach(callback: (entry: [K, V], index: number, table: HashTable<K, V>) => void): void {\n let index = 0;\n for (const entry of this) {\n callback(entry, index, this);\n index++;\n }\n }\n\n filter(predicate: (entry: [K, V], index: number, table: HashTable<K, V>) => boolean): HashTable<K, V> {\n const newTable = new HashTable<K, V>();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate([key, value], index, this)) {\n newTable.set(key, value);\n }\n index++;\n }\n return newTable;\n }\n\n map<T>(callback: (entry: [K, V], index: number, table: HashTable<K, V>) => T): HashTable<K, T> {\n const newTable = new HashTable<K, T>();\n let index = 0;\n for (const [key, value] of this) {\n newTable.set(key, callback([key, value], index, this));\n index++;\n }\n return newTable;\n }\n\n reduce<T>(callback: (accumulator: T, entry: [K, V], index: number, table: HashTable<K, V>) => T, initialValue: T): T {\n let accumulator = initialValue;\n let index = 0;\n for (const entry of this) {\n accumulator = callback(accumulator, entry, index, this);\n index++;\n }\n return accumulator;\n }\n\n /**\n * The function `_defaultHashFn` calculates the hash value of a given key and returns the remainder when divided by the\n * capacity of the data structure.\n * @param {K} key - The `key` parameter is the input value that needs to be hashed. It can be of any type, but in this\n * code snippet, it is checked whether the key is a string or an object. If it is a string, the `_murmurStringHashFn`\n * function is used to\n * @returns the hash value of the key modulo the capacity of the data structure.\n */\n protected _defaultHashFn(key: K): number {\n // Can be replaced with other hash functions as needed\n const hashValue = typeof key === 'string' ? this._murmurStringHashFn(key) : this._objectHash(key);\n return hashValue % this._capacity;\n }\n\n /**\n * The `_multiplicativeStringHashFn` function calculates a hash value for a given string key using the multiplicative\n * string hash function.\n * @param {K} key - The `key` parameter is the input value for which we want to calculate the hash. It can be of any\n * type, as it is generic (`K`). The function converts the `key` to a string using the `String()` function.\n * @returns a number, which is the result of the multiplicative string hash function applied to the input key.\n */\n protected _multiplicativeStringHashFn<K>(key: K): number {\n const keyString = String(key);\n let hash = 0;\n for (let i = 0; i < keyString.length; i++) {\n const charCode = keyString.charCodeAt(i);\n // Some constants for adjusting the hash function\n const A = 0.618033988749895;\n const M = 1 << 30; // 2^30\n hash = (hash * A + charCode) % M;\n }\n return Math.abs(hash); // Take absolute value to ensure non-negative numbers\n }\n\n /**\n * The function `_murmurStringHashFn` calculates a hash value for a given string key using the MurmurHash algorithm.\n * @param {K} key - The `key` parameter is the input value for which you want to calculate the hash. It can be of any\n * type, but it will be converted to a string using the `String()` function before calculating the hash.\n * @returns a number, which is the hash value calculated for the given key.\n */\n protected _murmurStringHashFn<K>(key: K): number {\n const keyString = String(key);\n const seed = 0;\n let hash = seed;\n\n for (let i = 0; i < keyString.length; i++) {\n const char = keyString.charCodeAt(i);\n hash = (hash ^ char) * 0x5bd1e995;\n hash = (hash ^ (hash >>> 15)) * 0x27d4eb2d;\n hash = hash ^ (hash >>> 15);\n }\n\n return Math.abs(hash);\n }\n\n /**\n * The _hash function takes a key and returns a number.\n * @param {K} key - The parameter \"key\" is of type K, which represents the type of the key that will be hashed.\n * @returns The hash function is returning a number.\n */\n protected _hash(key: K): number {\n return this.hashFn(key);\n }\n\n /**\n * The function calculates a hash value for a given string using the djb2 algorithm.\n * @param {string} key - The `key` parameter in the `stringHash` function is a string value that represents the input for\n * which we want to calculate the hash value.\n * @returns a number, which is the hash value of the input string.\n */\n protected _stringHash(key: string): number {\n let hash = 0;\n for (let i = 0; i < key.length; i++) {\n hash = (hash * 31 + key.charCodeAt(i)) & 0xffffffff;\n }\n return hash;\n }\n\n /**\n * The function `_objectHash` takes a key and returns a hash value, using a custom hash function for objects.\n * @param {K} key - The parameter \"key\" is of type \"K\", which means it can be any type. It could be a string, number,\n * boolean, object, or any other type of value. The purpose of the objectHash function is to generate a hash value for\n * the key, which can be used for\n * @returns a number, which is the hash value of the key.\n */\n protected _objectHash(key: K): number {\n // If the key is an object, you can write a custom hash function\n // For example, convert the object's properties to a string and use string hashing\n // This is just an example; you should write a specific object hash function as needed\n return this._stringHash(JSON.stringify(key));\n }\n\n /**\n * The `expand` function increases the capacity of a hash table by creating a new array of buckets with double the\n * capacity and rehashing all the existing key-value pairs into the new buckets.\n */\n protected _expand(): void {\n const newCapacity = this._capacity * 2;\n const newBuckets = new Array<HashTableNode<K, V> | undefined>(newCapacity).fill(undefined);\n\n for (const bucket of this._buckets) {\n let currentNode = bucket;\n while (currentNode) {\n const newIndex = this._hash(currentNode.key);\n const newNode = new HashTableNode<K, V>(currentNode.key, currentNode.value);\n\n if (!newBuckets[newIndex]) {\n newBuckets[newIndex] = newNode;\n } else {\n let currentNewNode = newBuckets[newIndex]!;\n while (currentNewNode.next) {\n currentNewNode = currentNewNode.next;\n }\n currentNewNode.next = newNode;\n }\n currentNode = currentNode.next;\n }\n }\n\n this._buckets = newBuckets;\n this._capacity = newCapacity;\n }\n}\n","import { ElementCallback, EntryCallback, ReduceElementCallback, ReduceEntryCallback } from \"../../types\";\n\nexport abstract class IterableEntryBase<K = any, V = any> {\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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 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 /**\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 /**\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 /**\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 /**\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 /**\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 /**\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 /**\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 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(n)\n */\n print(): void {\n console.log([...this])\n }\n\n protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;\n}\n\nexport abstract class IterableElementBase<V> {\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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<V> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(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<V> {\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 /**\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<V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item as V, 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 /**\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<V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item as V, 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 /**\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<V, void>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n callbackfn.call(thisArg, item as V, index++, this)\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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<V, U>, initialValue: U): U {\n let accumulator = initialValue;\n let index = 0;\n for (const item of this) {\n accumulator = callbackfn(accumulator, item as V, index++, this)\n }\n return accumulator;\n }\n\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n */\n print(): void {\n console.log([...this])\n }\n\n protected abstract _getIterator(...args: any[]): IterableIterator<V>;\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 { Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';\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\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\nexport const isThunk = (fnOrValue: any) => {\n return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL;\n};\n\nexport const toThunk = (fn: ToThunkFn): Thunk => {\n const thunk = () => fn();\n thunk.__THUNK__ = THUNK_SYMBOL;\n return thunk;\n};\n\nexport const trampoline = (fn: TrlFn) => {\n const cont = (...args: [...Parameters<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\nexport const trampolineAsync = (fn: TrlAsyncFn) => {\n const cont = (...args: [...Parameters<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\nexport const getMSB = (value: number): number => {\n if (value <= 0) {\n return 0;\n }\n return 1 << (31 - Math.clz32(value));\n};\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\nexport const throwRangeError = (message = 'The value is off-limits.'): void => {\n throw new RangeError(message);\n};\n\nexport const isWeakKey = (input: unknown): input is object => {\n const inputType = typeof input;\n return (inputType === 'object' && input !== null) || inputType === 'function';\n};\n\nexport const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) => Math.floor((totalQuantity + unitSize - 1) / unitSize)\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 { EntryCallback, HashMapLinkedNode, HashMapOptions, HashMapStoreItem } 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 maps to a value.\n * 2. Fast Lookup: It's used when you need to quickly find, insert, or delete elements based on a key.\n * 3. Unique Keys: Keys are unique. If you try to insert another entry with the same key, the old entry will be replaced by the new one.\n * 4. Unordered Collection: HashMap does not guarantee the order of elements, and the order may change over time.\n */\nexport class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {\n protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};\n protected _objMap: Map<object, V> = new Map();\n\n /**\n * The constructor function initializes a new instance of a class with optional elements and options.\n * @param elements - The `elements` parameter is an iterable containing key-value pairs `[K, V]`. It\n * is optional and defaults to an empty array `[]`. This parameter is used to initialize the map with\n * key-value pairs.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the constructor. In this case, it has one property:\n */\n constructor(elements: Iterable<[K, V]> = [], options?: {\n hashFn: (key: K) => string\n }) {\n super();\n if (options) {\n const { hashFn } = options;\n if (hashFn) {\n this._hashFn = hashFn;\n }\n }\n if (elements) {\n this.setMany(elements);\n }\n }\n\n protected _size = 0;\n\n get size(): number {\n return this._size;\n }\n\n isEmpty(): boolean {\n return this.size === 0;\n }\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\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\" sets multiple key-value pairs in a map.\n * @param elements - The `elements` parameter is an iterable containing key-value pairs. Each\n * key-value pair is represented as an array with two elements: the key and the value.\n */\n setMany(elements: Iterable<[K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const [key, value] of elements) results.push(this.set(key, value));\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 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 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\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<U>(callbackfn: EntryCallback<K, V, U>, thisArg?: any): HashMap<K, U> {\n const resultMap = new HashMap<K, U>();\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\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 print(): void {\n console.log([...this.entries()]);\n }\n\n put(key: K, value: V): boolean {\n return this.set(key, value);\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 protected _hashFn: (key: K) => string = (key: K) => String(key);\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 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 elements are inserted. Therefore, when you traverse it, elements 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 elements 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> extends IterableEntryBase<K, V> {\n\n protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};\n protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();\n protected _head: HashMapLinkedNode<K, V | undefined>;\n protected _tail: HashMapLinkedNode<K, V | undefined>;\n protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;\n protected _hashFn: (key: K) => string;\n protected _objHashFn: (key: K) => object;\n\n\n constructor(elements?: Iterable<[K, V]>, options: HashMapOptions<K> = {\n\n hashFn: (key: K) => String(key),\n objHashFn: (key: K) => (<object>key)\n }) {\n super();\n this._sentinel = <HashMapLinkedNode<K, V>>{};\n this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;\n\n const { hashFn, objHashFn } = options;\n this._hashFn = hashFn;\n this._objHashFn = objHashFn;\n if (elements) {\n for (const el of elements) {\n this.set(el[0], el[1]);\n }\n }\n }\n\n protected _size = 0;\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 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 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 setMany(entries: Iterable<[K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const entry of entries) {\n const [key, value] = entry;\n results.push(this.set(key, value));\n }\n return results;\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 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), where n is the index.\n * Space Complexity: O(1)\n *\n * The function `getAt` 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 `getAt(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 getAt(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), where n is the index.\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 * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function clears all the elements 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 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\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\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<NV>(callback: EntryCallback<K, V, NV>, thisArg?: any): LinkedHashMap<K, NV> {\n const mappedMap = new LinkedHashMap<K, NV>();\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 put(key: K, value: V): boolean {\n return this.set(key, value);\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the LinkedHashMap.\n * Space Complexity: O(1)\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback } from \"../../types\";\nimport { IterableElementBase } from \"../base\";\n\nexport class SinglyLinkedListNode<E = any> {\n value: E;\n next: SinglyLinkedListNode<E> | undefined;\n\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\nexport class SinglyLinkedList<E = any> extends IterableElementBase<E> {\n /**\n * The constructor initializes the linked list with an empty head, tail, and length.\n */\n constructor(elements?: Iterable<E>) {\n super();\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n if (elements) {\n for (const el of elements)\n this.push(el);\n }\n }\n\n protected _head: SinglyLinkedListNode<E> | undefined;\n\n get head(): SinglyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: SinglyLinkedListNode<E> | undefined;\n\n get tail(): SinglyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the input array, as it performs a loop to push each element into the linked list.\n * Space Complexity: O(n) - Linear space, as it creates a new node for each element in the array.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the input array, as it performs a loop to push each element into the linked list.\n * Space Complexity: O(n) - Linear space, as it creates a new node for each element in the array.\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) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n *\n * The `push` function adds a new node with the given value to the end of a singly linked list.\n * @param {E} value - The \"value\" parameter represents the value that you want to add to the linked list. It can be of\n * any type (E) as specified in the generic type declaration of the class or function.\n */\n push(value: E): boolean {\n const newNode = new SinglyLinkedListNode(value);\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(1) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n *\n * The `push` function adds a new node with the given value to the end of a singly linked list.\n * @param {E} value - The \"value\" parameter represents the value that you want to add to the linked list. It can be of\n * any type (E) as specified in the generic type declaration of the class or function.\n */\n addLast(value: E): boolean {\n return this.push(value);\n }\n\n /**\n * Time Complexity: O(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n *\n * The `pop()` function removes and returns the value of the last element in a linked list, updating the head and tail\n * pointers accordingly.\n * @returns The method `pop()` returns the value of the node that is being removed from the end of the linked list. If\n * the linked list is empty, it returns `undefined`.\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(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n *\n * The `pollLast()` function removes and returns the value of the last element in a linked list, updating the head and tail\n * pointers accordingly.\n * @returns The method `pop()` returns the value of the node that is being removed from the end of the linked list. If\n * the linked list is empty, it returns `undefined`.\n */\n pollLast(): E | undefined {\n return this.pop();\n }\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The `shift()` function removes and returns the value of the first node in a linked list.\n * @returns The value of the node that is being removed from the beginning of the linked list.\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) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The `pollFirst()` function removes and returns the value of the first node in a linked list.\n * @returns The value of the node that is being removed from the beginning of the linked list.\n */\n pollFirst(): E | undefined {\n return this.shift();\n }\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The unshift function adds a new node with the given value to the beginning of a singly linked list.\n * @param {E} value - The parameter \"value\" represents the value of the new node that will be added to the beginning of the\n * linked list.\n */\n unshift(value: E): boolean {\n const newNode = new SinglyLinkedListNode(value);\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(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The addFirst function adds a new node with the given value to the beginning of a singly linked list.\n * @param {E} value - The parameter \"value\" represents the value of the new node that will be added to the beginning of the\n * linked list.\n */\n addFirst(value: E): boolean {\n return this.unshift(value);\n }\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n *\n * The function `getAt` 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 `getAt(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 getAt(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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) 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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to traverse the entire list to convert it to an array.\n * Space Complexity: O(n) - Linear space, as it creates an array with the same length as the list.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to traverse the entire list to convert it to an array.\n * Space Complexity: O(n) - Linear space, as it creates an array with the same length as the list.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n *\n * The `find` function iterates through a linked list and returns the first element that satisfies a given condition.\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 particular value in the linked list satisfies a certain condition.\n * @returns The method `find` returns the first element in the linked list that satisfies the condition specified by\n * the callback function. If no element satisfies the condition, it returns `undefined`.\n */\n find(callback: (value: E) => boolean): E | undefined {\n let current = this.head;\n while (current) {\n if (callback(current.value)) {\n return current.value;\n }\n current = current.next;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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\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, boolean>, thisArg?: any): SinglyLinkedList<E> {\n const filteredList = new SinglyLinkedList<E>();\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 /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\n */\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new SinglyLinkedList by applying a callback function to each element\n * of the original list.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the linked list. It takes three arguments:\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 `map` function is returning a new `SinglyLinkedList` object that contains the results\n * of applying the provided `callback` function to each element in the original list.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): SinglyLinkedList<T> {\n const mappedList = new SinglyLinkedList<T>();\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 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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback } from '../../types';\nimport { IterableElementBase } from '../base';\n\nexport class DoublyLinkedListNode<E = any> {\n value: E;\n next: DoublyLinkedListNode<E> | undefined;\n prev: DoublyLinkedListNode<E> | undefined;\n\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\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> extends IterableElementBase<E> {\n /**\n * The constructor initializes the linked list with an empty head, tail, and size.\n */\n constructor(elements?: Iterable<E>) {\n super();\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n if (elements) {\n for (const el of elements) {\n this.push(el);\n }\n }\n }\n\n protected _head: DoublyLinkedListNode<E> | undefined;\n\n get head(): DoublyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: DoublyLinkedListNode<E> | undefined;\n\n get tail(): DoublyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(n), where n is the size of the input array.\n * Space Complexity: O(n)\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 * 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\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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(1)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n), where n is the size of the input array.\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 const doublyLinkedList = new DoublyLinkedList<E>();\n for (const item of data) {\n doublyLinkedList.push(item);\n }\n return doublyLinkedList;\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 push function adds a new node with the given value to the end of the doubly linked list.\n * @param {E} value - The value to be added to the linked list.\n */\n push(value: E): boolean {\n const newNode = new DoublyLinkedListNode(value);\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop()` function removes and returns the value of the last node in a doubly linked list.\n * @returns The method is returning the value of the removed node (removedNode.value) if the list is not empty. If the\n * list is empty, it returns undefined.\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 node in a doubly linked list.\n * @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked\n * list.\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The unshift function adds a new node with the given value to the beginning of a doubly linked list.\n * @param {E} value - The `value` parameter represents the value of the new node that will be added to the beginning of the\n * doubly linked list.\n */\n unshift(value: E): boolean {\n const newNode = new DoublyLinkedListNode(value);\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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * The `getAt` 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 getAt(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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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), where n is the number of elements in the linked list.\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(n), where n is the number of elements in the linked list.\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n */\n\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n */\n\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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * The `find` function iterates through a linked list and returns the first element that satisfies a given condition.\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 particular value in the linked list satisfies a certain condition.\n * @returns The method `find` returns the first element in the linked list that satisfies the condition specified by\n * the callback function. If no element satisfies the condition, it returns `undefined`.\n */\n find(callback: (value: E) => boolean): E | undefined {\n let current = this.head;\n while (current) {\n if (callback(current.value)) {\n return current.value;\n }\n current = current.next;\n }\n return 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\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\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 * 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), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\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 * 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\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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(1)\n * Space Complexity: O(1)\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, boolean>, thisArg?: any): DoublyLinkedList<E> {\n const filteredList = new DoublyLinkedList<E>();\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(1)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new DoublyLinkedList by applying a callback function to each element\n * in the original list.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * DoublyLinkedList. It takes three arguments: the current element, the index of the current element,\n * and the DoublyLinkedList itself. The callback function should return a value that will be added to\n * the new DoublyLinkedList that\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 `map` function is returning a new `DoublyLinkedList` object that contains the results\n * of applying the provided `callback` function to each element in the original `DoublyLinkedList`\n * object.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): DoublyLinkedList<T> {\n const mappedList = new DoublyLinkedList<T>();\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 * 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 addLast function adds a new node with the given value to the end of the doubly linked list.\n * @param {E} value - The value to be added to the linked list.\n */\n addLast(value: E): boolean {\n return this.push(value);\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 `pollLast()` function removes and returns the value of the last node in a doubly linked list.\n * @returns The method is returning the value of the removed node (removedNode.value) if the list is not empty. If the\n * list is empty, it returns undefined.\n */\n pollLast(): E | undefined {\n return this.pop();\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pollFirst()` function removes and returns the value of the first node in a doubly linked list.\n * @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked\n * list.\n */\n pollFirst(): E | undefined {\n return this.shift();\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The addFirst function adds a new node with the given value to the beginning of a doubly linked list.\n * @param {E} value - The `value` parameter represents the value of the new node that will be added to the beginning of the\n * doubly linked list.\n */\n addFirst(value: E): void {\n this.unshift(value);\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\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 initializes a SkipList with a specified maximum level and probability.\n * @param [maxLevel=16] - The `maxLevel` parameter represents the maximum level that a skip list can have. It determines\n * the maximum number of levels that can be created in the skip list.\n * @param [probability=0.5] - The probability parameter represents the probability of a node being promoted to a higher\n * level in the skip list. It is used to determine the height of each node in the skip list.\n */\n constructor(maxLevel = 16, probability = 0.5) {\n this._head = new SkipListNode<K, V>(undefined as any, undefined as any, maxLevel);\n this._level = 0;\n this._maxLevel = maxLevel;\n this._probability = probability;\n }\n\n protected _head: SkipListNode<K, V>;\n\n get head(): SkipListNode<K, V> {\n return this._head;\n }\n\n protected _level: number;\n\n get level(): number {\n return this._level;\n }\n\n protected _maxLevel: number;\n\n get maxLevel(): number {\n return this._maxLevel;\n }\n\n protected _probability: number;\n\n get probability(): number {\n return this._probability;\n }\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n has(key: K): boolean {\n return this.get(key) !== undefined;\n }\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where maxLevel is the maximum level of the SkipList, as it may iterate up to maxLevel times in the worst case.\n * Space Complexity: O(1) - constant space.\n */\n\n /**\n * Time Complexity: O(maxLevel) - where maxLevel is the maximum level of the SkipList, as it may iterate up to maxLevel times in the worst case.\n * Space Complexity: O(1) - constant space.\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback } 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> extends IterableElementBase<E> {\n /**\n * The constructor initializes an array of elements, which can be provided as an optional parameter.\n * @param {E[]} [elements] - The `elements` parameter is an optional parameter of type `E[]`, which represents an array\n * of elements of type `E`. It is used to initialize the `_elements` property of the class. If the `elements` parameter\n * is provided and is an array, it is assigned to the `_elements\n */\n constructor(elements?: Iterable<E>) {\n super();\n this._elements = [];\n if (elements) {\n for (const el of elements) {\n this.push(el);\n }\n }\n }\n\n protected _elements: E[];\n\n get elements(): E[] {\n return this._elements;\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the input array. Similar to the constructor, it requires iterating through each element.\n * Space Complexity: O(n), as it creates a new stack with the elements from the input array.\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), where n is the number of elements in the input array. Similar to the constructor, it requires iterating through each element.\n * Space Complexity: O(n), as it creates a new stack with the elements from the input array.\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), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\n */\n\n /**\n * Time Complexity: O(1), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\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), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\n */\n\n /**\n * Time Complexity: O(1), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\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), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\n */\n\n /**\n * Time Complexity: O(1), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\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 * 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 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 * The clear function clears the elements array.\n */\n clear(): void {\n this._elements = [];\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the stack, as it creates a new stack and copies all elements into it.\n * Space Complexity: O(n), as it creates a new stack.\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the stack, as it creates a new stack and copies all elements into it.\n * Space Complexity: O(n), as it creates a new stack.\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> {\n return new Stack(this.elements.slice());\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 `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, boolean>, thisArg?: any): Stack<E> {\n const newStack = new Stack<E>();\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\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\n * the stack. It takes three arguments:\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 `map` method is returning a new `Stack` object.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): Stack<T> {\n const newStack = new Stack<T>();\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 * 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 Tyler Zeng <zrwusa@gmail.com>\n * @class\n */\nimport type { ElementCallback } 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 nodes that are to be visited.\n * 7. Real-time Queuing: Like queuing systems in banks or supermarkets.\n */\nexport class Queue<E = any> extends IterableElementBase<E> {\n /**\n * The constructor initializes an instance of a class with an optional array of elements and sets the offset to 0.\n * @param {E[]} [elements] - The `elements` parameter is an optional array of elements of type `E`. If provided, it\n * will be used to initialize the `_nodes` property of the class. If not provided, the `_nodes` property will be\n * initialized as an empty array.\n */\n constructor(elements?: E[]) {\n super();\n this._nodes = elements || [];\n this._offset = 0;\n }\n\n protected _nodes: E[];\n\n get nodes(): E[] {\n return this._nodes;\n }\n\n protected _offset: number;\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.nodes.length - this.offset;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The `first` function returns the first element of the array `_nodes` if it exists, otherwise it returns `undefined`.\n * @returns The `get first()` method returns the first element of the data structure, represented by the `_nodes` 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.nodes[this.offset] : undefined;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it adds an element to the end of the array.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\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 `_nodes` 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.nodes[this.nodes.length - 1] : undefined;\n }\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. In the worst case, it may need to shift all elements to update the offset.\n * Space Complexity: O(1) - no additional space is used.\n */\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 * @static\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) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it adds an element to the end of the array.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The push function adds an element to the end of the queue and returns the updated queue.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 The `add` method is returning a `Queue<E>` object.\n */\n push(element: E): boolean {\n this.nodes.push(element);\n return true;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. In the worst case, it may need to shift all elements to update the offset.\n * Space Complexity: O(1) - no additional space is used.\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 * 2 < this.nodes.length) return first;\n\n // only delete dequeued elements when reaching half size\n // to decrease latency of shifting elements.\n this._nodes = this.nodes.slice(this.offset);\n this._offset = 0;\n return first;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The `peek` function returns the first element of the array `_nodes` if it exists, otherwise it returns `undefined`.\n * @returns The `peek()` method returns the first element of the data structure, represented by the `_nodes` array at\n * the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.\n */\n peek(): E | undefined {\n return this.first;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The `peekLast` function returns the last element in an array-like data structure, or undefined if the structure is empty.\n * @returns The method `peekLast()` returns the last element of the `_nodes` array if the array is not empty. If the\n * array is empty, it returns `undefined`.\n */\n peekLast(): E | undefined {\n return this.last;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The enqueue function adds a value to the end of a queue.\n * @param {E} value - The value parameter represents the value that you want to add to the queue.\n */\n enqueue(value: E): boolean {\n return this.push(value);\n }\n\n /**\n * Time Complexity: O(n) - same as shift().\n * Space Complexity: O(1) - same as shift().\n */\n\n /**\n * Time Complexity: O(n) - same as shift().\n * Space Complexity: O(1) - same as shift().\n *\n * The `dequeue` function removes and returns the first element from a queue, or returns undefined if the queue is empty.\n * @returns The method is returning a value of type E or undefined.\n */\n dequeue(): E | undefined {\n return this.shift();\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\n *\n * @param index\n */\n getAt(index: number): E | undefined {\n return this.nodes[index];\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\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) - constant time as it returns a shallow copy of the internal array.\n * Space Complexity: O(n) - where n is the number of elements in the queue.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it returns a shallow copy of the internal array.\n * Space Complexity: O(n) - where n is the number of elements in the queue.\n *\n * The toArray() function returns an array of elements from the current offset to the end of the _nodes array.\n * @returns An array of type E is being returned.\n */\n toArray(): E[] {\n return this.nodes.slice(this.offset);\n }\n\n /**\n * The clear function resets the nodes array and offset to their initial values.\n */\n clear(): void {\n this._nodes = [];\n this._offset = 0;\n }\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. It creates a shallow copy of the internal array.\n * Space Complexity: O(n) - the space required is proportional to the number of elements in the queue.\n */\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. It creates a shallow copy of the internal array.\n * Space Complexity: O(n) - the space required is proportional to the number of elements in the queue.\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> {\n return new Queue(this.nodes.slice(this.offset));\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 `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, boolean>, thisArg?: any): Queue<E> {\n const newDeque = new Queue<E>([]);\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 /**\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 queue,\n * returning a new queue with the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * queue. It takes three arguments: the current element, the index of the current element, and the\n * queue itself. The callback function should return a new value that will be added to the new queue.\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 `map` function is returning a new `Queue` object with the transformed elements.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): Queue<T> {\n const newDeque = new Queue<T>([]);\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\n protected* _getIterator(): IterableIterator<E> {\n for (const item of this.nodes) {\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> extends SinglyLinkedList<E> {\n /**\n * The `get first` function returns the value of the head node in a linked list, or `undefined` if the list is empty.\n * @returns The `get first()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.\n */\n get first(): E | undefined {\n return this.head?.value;\n }\n\n /**\n * The enqueue function adds a value to the end of an array.\n * @param {E} value - The value parameter represents the value that you want to add to the queue.\n */\n enqueue(value: E): boolean {\n return this.push(value);\n }\n\n /**\n * The `dequeue` function removes and returns the first element from a queue, or returns undefined if the queue is empty.\n * @returns The method is returning the element at the front of the queue, or undefined if the queue is empty.\n */\n dequeue(): E | undefined {\n return this.shift();\n }\n\n /**\n * The `peek` function returns the value of the head node in a linked list, or `undefined` if the list is empty.\n * @returns The `peek()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.\n */\n peek(): E | undefined {\n return this.first;\n }\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 { 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> extends IterableElementBase<E> {\n protected _bucketFirst = 0;\n protected _firstInBucket = 0;\n protected _bucketLast = 0;\n protected _lastInBucket = 0;\n protected _bucketCount = 0;\n protected readonly _bucketSize: number;\n\n /**\n * The constructor initializes a data structure with a specified bucket size and populates it with\n * elements from an iterable.\n * @param elements - The `elements` parameter is an iterable object (such as an array or a Set) that\n * contains the initial elements to be stored in the data structure. It can also be an object with a\n * `length` property or a `size` property, which represents the number of elements in the iterable.\n * @param bucketSize - The `bucketSize` parameter is the maximum number of elements that can be\n * stored in each bucket. It determines the size of each bucket in the data structure.\n */\n constructor(elements: IterableWithSizeOrLength<E> = [], bucketSize = (1 << 12)) {\n super();\n let _size: number;\n if ('length' in elements) {\n if (elements.length instanceof Function) _size = elements.length(); else _size = elements.length;\n } else {\n if (elements.size instanceof Function) _size = elements.size(); else _size = elements.size;\n }\n\n this._bucketSize = bucketSize;\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 element of elements) {\n this.push(element);\n }\n }\n\n protected _buckets: E[][] = [];\n\n get buckets() {\n return this._buckets;\n }\n\n protected _size = 0;\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 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\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 (\n this._bucketLast === this._bucketFirst &&\n this._lastInBucket === this._firstInBucket\n ) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketLast][this._lastInBucket] = element;\n return true;\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 `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\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 (\n this._bucketFirst === this._bucketLast &&\n this._firstInBucket === this._lastInBucket\n ) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketFirst][this._firstInBucket] = element;\n return true;\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 `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) - Removes the last element.\n * Space Complexity: O(1) - Operates in-place.\n */\n\n isEmpty(): boolean {\n return this.size === 0;\n }\n\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.getAt(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.getAt(index);\n index--;\n }\n }\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 `getAt` 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 getAt(pos: number): E {\n rangeCheck(pos, 0, this.size - 1);\n const {\n bucketIndex,\n indexInBucket\n } = this._getBucketAndPosition(pos);\n return this._buckets[bucketIndex][indexInBucket]!;\n }\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 `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 {\n bucketIndex,\n indexInBucket\n } = 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\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.getAt(i));\n }\n this.cut(pos - 1);\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\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 * @returns The method is returning the updated size of the data structure.\n */\n cut(pos: number): number {\n if (pos < 0) {\n this.clear();\n return 0;\n }\n const {\n bucketIndex,\n indexInBucket\n } = this._getBucketAndPosition(pos);\n this._bucketLast = bucketIndex;\n this._lastInBucket = indexInBucket;\n this._size = pos + 1;\n return this.size;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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 {\n bucketIndex: curBucket,\n indexInBucket: curPointer\n } = this._getBucketAndPosition(pos);\n for (let i = pos; i < length; ++i) {\n const {\n bucketIndex: nextBucket,\n indexInBucket: nextPointer\n } = 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\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.getAt(i);\n if (oldElement !== element) {\n this.setAt(index, oldElement!);\n index += 1;\n }\n i += 1;\n }\n this.cut(index - 1);\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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\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.getAt(0);\n for (let i = 1; i < this.size; ++i) {\n const cur = this.getAt(i);\n if (cur !== prev) {\n prev = cur;\n this.setAt(index++, cur);\n }\n }\n this.cut(index - 1);\n return this;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\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.getAt(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\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\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the elements in a deque and returns the first element for which\n * the callback function returns true, or undefined if no such element is found.\n * @param callback - A function that takes three parameters: element, index, and deque. It should\n * return a boolean value indicating whether the element satisfies a certain condition.\n * @returns The method `find` returns the first element in the deque that satisfies the condition\n * specified by the callback function. If no element satisfies the condition, it returns `undefined`.\n */\n find(callback: (element: E, index: number, deque: Deque<E>) => boolean): E | undefined {\n for (let i = 0; i < this.size; ++i) {\n const element = this.getAt(i);\n if (callback(element, i, this)) {\n return element;\n }\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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.getAt(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\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 /**\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, boolean>, thisArg?: any): Deque<E> {\n const newDeque = new Deque<E>([], this._bucketSize);\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 /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new Deque by applying a callback function to each element of the\n * original Deque.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the deque. It takes three arguments:\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 a new Deque object with the mapped values.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): Deque<T> {\n const newDeque = new Deque<T>([], this._bucketSize);\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: Amortized O(1) - Similar to push, resizing leads to O(n).\n * Space Complexity: O(n) - Due to potential resizing.\n */\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(n) - In worst case, resizing doubles the array size.\n *\n * The addLast function adds an element to the end of an array.\n * @param {E} element - The element parameter represents the element that you want to add to the end of the\n * data structure.\n */\n addLast(element: E): boolean {\n return this.push(element);\n }\n\n /**\n * Time Complexity: O(1) - Removes the first element.\n * Space Complexity: O(1) - In-place operation.\n */\n\n /**\n * Time Complexity: O(1) - Removes the last element.\n * Space Complexity: O(1) - Operates in-place.\n *\n * The function \"pollLast\" removes and returns the last element of an array.\n * @returns The last element of the array is being returned.\n */\n pollLast(): E | undefined {\n return this.pop();\n }\n\n /**\n * Time Complexity: O(1).\n * Space Complexity: O(n) - Due to potential resizing.\n *\n * The \"addFirst\" function adds an element to the beginning of an array.\n * @param {E} element - The parameter \"element\" represents the element that you want to add to the\n * beginning of the data structure.\n */\n addFirst(element: E): boolean {\n return this.unshift(element);\n }\n\n /**\n * Time Complexity: O(1) - Removes the first element.\n * Space Complexity: O(1) - In-place operation.\n *\n * The function \"pollFirst\" removes and returns the first element of an array.\n * @returns The method `pollFirst()` is returning the first element of the array after removing it\n * from the beginning. If the array is empty, it will return `undefined`.\n */\n pollFirst(): E | undefined {\n return this.shift();\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.getAt(i);\n }\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 `_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\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 * 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 Prim's minimum spanning tree algorithm, which use heaps to improve performance.\n */\nexport class Heap<E = any> extends IterableElementBase<E> {\n options: HeapOptions<E>;\n\n constructor(elements?: Iterable<E>, options?: HeapOptions<E>) {\n super();\n const defaultComparator = (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return a - b;\n }\n }\n if (options) {\n this.options = options\n } else {\n this.options = {\n comparator: defaultComparator\n }\n }\n\n if (elements) {\n for (const el of elements) {\n this.add(el);\n }\n // this.fix();\n }\n }\n\n protected _elements: E[] = [];\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>(elements: Iterable<E>, options: { comparator: Comparator<E> }): Heap<E> {\n return new Heap<E>(elements, options);\n }\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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 * 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), where n is the number of elements in the elements array.\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the elements array.\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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the heap.\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 has(element: E): boolean {\n return this.elements.includes(element);\n }\n\n /**\n * Time Complexity: O(n). The worst-case O(n), where n is the number of elements in the heap. This is because, in the worst case, the element to be deleted is located at the end of the heap (not the root), and after deletion, we may need to reorganize the elements by performing a sinkDown operation.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n). The worst-case O(n), where n is the number of elements in the heap. This is because, in the worst case, the element to be deleted is located at the end of the heap (not the root), and after deletion, we may need to reorganize the elements by performing a sinkDown operation.\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), where n is the number of elements in the heap.\n * Space Complexity: O(h), where h is the height of the heap.\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the heap.\n * Space Complexity: O(h), where h is the height of the heap.\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, 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\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\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> {\n const clonedHeap = new Heap<E>([], this.options);\n clonedHeap._elements = [...this.elements];\n return clonedHeap;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\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 = this.clone();\n while (cloned.size !== 0) {\n const top = cloned.poll();\n if (top) visitedNode.push(top);\n }\n return visitedNode;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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\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, boolean>, thisArg?: any): Heap<E> {\n const filteredList = new Heap<E>();\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)\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(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 the\n * original heap. It takes three arguments: the current element, the index of the current element,\n * and the original heap itself. The callback function should return a value of type T, which will be\n * added to the mapped heap.\n * @param comparator - The `comparator` parameter is a function that is used to compare elements in\n * the heap. It takes two arguments, `a` and `b`, and returns a negative number if `a` is less than\n * `b`, a positive number if `a` is greater than `b`, or\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 when you want to bind a\n * specific object as the context for the callback function. If `thisArg` is not provided,\n * `undefined` is used as\n * @returns a new instance of the Heap class, which is created using the mapped elements from the\n * original Heap.\n */\n map<T>(callback: ElementCallback<E, T>, comparator: Comparator<T>, thisArg?: any): Heap<T> {\n\n const mappedHeap: Heap<T> = new Heap<T>([], { comparator: comparator });\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* _getIterator(): IterableIterator<E> {\n for (const element of this.elements) {\n yield element;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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.options.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 (\n right < this.elements.length &&\n this.options.comparator(minItem, this.elements[right]) > 0\n ) {\n left = right;\n minItem = this.elements[right];\n }\n if (this.options.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 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 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 get root(): FibonacciHeapNode<E> | undefined {\n return this._root;\n }\n\n protected _size = 0;\n\n get size(): number {\n return this._size;\n }\n\n protected _min?: FibonacciHeapNode<E>;\n\n get min(): FibonacciHeapNode<E> | undefined {\n return this._min;\n }\n\n protected _comparator: Comparator<E>;\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\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\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\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\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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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\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\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *.\n * Remove and return the top element (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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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), where n is the number of elements in the heap.\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n log n), where n is the number of elements in the heap.\n * Space Complexity: O(n)\n *\n * Remove and return the top element (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 { 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> extends Heap<E> {\n constructor(\n elements?: Iterable<E>,\n options: HeapOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return b - a;\n }\n }\n }) {\n super(elements, options);\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 { 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 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 Prim's minimum spanning tree algorithm, which use heaps to improve performance.\n */\nexport class MinHeap<E = any> extends Heap<E> {\n constructor(\n elements?: Iterable<E>,\n options: HeapOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return a - b;\n }\n }\n }) {\n super(elements, options);\n }\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 { 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> extends IterableEntryBase<VertexKey, V | undefined> implements IGraph<V, E, VO, EO> {\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 /**\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\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\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 /**\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 const vertexKey = this._getVertexKey(vertexOrKey);\n return this._vertexMap.delete(vertexKey);\n }\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\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\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\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\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\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\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\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 * Dijkstra algorithm time: O(VE) space: O(VO + EO)\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\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 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 genPaths && getPaths(minDest);\n\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n\n /**\n * Dijkstra algorithm time: O(logVE) space: O(VO + EO)\n *\n * Dijkstra's algorithm only solves the single-source shortest path problem, while the Bellman-Ford algorithm and Floyd-Warshall algorithm can address shortest paths between all pairs of nodes.\n * Dijkstra's algorithm is suitable for graphs with non-negative edge weights, whereas the Bellman-Ford algorithm and Floyd-Warshall algorithm can handle negative-weight edgeMap.\n * The time complexity of Dijkstra's algorithm and the Bellman-Ford algorithm depends on the size of the graph, while the time complexity of the Floyd-Warshall algorithm is O(VO^3), where VO is the number of nodes. For dense graphs, Floyd-Warshall might become slower.\n *\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\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\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 * one to rest pairs\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 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 * 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 * /\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 * Time Complexity: O(V + E) - Linear time (Tarjan's algorithm).\n * Space Complexity: O(V) - Linear space (Tarjan's algorithm).\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * Tarjan can find cycles in directed or undirected graph\n * Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time,\n * Tarjan solve the bi-connected components of undirected graphs;\n * Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.\n * /\n\n /**\n * Time Complexity: O(V + E) - Linear time (Tarjan's algorithm).\n * Space Complexity: O(V) - Linear space (Tarjan's algorithm).\n *\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * Tarjan can find cycles in directed or undirected graph\n * Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time,\n * Tarjan solve the bi-connected components of undirected graphs;\n * Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.\n * The `tarjan` function is used to perform various graph analysis tasks such as finding articulation points, bridges,\n * strongly connected components (SCCs), and cycles in a graph.\n * @param {boolean} [needCutVertexes] - A boolean value indicating whether or not to calculate and return the\n * articulation points in the graph. Articulation points are the vertexMap in a graph whose removal would increase the\n * number of connected components in the graph.\n * @param {boolean} [needBridges] - A boolean flag indicating whether the algorithm should find and return the bridges\n * (edgeMap whose removal would increase the number of connected components in the graph).\n * @param {boolean} [needSCCs] - A boolean value indicating whether the Strongly Connected Components (SCCs) of the\n * graph are needed. If set to true, the function will calculate and return the SCCs of the graph. If set to false, the\n * SCCs will not be calculated or returned.\n * @param {boolean} [needCycles] - A boolean flag indicating whether the algorithm should find cycles in the graph. If\n * set to true, the algorithm will return a map of cycles, where the keys are the low values of the SCCs and the values\n * are arrays of vertexMap that form cycles within the SCCs.\n * @returns The function `tarjan` returns an object with the following properties:\n */\n tarjan(\n needCutVertexes: boolean = false,\n needBridges: boolean = false,\n needSCCs: boolean = true,\n needCycles: boolean = false\n ) {\n // !! in undirected graph we will not let child visit parent when dfs\n // !! articulation point(in dfs search tree not in graph): (cur !== root && cur.has(child)) && (low(child) >= dfn(cur)) || (cur === root && cur.children() >= 2)\n // !! bridge: low(child) > dfn(cur)\n\n const defaultConfig = false;\n if (needCutVertexes === undefined) needCutVertexes = defaultConfig;\n if (needBridges === undefined) needBridges = defaultConfig;\n if (needSCCs === undefined) needSCCs = defaultConfig;\n if (needCycles === undefined) needCycles = defaultConfig;\n\n const dfnMap: Map<VO, number> = new Map();\n const lowMap: Map<VO, number> = new Map();\n const vertexMap = this._vertexMap;\n vertexMap.forEach(v => {\n dfnMap.set(v, -1);\n lowMap.set(v, Infinity);\n });\n\n const [root] = vertexMap.values();\n\n const cutVertexes: VO[] = [];\n const bridges: EO[] = [];\n let dfn = 0;\n const dfs = (cur: VO, parent: VO | undefined) => {\n dfn++;\n dfnMap.set(cur, dfn);\n lowMap.set(cur, dfn);\n\n const neighbors = this.getNeighbors(cur);\n let childCount = 0; // child in dfs tree not child in graph\n for (const neighbor of neighbors) {\n if (neighbor !== parent) {\n if (dfnMap.get(neighbor) === -1) {\n childCount++;\n dfs(neighbor, cur);\n }\n const childLow = lowMap.get(neighbor);\n const curLow = lowMap.get(cur);\n // TODO after no-non-undefined-assertion not ensure the logic\n if (curLow !== undefined && childLow !== undefined) {\n lowMap.set(cur, Math.min(curLow, childLow));\n }\n const curFromMap = dfnMap.get(cur);\n if (childLow !== undefined && curFromMap !== undefined) {\n if (needCutVertexes) {\n if ((cur === root && childCount >= 2) || (cur !== root && childLow >= curFromMap)) {\n // todo not ensure the logic if (cur === root && childCount >= 2 || ((cur !== root) && (childLow >= curFromMap))) {\n cutVertexes.push(cur);\n }\n }\n\n if (needBridges) {\n if (childLow > curFromMap) {\n const edgeCurToNeighbor = this.getEdge(cur, neighbor);\n if (edgeCurToNeighbor) {\n bridges.push(edgeCurToNeighbor);\n }\n }\n }\n }\n }\n }\n };\n\n dfs(root, undefined);\n\n let SCCs: Map<number, VO[]> = new Map();\n\n const getSCCs = () => {\n const SCCs: Map<number, VO[]> = new Map();\n lowMap.forEach((low, vertex) => {\n if (!SCCs.has(low)) {\n SCCs.set(low, [vertex]);\n } else {\n SCCs.get(low)?.push(vertex);\n }\n });\n return SCCs;\n };\n\n if (needSCCs) {\n SCCs = getSCCs();\n }\n\n const cycles: Map<number, VO[]> = new Map();\n\n if (needCycles) {\n const visitedMap: Map<VO, boolean> = new Map();\n const stack: VO[] = [];\n const findCyclesDFS = (cur: VO, parent: VO | undefined) => {\n visitedMap.set(cur, true);\n stack.push(cur);\n\n const neighbors = this.getNeighbors(cur);\n\n for (const neighbor of neighbors) {\n if (!visitedMap.get(neighbor)) {\n findCyclesDFS(neighbor, cur);\n } else if (stack.includes(neighbor) && neighbor !== parent) {\n const cycleStartIndex = stack.indexOf(neighbor);\n const cycle = stack.slice(cycleStartIndex);\n const cycleLow = Math.min(...cycle.map(v => dfnMap.get(v) || Infinity));\n cycles.set(cycleLow, cycle);\n }\n }\n\n stack.pop();\n };\n\n vertexMap.forEach(v => {\n if (!visitedMap.get(v)) {\n findCyclesDFS(v, undefined);\n }\n });\n }\n\n return { dfnMap, lowMap, bridges, cutVertexes, SCCs, cycles };\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\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(false, false, false, false).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(false, false, false, false).lowMap;\n }\n\n /**\n * The function \"getCutVertexes\" returns an array of cut vertexes using the Tarjan algorithm.\n * @returns an array of VO objects, specifically the cut vertexes.\n */\n getCutVertexes(): VO[] {\n return this.tarjan(true, false, false, false).cutVertexes;\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(false, false, true, false).SCCs;\n }\n\n /**\n * The function \"getBridges\" returns an array of bridges using the Tarjan algorithm.\n * @returns the bridges found using the Tarjan algorithm.\n */\n getBridges() {\n return this.tarjan(false, true, false, false).bridges;\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 ((!isInclude2Cycle && currentPath.length > 2 || isInclude2Cycle && currentPath.length >= 2) && currentPath[0] === vertex.key) {\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 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 =>\n cycleString[1]\n );\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 `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\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler 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 * 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 protected _inEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();\n\n get inEdgeMap(): Map<VO, EO[]> {\n return this._inEdgeMap;\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 /**\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 * 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 /**\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\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\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\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\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 override 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 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\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 v1ToV2 && removed.push(v1ToV2);\n v2ToV1 && removed.push(v2ToV1);\n }\n\n return removed;\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 `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\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\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\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\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\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\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\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\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\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\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\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\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 /**\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 `_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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler 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 vertexMap: [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.vertexMap = [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 * 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 /**\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\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 vertexMap, 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.vertexMap.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\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 vertexMap (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.vertexMap.includes(vertex2.key))[0] || undefined;\n }\n const v2Edges = this._edgeMap.get(vertex2);\n if (v2Edges) {\n arrayRemove<EO>(v2Edges, (e: EO) => e.vertexMap.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\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 vertexMap 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.vertexMap[0]);\n otherSide = this._getVertex(edgeOrOneSideVertexKey.vertexMap[1]);\n }\n\n if (oneSide && otherSide) {\n return this.deleteEdgeBetween(oneSide, otherSide);\n\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\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 override 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.vertexMap.includes(vertexKey);\n });\n this._edgeMap.set(neighbor, restEdges);\n }\n })\n this._edgeMap.delete(vertex);\n\n }\n\n return this._vertexMap.delete(vertexKey);\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 `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\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\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\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 vertexMap 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.vertexMap.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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEndsOfEdge\" returns the vertexMap 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 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.vertexMap[0], edge.vertexMap[1])) {\n return undefined;\n }\n const v1 = this._getVertex(edge.vertexMap[0]);\n const v2 = this._getVertex(edge.vertexMap[1]);\n if (v1 && v2) {\n return [v1, v2];\n } else {\n return undefined;\n }\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 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.vertexMap) {\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(key: VertexKey, value?: V, lat: number = this.originCoord[0], long: number = this.originCoord[1]): 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","import { RedBlackTree, RedBlackTreeNode } from '../../../data-structures';\nimport type { BSTOptions } from \"./bst\";\n\nexport enum RBTNColor { RED = 1, BLACK = 0}\n\nexport type RedBlackTreeNodeNested<K, V> = RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\nexport type RedBlackTreeNested<K, V, N extends RedBlackTreeNode<K, V, N>> = RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\nexport type RBTreeOptions<K> = BSTOptions<K> & {};\n","export enum BSTVariant {\n MIN = 'MIN',\n MAX = 'MAX',\n}\n\nexport enum CP {\n lt = 'lt',\n eq = 'eq',\n gt = 'gt'\n}\n\n/**\n * Enum representing different loop types.\n *\n * - `iterative`: Indicates the iterative loop type (with loops that use iterations).\n * - `recursive`: Indicates the recursive loop type (with loops that call themselves).\n */\nexport enum IterationType {\n ITERATIVE = 'ITERATIVE',\n RECURSIVE = 'RECURSIVE'\n}\n\nexport enum FamilyPosition {\n ROOT = 'ROOT',\n LEFT = 'LEFT',\n RIGHT = 'RIGHT',\n ROOT_LEFT = 'ROOT_LEFT',\n ROOT_RIGHT = 'ROOT_RIGHT',\n ISOLATED = 'ISOLATED',\n MAL_NODE = 'MAL_NODE'\n}\n\nexport type Comparator<K> = (a: K, b: K) => number;\n\nexport type DFSOrderPattern = 'pre' | 'in' | 'post';\n\nexport type NodeDisplayLayout = [string[], number, number, number];\n\nexport type BTNCallback<N, D = any> = (node: N) => D;\n\nexport interface IterableWithSize<T> extends Iterable<T> {\n size: number | ((...args: any[]) => number);\n}\n\nexport interface IterableWithLength<T> extends Iterable<T> {\n length: number | ((...args: any[]) => number);\n}\n\nexport type IterableWithSizeOrLength<T> = IterableWithSize<T> | IterableWithLength<T>\n\nexport type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean }\n\nexport type BTNEntry<K, V> = [K | null | undefined, V | undefined];\n\nexport type BTNKeyOrNode<K, N> = K | null | undefined | N;\n\nexport type BTNExemplar<K, V, N> = BTNEntry<K, V> | BTNKeyOrNode<K, N>\n\nexport type BTNodePureKeyOrNode<K, N> = K | N;\n\nexport type BTNodePureExemplar<K, V, N> = [K, V | undefined] | BTNodePureKeyOrNode<K, N>;\n\nexport type BSTNKeyOrNode<K, N> = K | undefined | N;\n\nexport type BinaryTreeDeleteResult<N> = { deleted: N | null | undefined; needBalanced: N | null | undefined };\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 */\n\nimport type {\n BinaryTreeDeleteResult,\n BinaryTreeNested,\n BinaryTreeNodeNested,\n BinaryTreeOptions,\n BinaryTreePrintOptions,\n BTNCallback,\n BTNEntry,\n BTNExemplar,\n BTNKeyOrNode,\n DFSOrderPattern,\n EntryCallback,\n NodeDisplayLayout\n} from '../../types';\nimport { FamilyPosition, IterationType } from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { trampoline } from '../../utils';\nimport { Queue } from '../queue';\nimport { IterableEntryBase } from \"../base\";\n\n/**\n * Represents a node in a binary tree.\n * @template V - The type of data stored in the node.\n * @template N - The type of the family relationship in the binary tree.\n */\nexport class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>> {\n key: K;\n\n value?: V;\n\n parent?: N;\n\n constructor(key: K, value?: V) {\n this.key = key;\n this.value = value;\n }\n\n protected _left?: N | null;\n\n get left(): N | null | undefined {\n return this._left;\n }\n\n set left(v: N | null | undefined) {\n if (v) {\n v.parent = this as unknown as N;\n }\n this._left = v;\n }\n\n protected _right?: N | null;\n\n get right(): N | null | undefined {\n return this._right;\n }\n\n set right(v: N | null | undefined) {\n if (v) {\n v.parent = this as unknown as N;\n }\n this._right = v;\n }\n\n /**\n * Get the position of the node within its family.\n * @returns {FamilyPosition} - The family position of the node.\n */\n get familyPosition(): FamilyPosition {\n const that = this as unknown as N;\n if (!this.parent) {\n return this.left || this.right ? FamilyPosition.ROOT : FamilyPosition.ISOLATED;\n }\n\n if (this.parent.left === that) {\n return this.left || this.right ? FamilyPosition.ROOT_LEFT : FamilyPosition.LEFT;\n } else if (this.parent.right === that) {\n return this.left || this.right ? FamilyPosition.ROOT_RIGHT : FamilyPosition.RIGHT;\n }\n\n return FamilyPosition.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 */\n\nexport class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>, TREE extends BinaryTree<K, V, N, TREE> = BinaryTree<K, V, N, BinaryTreeNested<K, V, N>>> extends IterableEntryBase<K, V | undefined>\n\n implements IBinaryTree<K, V, N, TREE> {\n iterationType = IterationType.ITERATIVE\n\n /**\n * The constructor function initializes a binary tree object with optional elements and options.\n * @param [elements] - An optional iterable of BTNExemplar objects. These objects represent the\n * elements to be added to the binary tree.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the binary tree. In this case, it is of type\n * `Partial<BinaryTreeOptions>`, which means that not all properties of `BinaryTreeOptions` are\n * required.\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<BinaryTreeOptions<K>>) {\n super();\n if (options) {\n const { iterationType, extractor } = options;\n if (iterationType) {\n this.iterationType = iterationType;\n }\n if (extractor) {\n this._extractor = extractor;\n }\n }\n\n this._size = 0;\n\n if (elements) this.addMany(elements);\n }\n\n protected _extractor = (key: K) => Number(key)\n\n get extractor() {\n return this._extractor;\n }\n\n protected _root?: N | null;\n\n get root(): N | null | undefined {\n return this._root;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n /**\n * Creates a new instance of BinaryTreeNode with the given key and value.\n * @param {K} key - The key for the new node.\n * @param {V} value - The value for the new node.\n * @returns {N} - The newly created BinaryTreeNode.\n */\n createNode(key: K, value?: V): N {\n return new BinaryTreeNode<K, V, N>(key, value) as N;\n }\n\n /**\n * The function creates a binary tree with the given options.\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the `BinaryTree` class. It is of type `Partial<BinaryTreeOptions>`, which means that\n * you can provide only a subset of the properties defined in the `BinaryTreeOptions` interface.\n * @returns a new instance of a binary tree.\n */\n createTree(options?: Partial<BinaryTreeOptions<K>>): TREE {\n return new BinaryTree<K, V, N, TREE>([], { iterationType: this.iterationType, ...options }) as TREE;\n }\n\n /**\n * The function \"isNode\" checks if an exemplar is an instance of the BinaryTreeNode class.\n * @param exemplar - The `exemplar` parameter is a variable of type `BTNExemplar<K, V,N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the class N.\n */\n isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof BinaryTreeNode;\n }\n\n /**\n * The function `exemplarToNode` converts an exemplar object into a node object.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `exemplarToNode` function. It represents the value associated with the exemplar node. If no value\n * is provided, it will be `undefined`.\n * @returns a value of type N (node), or null, or undefined.\n */\n exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V): N | null | undefined {\n if (exemplar === undefined) return;\n\n let node: N | null | undefined;\n if (exemplar === null) {\n node = null;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined) {\n return;\n } else if (key === null) {\n node = null;\n } else {\n node = this.createNode(key, value);\n }\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * The function checks if a given value is an entry in a binary tree node.\n * @param kne - BTNExemplar<K, V,N> - A generic type representing a node in a binary tree. It has\n * two type parameters V and N, representing the value and node type respectively.\n * @returns a boolean value.\n */\n isEntry(kne: BTNExemplar<K, V, N>): kne is BTNEntry<K, V> {\n return Array.isArray(kne) && kne.length === 2;\n }\n\n /**\n * Time Complexity O(log n) - O(n)\n * Space Complexity O(1)\n */\n\n /**\n * Time Complexity O(log n) - O(n)\n * Space Complexity O(1)\n *\n * The `add` function adds a new node to a binary tree, either by creating a new node or replacing an\n * existing node with the same key.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following:\n * @param {V} [value] - The value to be inserted into the binary tree.\n * @returns The function `add` returns either a node (`N`), `null`, or `undefined`.\n */\n add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | null | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);\n if (newNode === undefined) return;\n\n // If the tree is empty, directly set the new node as the root node\n if (!this.root) {\n this._root = newNode;\n this._size = 1;\n return newNode;\n }\n\n const queue = new Queue<N>([this.root]);\n let potentialParent: N | 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 newNode; // 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 cur.left && queue.push(cur.left);\n }\n if (cur.right !== null) {\n 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 newNode;\n }\n\n return undefined; // If the insertion position cannot be found, return undefined\n }\n\n\n /**\n * Time Complexity: O(k log n) - O(k * n)\n * Space Complexity: O(1)\n * Comments: The time complexity for adding a node depends on the depth of the tree. In the best case (when the tree is empty), it's O(1). In the worst case (when the tree is a degenerate tree), it's O(n). The space complexity is constant.\n */\n\n /**\n * Time Complexity: O(k log n) - O(k * n)\n * Space Complexity: O(1)\n *\n * The `addMany` function takes in a collection of nodes and an optional collection of values, and\n * adds each node with its corresponding value to the data structure.\n * @param nodes - An iterable collection of BTNExemplar objects.\n * @param [values] - An optional iterable of values that will be assigned to each node being added.\n * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.\n */\n addMany(nodes: Iterable<BTNExemplar<K, V, N>>, values?: Iterable<V | undefined>): (N | null | undefined)[] {\n // TODO not sure addMany not be run multi times\n const inserted: (N | null | undefined)[] = [];\n\n let valuesIterator: Iterator<V | undefined> | undefined;\n if (values) {\n valuesIterator = values[Symbol.iterator]();\n }\n\n for (const kne of nodes) {\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(kne, value));\n }\n\n return inserted;\n }\n\n\n /**\n * Time Complexity: O(k * n) \"n\" is the number of nodes in the tree, and \"k\" is the number of keys to be inserted.\n * Space Complexity: O(1)\n */\n\n refill(nodesOrKeysOrEntries: Iterable<BTNExemplar<K, V, N>>, values?: Iterable<V | undefined>): void {\n this.clear();\n this.addMany(nodesOrKeysOrEntries, values);\n }\n\n /**\n * Time Complexity: O(k * n) \"n\" is the number of nodes in the tree, and \"k\" is the number of keys to be inserted.\n * Space Complexity: O(1)\n */\n\n delete<C extends BTNCallback<N, K>>(identifier: K, callback?: C): BinaryTreeDeleteResult<N>[];\n\n delete<C extends BTNCallback<N, N>>(identifier: N | null | undefined, callback?: C): BinaryTreeDeleteResult<N>[];\n\n delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BinaryTreeDeleteResult<N>[];\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function deletes a node from a binary tree and returns an array of the deleted nodes along\n * with the nodes that need to be balanced.\n * @param {ReturnType<C> | null | undefined} identifier - The identifier parameter is the value or\n * object that you want to delete from the binary tree. It can be of any type that is compatible with\n * the callback function's return type. It can also be null or undefined if you want to delete a\n * specific node based on its value or object.\n * @param {C} callback - The `callback` parameter is a function that is used to determine the\n * identifier of the node to be deleted. It is optional and has a default value of\n * `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.\n * @returns an array of `BinaryTreeDeleteResult<N>`.\n */\n delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C\n ): BinaryTreeDeleteResult<N>[] {\n const deletedResult: BinaryTreeDeleteResult<N>[] = [];\n if (!this.root) return deletedResult;\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n const curr = this.getNode(identifier, callback);\n if (!curr) return deletedResult;\n\n const parent: N | null | undefined = curr?.parent ? curr.parent : null;\n let needBalanced: N | null | undefined = undefined;\n let orgCurrent: N | undefined = curr;\n\n if (!curr.left) {\n if (!parent) {\n // Handle the case when there's only one root node\n this._setRoot(null);\n } else {\n const { familyPosition: fp } = curr;\n if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {\n parent.left = curr.right;\n } else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {\n parent.right = curr.right;\n }\n needBalanced = parent;\n }\n } else {\n if (curr.left) {\n const leftSubTreeRightMost = this.getRightMost(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 }\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(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function calculates the depth of a given node in a binary tree.\n * @param {K | N | null | undefined} distNode - The `distNode` parameter represents the node in\n * the binary tree whose depth we want to find. It can be of type `K`, `N`, `null`, or\n * `undefined`.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node\n * from which we want to calculate the depth. It can be either a `K` (binary tree node key) or\n * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot\n * @returns the depth of the `distNode` relative to the `beginRoot`.\n */\n getDepth(distNode: BTNKeyOrNode<K, N>, beginRoot: BTNKeyOrNode<K, N> = this.root): number {\n distNode = this.ensureNode(distNode);\n beginRoot = this.ensureNode(beginRoot);\n let depth = 0;\n while (distNode?.parent) {\n if (distNode === beginRoot) {\n return depth;\n }\n depth++;\n distNode = distNode.parent;\n }\n return depth;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getHeight` calculates the maximum height of a binary tree using either recursive or\n * iterative traversal.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node of the binary tree from which we want to calculate the height. It can be of type\n * `K`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.\n * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the\n * height of the tree using a recursive approach or an iterative approach. It can have two possible\n * values:\n * @returns the height of the binary tree.\n */\n getHeight(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return -1;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _getMaxHeight = (cur: N | null | undefined): number => {\n if (!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: N; 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 (node.left) stack.push({ node: node.left, depth: depth + 1 });\n if (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 * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)\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.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node of the binary tree from which we want to calculate the minimum height. It can be of\n * type `K`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.\n * @param iterationType - The `iterationType` parameter is used to determine the method of iteration\n * to calculate the minimum height of a binary tree. It can have two possible values:\n * @returns The function `getMinHeight` returns the minimum height of a binary tree.\n */\n getMinHeight(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return -1;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _getMinHeight = (cur: N | null | undefined): number => {\n if (!cur) return 0;\n if (!cur.left && !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: N[] = [];\n let node: N | null | undefined = beginRoot,\n last: N | null | undefined = null;\n const depths: Map<N, 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 leftMinHeight = node.left ? depths.get(node.left) ?? -1 : -1;\n const rightMinHeight = node.right ? depths.get(node.right) ?? -1 : -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) ?? -1;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)\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 the minimum height and the\n * height of the tree.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for calculating the height and minimum height of a binary tree. It can be either a `K` (a key\n * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If\n * @returns a boolean value.\n */\n isPerfectlyBalanced(beginRoot: BTNKeyOrNode<K, N> = this.root): boolean {\n return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n getNodes<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n onlyOne?: boolean,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N[];\n\n getNodes<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n onlyOne?: boolean,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N[];\n\n getNodes<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n onlyOne?: boolean,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N[];\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n).\n *\n * The function `getNodes` retrieves nodes from a binary tree based on a given identifier and\n * callback function.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * that you want to search for in the binary tree. It can be of any type that is returned by the\n * callback function `C`. It can also be `null` or `undefined` if you don't want to search for a\n * specific value.\n * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` as\n * input and returns a value of type `C`. It is used to determine if a node matches the given\n * identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the\n * default\n * @param [onlyOne=false] - A boolean value indicating whether to only return the first node that\n * matches the identifier. If set to true, the function will stop iterating once it finds a matching\n * node and return that node. If set to false (default), the function will continue iterating and\n * return all nodes that match the identifier.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node for the traversal. It can be either a key, a node object, or `null`/`undefined`. If\n * it is `null` or `undefined`, an empty array will be returned.\n * @param iterationType - The `iterationType` parameter determines the type of iteration used to\n * traverse the binary tree. It can have two possible values:\n * @returns an array of nodes of type `N`.\n */\n getNodes<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n onlyOne = false,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N[] {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n\n const ans: N[] = [];\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N) => {\n if (callback(cur) === identifier) {\n ans.push(cur);\n if (onlyOne) return;\n }\n if (!cur.left && !cur.right) return;\n cur.left && _traverse(cur.left);\n cur.right && _traverse(cur.right);\n };\n\n _traverse(beginRoot);\n } else {\n const queue = new Queue<N>([beginRoot]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n if (callback(cur) === identifier) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n cur.left && queue.push(cur.left);\n cur.right && queue.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\n has<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): boolean;\n\n has<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): boolean;\n\n has<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): boolean;\n\n /**\n * Time Complexity: O(n)\n *\n * The function checks if a Binary Tree Node with a specific identifier exists in the tree.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * that you want to search for in the binary tree. It can be of any type that is returned by the\n * callback function `C`. It can also be `null` or `undefined` if you don't want to specify a\n * specific identifier.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the binary tree. It is used to filter the nodes based on certain conditions. The `callback`\n * function should return a boolean value indicating whether the node should be included in the\n * result or not.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a\n * node in the binary tree), a node object (`N`), or `null`/`undefined` to start the search from\n * @param iterationType - The `iterationType` parameter is a variable that determines the type of\n * iteration to be performed on the binary tree. It is used to specify whether the iteration should\n * be performed in a pre-order, in-order, or post-order manner.\n * @returns a boolean value.\n */\n has<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): boolean {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n).\n */\n\n getNode<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N | null | undefined;\n\n getNode<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N | null | undefined;\n\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N | null | undefined;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getNode` returns the first node that matches the given identifier and callback\n * function.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * used to identify the node you want to retrieve. It can be of any type that is returned by the\n * callback function `C`. It can also be `null` or `undefined` if you don't have a specific\n * identifier.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the binary tree. It is used to determine if a node matches the given identifier. The `callback`\n * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for searching the binary tree. It can be either a key value, a node object, or `null`/`undefined`.\n * If `null` or `undefined` is passed, the search will start from the root of the binary tree.\n * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to\n * be performed when searching for nodes in the binary tree. It determines the order in which the\n * nodes are visited during the search.\n * @returns a value of type `N | null | undefined`.\n */\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getNodeByKey` searches for a node in a binary tree by its key, using either\n * recursive or iterative iteration.\n * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.\n * It is used to find the node with the matching key value.\n * @param iterationType - The `iterationType` parameter is used to determine whether the search for\n * the node with the given key should be performed iteratively or recursively. It has two possible\n * values:\n * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is\n * found in the binary tree. If no node is found, it returns `undefined`.\n */\n getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {\n if (!this.root) return undefined;\n if (iterationType === IterationType.RECURSIVE) {\n const _dfs = (cur: N): N | undefined => {\n if (cur.key === key) return cur;\n\n if (!cur.left && !cur.right) return;\n if (cur.left) return _dfs(cur.left);\n if (cur.right) return _dfs(cur.right);\n };\n\n return _dfs(this.root);\n } else {\n const queue = new Queue<N>([this.root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n if (cur.key === key) return cur;\n cur.left && queue.push(cur.left);\n cur.right && queue.push(cur.right);\n }\n }\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n /**\n * The function `ensureNode` returns the node corresponding to the given key if it is a valid node\n * key, otherwise it returns the key itself.\n * @param {K | N | null | undefined} key - The `key` parameter can be of type `K`, `N`,\n * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to be used when searching for a node by key. It has a default value of\n * `IterationType.ITERATIVE`.\n * @returns either the node corresponding to the given key if it is a valid node key, or the key\n * itself if it is not a valid node key.\n */\n ensureNode(key: BTNKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | null | undefined {\n return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;\n }\n\n get<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): V | undefined;\n\n get<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): V | undefined;\n\n get<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): V | undefined;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `get` retrieves the value of a node in a binary tree based on the provided identifier\n * and callback function.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * used to identify the node in the binary tree. It can be of any type that is the return type of the\n * callback function `C`. It can also be `null` or `undefined` if no identifier is provided.\n * @param {C} callback - The `callback` parameter is a function that will be called with each node in\n * the binary tree. It is used to determine whether a node matches the given identifier. The callback\n * function should return a value that can be compared to the identifier to determine if it is a\n * match.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a\n * node), a node object of type `N`, or `null`/`undefined` to start the search from the root of\n * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to\n * be performed when searching for a node in the binary tree. It is an optional parameter with a\n * default value specified by `this.iterationType`.\n * @returns The value of the node with the given identifier is being returned. If the node is not\n * found, `undefined` is returned.\n */\n get<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): V | undefined {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n /**\n * Clear the binary tree, removing all nodes.\n */\n clear() {\n this._setRoot(undefined);\n this._size = 0;\n }\n\n /**\n * Check if the binary tree is empty.\n * @returns {boolean} - True if the binary tree is empty, false otherwise.\n */\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n *\n * The function `getPathToRoot` returns an array of nodes from a given node to the root of a tree\n * structure, with the option to reverse the order of the nodes.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node from which you want to find the path to the root. It can be of type `K`, `N`,\n * `null`, or `undefined`.\n * @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the\n * resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be\n * reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is\n * @returns The function `getPathToRoot` returns an array of nodes (`N[]`).\n */\n getPathToRoot(beginRoot: BTNKeyOrNode<K, N>, isReverse = true): N[] {\n // TODO to support get path through passing key\n const result: N[] = [];\n beginRoot = this.ensureNode(beginRoot);\n\n if (!beginRoot) return result;\n\n while (beginRoot.parent) {\n // Array.push + Array.reverse is more efficient than Array.unshift\n // TODO may consider using Deque, so far this is not the performance bottleneck\n result.push(beginRoot);\n beginRoot = beginRoot.parent;\n }\n result.push(beginRoot);\n return isReverse ? result.reverse() : result;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getLeftMost` returns the leftmost node in a binary tree, either recursively or\n * iteratively.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for finding the leftmost node in a binary tree. It can be either a `K` (a key value), `N` (a\n * node), `null`, or `undefined`. If not provided, it defaults to `this.root`,\n * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to\n * be performed when finding the leftmost node in a binary tree. It can have two possible values:\n * @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there\n * is no leftmost node, it returns `null` or `undefined` depending on the input.\n */\n getLeftMost(\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n beginRoot = this.ensureNode(beginRoot);\n\n if (!beginRoot) return beginRoot;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N): N => {\n if (!this.isRealNode(cur.left)) return cur;\n return _traverse(cur.left);\n };\n\n return _traverse(beginRoot);\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const _traverse = trampoline((cur: N) => {\n if (!this.isRealNode(cur.left)) return cur;\n return _traverse.cont(cur.left);\n });\n\n return _traverse(beginRoot);\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getRightMost` returns the rightmost node in a binary tree, either recursively or\n * iteratively.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node from which we want to find the rightmost node. It can be of type `K`, `N`,\n * `null`, or `undefined`. If not provided, it defaults to `this.root`, which is a property of the\n * current object.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when finding the rightmost node. It can have one of two values:\n * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there\n * is no rightmost node, it returns `null` or `undefined`, depending on the input.\n */\n getRightMost(\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n // TODO support get right most by passing key in\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return beginRoot;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N): N => {\n if (!this.isRealNode(cur.right)) return cur;\n return _traverse(cur.right);\n };\n\n return _traverse(beginRoot);\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const _traverse = trampoline((cur: N) => {\n if (!this.isRealNode(cur.right)) return cur;\n return _traverse.cont(cur.right);\n });\n\n return _traverse(beginRoot);\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root\n * node of the binary search tree (BST) that you want to check if it is a subtree of another BST.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two\n * possible values:\n * @returns a boolean value.\n */\n isSubtreeBST(beginRoot: BTNKeyOrNode<K, N>, iterationType = this.iterationType): boolean {\n // TODO there is a bug\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return true;\n\n if (iterationType === IterationType.RECURSIVE) {\n const dfs = (cur: N | null | undefined, min: number, max: number): boolean => {\n if (!cur) return true;\n const numKey = this.extractor(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 return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);\n } else {\n const stack = [];\n let prev = Number.MIN_SAFE_INTEGER,\n curr: N | null | undefined = beginRoot;\n while (curr || stack.length > 0) {\n while (curr) {\n stack.push(curr);\n curr = curr.left;\n }\n curr = stack.pop()!;\n const numKey = this.extractor(curr.key);\n if (!curr || prev >= numKey) return false;\n prev = numKey;\n curr = curr.right;\n }\n return true;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a binary tree is a binary search tree.\n * @param iterationType - The parameter \"iterationType\" is used to specify the type of iteration to\n * be used when checking if the binary tree is a binary search tree (BST). It is an optional\n * parameter with a default value of \"this.iterationType\". The value of \"this.iterationType\" is\n * expected to be\n * @returns a boolean value.\n */\n isBST(iterationType = this.iterationType): boolean {\n if (this.root === null) return true;\n return this.isSubtreeBST(this.root, iterationType);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n subTreeTraverse<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n subTreeTraverse<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[];\n\n subTreeTraverse<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: true\n ): ReturnType<C>[];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(log n)\n *\n * The function `subTreeTraverse` traverses a binary tree and applies a callback function to each\n * node, either recursively or iteratively.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the subtree traversal. It takes a single parameter, which is the current node being traversed, and\n * returns a value of any type.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node or key from which the subtree traversal should begin. It can be of type `K`,\n * `N`, `null`, or `undefined`. If not provided, the `root` property of the current object is used as\n * the default value.\n * @param iterationType - The `iterationType` parameter determines the type of traversal to be\n * performed on the subtree. It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines\n * whether to include null values in the traversal. If `includeNull` is set to `true`, the\n * traversal will include null values, otherwise it will skip them.\n * @returns The function `subTreeTraverse` returns an array of values that are the result of invoking\n * the `callback` function on each node in the subtree. The type of the array elements is determined\n * by the return type of the `callback` function.\n */\n subTreeTraverse<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n\n const ans: (ReturnType<BTNCallback<N>> | null | undefined)[] = [];\n if (!beginRoot) return ans;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N | null | undefined) => {\n if (cur !== undefined) {\n ans.push(callback(cur));\n if (includeNull) {\n cur && this.isNodeOrNull(cur.left) && _traverse(cur.left);\n cur && this.isNodeOrNull(cur.right) && _traverse(cur.right);\n } else {\n cur && cur.left && _traverse(cur.left);\n cur && cur.right && _traverse(cur.right);\n }\n }\n };\n\n _traverse(beginRoot);\n } else {\n const stack: (N | null | undefined)[] = [beginRoot];\n\n while (stack.length > 0) {\n const cur = stack.pop();\n if (cur !== undefined) {\n ans.push(callback(cur));\n if (includeNull) {\n cur && this.isNodeOrNull(cur.right) && stack.push(cur.right);\n cur && this.isNodeOrNull(cur.left) && stack.push(cur.left);\n } else {\n cur && cur.right && stack.push(cur.right);\n cur && cur.left && stack.push(cur.left);\n }\n }\n }\n }\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(log n)\n */\n\n /**\n * The function checks if a given node is a real node by verifying if it is an instance of\n * BinaryTreeNode and its key is not NaN.\n * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.\n * @returns a boolean value.\n */\n isRealNode(node: BTNExemplar<K, V, N>): node is N {\n return node instanceof BinaryTreeNode && String(node.key) !== 'NaN';\n }\n\n /**\n * The function checks if a given node is a BinaryTreeNode instance and has a key value of NaN.\n * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.\n * @returns a boolean value.\n */\n isNIL(node: BTNExemplar<K, V, N>) {\n return node instanceof BinaryTreeNode && String(node.key) === 'NaN';\n }\n\n /**\n * The function checks if a given node is a real node or null.\n * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.\n * @returns a boolean value.\n */\n isNodeOrNull(node: BTNExemplar<K, V, N>): node is N | null {\n return this.isRealNode(node) || node === null;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof BinaryTreeNode)\n }\n\n dfs<C extends BTNCallback<N>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n dfs<C extends BTNCallback<N>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[];\n\n dfs<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: true\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 or graph, based on the\n * specified pattern and iteration type, and returns an array of values obtained from applying a\n * callback function to each visited node.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the tree during the depth-first search. It takes a single parameter, which can be of type `N`,\n * `null`, or `undefined`, and returns a value of any type. The default value for this parameter is\n * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the\n * nodes are traversed during the depth-first search. It can have one of the following values:\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node\n * for the depth-first search traversal. It can be specified as a key, a node object, or\n * `null`/`undefined`. If not provided, the `beginRoot` will default to the root node of the tree.\n * @param {IterationType} iterationType - The `iterationType` parameter determines the type of\n * iteration to use when traversing the tree. It can have one of the following values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines\n * whether null or undefined nodes should be included in the traversal. If `includeNull` is set to\n * `true`, null or undefined nodes will be included in the traversal. If `includeNull` is set to\n * `false`, null or undefined\n * @returns an array of values that are the return values of the callback function.\n */\n dfs<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n pattern: DFSOrderPattern = 'in',\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType: IterationType = IterationType.ITERATIVE,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: ReturnType<C>[] = [];\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (node: N | null | undefined) => {\n switch (pattern) {\n case 'in':\n if (includeNull) {\n if (node && this.isNodeOrNull(node.left)) _traverse(node.left);\n this.isNodeOrNull(node) && ans.push(callback(node));\n if (node && this.isNodeOrNull(node.right)) _traverse(node.right);\n } else {\n if (node && node.left) _traverse(node.left);\n this.isRealNode(node) && ans.push(callback(node));\n if (node && node.right) _traverse(node.right);\n }\n break;\n case 'pre':\n if (includeNull) {\n this.isNodeOrNull(node) && ans.push(callback(node));\n if (node && this.isNodeOrNull(node.left)) _traverse(node.left);\n if (node && this.isNodeOrNull(node.right)) _traverse(node.right);\n } else {\n this.isRealNode(node) && ans.push(callback(node));\n if (node && node.left) _traverse(node.left);\n if (node && node.right) _traverse(node.right);\n }\n break;\n case 'post':\n if (includeNull) {\n if (node && this.isNodeOrNull(node.left)) _traverse(node.left);\n if (node && this.isNodeOrNull(node.right)) _traverse(node.right);\n this.isNodeOrNull(node) && ans.push(callback(node));\n } else {\n if (node && node.left) _traverse(node.left);\n if (node && node.right) _traverse(node.right);\n this.isRealNode(node) && ans.push(callback(node));\n }\n\n break;\n }\n };\n\n _traverse(beginRoot);\n } else {\n // 0: visit, 1: print\n const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{ opt: 0, node: beginRoot }];\n\n while (stack.length > 0) {\n const cur = stack.pop();\n if (cur === undefined || this.isNIL(cur.node)) continue;\n if (includeNull) {\n if (cur.node === undefined) continue;\n } else {\n if (cur.node === null || cur.node === undefined) continue;\n }\n if (cur.opt === 1) {\n ans.push(callback(cur.node));\n } else {\n switch (pattern) {\n case 'in':\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n stack.push({ opt: 1, node: cur.node });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n break;\n case 'pre':\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n stack.push({ opt: 1, node: cur.node });\n break;\n case 'post':\n stack.push({ opt: 1, node: cur.node });\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n break;\n default:\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n stack.push({ opt: 1, node: cur.node });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n break;\n }\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n */\n\n bfs<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n bfs<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[];\n\n bfs<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\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, executing a\n * callback function on each node.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the breadth-first search traversal. It takes a single parameter, which is the current node being\n * visited, and returns a value of any type.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node for the breadth-first search traversal. It can be specified as a key, a node object,\n * or `null`/`undefined` to indicate the root of the tree. If not provided, the `root` property of\n * the class is used as\n * @param iterationType - The `iterationType` parameter determines the type of iteration to be\n * performed during the breadth-first search (BFS). It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean flag that determines whether\n * to include null values in the breadth-first search traversal. If `includeNull` is set to\n * `true`, null values will be included in the traversal, otherwise they will be skipped.\n * @returns an array of values that are the result of invoking the callback function on each node in\n * the breadth-first traversal of a binary tree.\n */\n bfs<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n\n const ans: ReturnType<BTNCallback<N>>[] = [];\n\n if (iterationType === IterationType.RECURSIVE) {\n const queue: Queue<N | null | undefined> = new Queue<N | null | undefined>([beginRoot]);\n\n const traverse = (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.isNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (current.left) queue.push(current.left);\n if (current.right) queue.push(current.right);\n }\n\n traverse(level + 1);\n };\n\n traverse(0);\n } else {\n const queue = new Queue<N | null | undefined>([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.isNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (current.left) queue.push(current.left);\n if (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\n listLevels<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[][];\n\n listLevels<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[][];\n\n listLevels<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\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 returns an array of arrays, where each inner array represents a level in\n * a binary tree and contains the values returned by a callback function applied to the nodes at that\n * level.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the tree. It takes a single parameter, which can be of type `N`, `null`, or `undefined`, and\n * returns a value of any type.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node for traversing the tree. It can be either a node object (`N`), a key value\n * (`K`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.\n * @param iterationType - The `iterationType` parameter determines the type of iteration to be\n * performed on the tree. It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines\n * whether to include null values in the resulting levels. If `includeNull` is set to `true`,\n * null values will be included in the levels. If `includeNull` is set to `false`, null values will\n * be excluded\n * @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.\n */\n listLevels<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n 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 === IterationType.RECURSIVE) {\n const _recursive = (node: N | null | undefined, level: number) => {\n if (!levelsNodes[level]) levelsNodes[level] = [];\n levelsNodes[level].push(callback(node));\n if (includeNull) {\n if (node && this.isNodeOrNull(node.left)) _recursive(node.left, level + 1);\n if (node && this.isNodeOrNull(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: [N | null | undefined, 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.isNodeOrNull(node.right)) stack.push([node.right, level + 1]);\n if (node && this.isNodeOrNull(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(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function returns the predecessor of a given node in a tree.\n * @param {N} node - The parameter `node` is of type `RedBlackTreeNode`, which represents a node in a\n * tree.\n * @returns the predecessor of the given 'node'.\n */\n getPredecessor(node: N): N {\n if (this.isRealNode(node.left)) {\n let predecessor: N | null | undefined = 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 * The function `getSuccessor` returns the next node in a binary tree given a current node.\n * @param {K | N | null} [x] - The parameter `x` can be of type `K`, `N`, or `null`.\n * @returns the successor of the given node or key. The successor is the node that comes immediately\n * after the given node in the inorder traversal of the binary tree.\n */\n getSuccessor(x?: K | N | null): N | null | undefined {\n\n x = this.ensureNode(x);\n if (!this.isRealNode(x)) return undefined;\n\n if (this.isRealNode(x.right)) {\n return this.getLeftMost(x.right);\n }\n\n let y: N | null | undefined = x.parent;\n while (this.isRealNode(y) && x === y.right) {\n x = y;\n y = y.parent;\n }\n return y;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(1)\n * The `morris` function performs a depth-first traversal on a binary tree using the Morris traversal\n * algorithm.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the tree. It takes a single parameter of type `N` (the type of the nodes in the tree) and returns\n * a value of any type.\n * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function\n * determines the order in which the nodes of a binary tree are traversed. It can have one of the\n * following values:\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node\n * for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate\n * the root of the tree. If no value is provided, the default value is the root of the tree.\n * @returns The function `morris` returns an array of values that are the result of invoking the\n * `callback` function on each node in the binary tree. The type of the array elements is determined\n * by the return type of the `callback` function.\n */\n morris<C extends BTNCallback<N>>(\n callback: C = this._defaultOneParamCallback as C,\n pattern: DFSOrderPattern = 'in',\n beginRoot: BTNKeyOrNode<K, N> = this.root\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (beginRoot === null) return [];\n const ans: ReturnType<BTNCallback<N>>[] = [];\n\n let cur: N | null | undefined = beginRoot;\n const _reverseEdge = (node: N | null | undefined) => {\n let pre: N | null | undefined = null;\n let next: N | null | undefined = 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: N | null | undefined) => {\n const tail: N | null | undefined = _reverseEdge(node);\n let cur: N | null | undefined = 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\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `clone` function creates a new tree object and copies all the nodes from the original tree to\n * the new tree.\n * @returns The `clone()` method is returning a cloned instance of the `TREE` object.\n */\n clone(): TREE {\n const cloned = this.createTree();\n this.bfs(node => cloned.add([node.key, node.value]));\n return cloned;\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 `filter` function creates a new tree by iterating over the elements of the current tree and\n * adding only the elements that satisfy the given predicate function.\n * @param predicate - The `predicate` parameter is a function that takes three arguments: `value`,\n * `key`, and `index`. It should return a boolean value indicating whether the pair should be\n * included in the filtered tree or not.\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 The `filter` method is returning a new tree object that contains the key-value pairs that\n * pass the given 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\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new tree by applying a callback function to each key-value pair in\n * the original tree.\n * @param callback - The callback parameter is a function that will be called for each key-value pair\n * in the tree. It takes four arguments: the value of the current pair, the key of the current pair,\n * the index of the current pair, and a reference to the tree itself. The callback function should\n * return a new\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 you pass a value for `thisArg`, it\n * will be used as the `this` value when the callback function is called. If you don't pass a value\n * @returns The `map` method is returning a new tree object.\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 * The `print` function is used to display a binary tree structure in a visually appealing way.\n * @param {K | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `K | N | null |\n * undefined`. It represents the root node of a binary tree. The root node can have one of the\n * following types:\n * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.\n */\n print(beginRoot: BTNKeyOrNode<K, N> = this.root, options?: BinaryTreePrintOptions): void {\n const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return;\n\n if (opts.isShowUndefined) console.log(`U for undefined\n `);\n if (opts.isShowNull) console.log(`N for null\n `);\n if (opts.isShowRedBlackNIL) console.log(`S for Sentinel Node\n `);\n\n const display = (root: N | null | undefined): void => {\n const [lines, , ,] = this._displayAux(root, opts);\n for (const line of lines) {\n console.log(line);\n }\n };\n\n display(beginRoot);\n }\n\n protected* _getIterator(node = this.root): IterableIterator<[K, V | undefined]> {\n if (!node) return;\n\n if (this.iterationType === IterationType.ITERATIVE) {\n const stack: (N | null | undefined)[] = [];\n let current: N | null | undefined = node;\n\n while (current || stack.length > 0) {\n while (current && !isNaN(this.extractor(current.key))) {\n stack.push(current);\n current = current.left;\n }\n\n current = stack.pop();\n\n if (current && !isNaN(this.extractor(current.key))) {\n yield [current.key, current.value];\n current = current.right;\n }\n }\n } else {\n if (node.left && !isNaN(this.extractor(node.key))) {\n yield* this[Symbol.iterator](node.left);\n }\n yield [node.key, node.value];\n if (node.right && !isNaN(this.extractor(node.key))) {\n yield* this[Symbol.iterator](node.right);\n }\n }\n }\n\n protected _displayAux(node: N | null | undefined, 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 (node !== null && node !== undefined && isNaN(this.extractor(node.key)) && !isShowRedBlackNIL) {\n return emptyDisplayLayout;\n } else if (node !== null && node !== undefined) {\n // Display logic of normal nodes\n\n const key = node.key, line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),\n width = line.length;\n\n return _buildNodeDisplay(line, width, this._displayAux(node.left, options), 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', 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 = ' '.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 = (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth))\n + ' '.repeat(width)\n + (rightHeight > 0 ? ' '.repeat(rightMiddle) + '\\\\' + ' '.repeat(rightWidth - rightMiddle - 1) : ' '.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>[mergedLines, leftWidth + width + rightWidth, Math.max(leftHeight, rightHeight) + 2, leftWidth + Math.floor(width / 2)];\n }\n }\n\n protected _defaultOneParamCallback = (node: N) => node.key;\n\n /**\n * Swap the data of two nodes in the binary tree.\n * @param {N} srcNode - The source node to swap.\n * @param {N} destNode - The destination node to swap.\n * @returns {N} - The destination node after the swap.\n */\n protected _swapProperties(srcNode: BTNKeyOrNode<K, N>, destNode: BTNKeyOrNode<K, N>): N | 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 * The function replaces an old node with a new node in a binary tree.\n * @param {N} oldNode - The oldNode parameter represents the node that needs to be replaced in the\n * tree.\n * @param {N} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the\n * tree.\n * @returns The method is returning the newNode.\n */\n protected _replaceNode(oldNode: N, newNode: N): N {\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._root = newNode;\n }\n\n return newNode;\n }\n\n /**\n * The function `_addTo` adds a new node to a binary tree if there is an available position.\n * @param {N | null | undefined} newNode - The `newNode` parameter represents the node that you want to add to\n * the binary tree. It can be either a node object or `null`.\n * @param {N} parent - The `parent` parameter represents the parent node to which the new node will\n * be added as a child.\n * @returns either the left or right child node of the parent node, depending on which child is\n * available for adding the new node. If a new node is added, the function also updates the size of\n * the binary tree. If neither the left nor right child is available, the function returns undefined.\n * If the parent node is null, the function also returns undefined.\n */\n protected _addTo(newNode: N | null | undefined, parent: BTNKeyOrNode<K, N>): N | null | undefined {\n if (this.isNotNodeInstance(parent)) parent = this.getNode(parent);\n\n if (parent) {\n // When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.\n // In this scenario, null nodes serve as \"sentinel nodes,\" \"virtual nodes,\" or \"placeholder nodes.\"\n if (parent.left === undefined) {\n parent.left = newNode;\n if (newNode) {\n this._size = this.size + 1;\n }\n return parent.left;\n } else if (parent.right === undefined) {\n parent.right = newNode;\n if (newNode) {\n this._size = this.size + 1;\n }\n return parent.right;\n } else {\n return;\n }\n } else {\n return;\n }\n }\n\n /**\n * The function sets the root property of an object to a given value, and if the value is not null,\n * it also sets the parent property of the value to undefined.\n * @param {N | null | undefined} v - The parameter `v` is of type `N | null | undefined`, which means it can either be of\n * type `N` or `null`.\n */\n protected _setRoot(v: N | null | undefined) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\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 {\n BSTNested,\n BSTNKeyOrNode,\n BSTNodeNested,\n BSTOptions,\n BTNCallback,\n BTNExemplar,\n BTNKeyOrNode,\n BTNodePureExemplar\n} from '../../types';\nimport { BSTVariant, CP, IterationType } from '../../types';\nimport { BinaryTree, BinaryTreeNode } from './binary-tree';\nimport { IBinaryTree } from '../../interfaces';\nimport { Queue } from '../queue';\n\nexport class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, N> {\n override parent?: N;\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?: N;\n\n /**\n * Get the left child node.\n */\n override get left(): N | undefined {\n return this._left;\n }\n\n /**\n * Set the left child node.\n * @param {N | undefined} v - The left child node.\n */\n override set left(v: N | undefined) {\n if (v) {\n v.parent = this as unknown as N;\n }\n this._left = v;\n }\n\n protected override _right?: N;\n\n /**\n * Get the right child node.\n */\n override get right(): N | undefined {\n return this._right;\n }\n\n /**\n * Set the right child node.\n * @param {N | undefined} v - The right child node.\n */\n override set right(v: N | undefined) {\n if (v) {\n v.parent = this as unknown as N;\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<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>>\n extends BinaryTree<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n\n\n /**\n * This is the constructor function for a binary search tree class in TypeScript, which initializes\n * the tree with optional elements and options.\n * @param [elements] - An optional iterable of BTNExemplar objects that will be added to the\n * binary search tree.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the binary search tree. It can have the following properties:\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<BSTOptions<K>>) {\n super([], options);\n\n if (options) {\n const { variant } = options;\n if (variant) {\n this._variant = variant;\n }\n }\n\n this._root = undefined;\n\n if (elements) this.addMany(elements);\n }\n\n protected override _root?: N;\n\n override get root(): N | undefined {\n return this._root;\n }\n\n protected _variant = BSTVariant.MIN\n\n get variant() {\n return this._variant;\n }\n\n /**\n * The function creates a new binary search tree node with the given key and value.\n * @param {K} key - The key parameter is the key value that will be associated with\n * the new node. It is used to determine the position of the node in the binary search tree.\n * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It\n * represents the value associated with the node in a binary search tree.\n * @returns a new instance of the BSTNode class with the specified key and value.\n */\n override createNode(key: K, value?: V): N {\n return new BSTNode<K, V, N>(key, value) as N;\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 is a type\n * that defines various options for creating a binary search tree.\n * @returns a new instance of the BST class with the specified options.\n */\n override createTree(options?: Partial<BSTOptions<K>>): TREE {\n return new BST<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of BSTNode.\n * @param exemplar - The `exemplar` parameter is a variable of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the BSTNode class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof BSTNode;\n }\n\n\n /**\n * The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,\n * otherwise it returns undefined.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`, where:\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `exemplarToNode` function. It represents the value associated with the exemplar node.\n * @returns a node of type N or undefined.\n */\n override exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V): N | undefined {\n let node: N | undefined;\n if (exemplar === null || exemplar === undefined) {\n return;\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined || key === null) {\n return;\n } else {\n node = this.createNode(key, value);\n }\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).\n * Space Complexity: O(1) - Constant space is used.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).\n * Space Complexity: O(1) - Constant space is used.\n *\n * The `add` function adds a new node to a binary tree, updating the value if the key already exists\n * or inserting a new node if the key is unique.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can accept three types of values:\n * @param {V} [value] - The `value` parameter represents the value associated with the key that is\n * being added to the binary tree.\n * @returns The method `add` returns either the newly added node (`newNode`) or `undefined` if the\n * node was not added.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);\n if (newNode === undefined) return;\n\n if (this.root === undefined) {\n this._setRoot(newNode);\n this._size++;\n return this.root;\n }\n\n let current = this.root;\n while (current !== undefined) {\n if (this._compare(current.key, newNode.key) === CP.eq) {\n // if (current !== newNode) {\n // The key value is the same but the reference is different, update the value of the existing node\n this._replaceNode(current, newNode);\n return newNode;\n\n // } else {\n // The key value is the same and the reference is the same, replace the entire node\n // this._replaceNode(current, newNode);\n\n // return;\n // }\n } else if (this._compare(current.key, newNode.key) === CP.gt) {\n if (current.left === undefined) {\n current.left = newNode;\n newNode.parent = current;\n this._size++;\n return newNode;\n }\n current = current.left;\n } else {\n if (current.right === undefined) {\n current.right = newNode;\n newNode.parent = current;\n this._size++;\n return newNode;\n }\n current = current.right;\n }\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(k log n) - Adding each element individually in a balanced tree.\n * Space Complexity: O(k) - Additional space is required for the sorted array.\n */\n\n /**\n * Time Complexity: O(k log n) - Adding each element individually in a balanced tree.\n * Space Complexity: O(k) - Additional space is required for the sorted array.\n *\n * The `addMany` function in TypeScript adds multiple keys or nodes to a binary tree, optionally\n * balancing the tree after each addition.\n * @param keysOrNodesOrEntries - An iterable containing the keys, nodes, or entries to be added to\n * the binary tree.\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 add operation should be\n * balanced or not. If set to true, the add operation will be balanced using a binary search tree\n * algorithm. If set to false, the add operation will not be balanced and the elements will be added\n * in the order they appear in the input.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when adding multiple keys or nodes. It has a default value of\n * `this.iterationType`, which suggests that it is a property of the current object.\n * @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.\n */\n override addMany(\n keysOrNodesOrEntries: Iterable<BTNExemplar<K, V, N>>,\n values?: Iterable<V | undefined>,\n isBalanceAdd = true,\n iterationType = this.iterationType\n ): (N | undefined)[] {\n const inserted: (N | undefined)[] = [];\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 keysOrNodesOrEntries) {\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: BTNodePureExemplar<K, V, N>[] = [];\n\n const isRealBTNExemplar = (kve: BTNExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {\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 keysOrNodesOrEntries) {\n isRealBTNExemplar(kve) && realBTNExemplars.push(kve);\n }\n\n let sorted: BTNodePureExemplar<K, V, N>[] = [];\n\n sorted = realBTNExemplars.sort((a, b) => {\n let aR: number, bR: number;\n if (this.isEntry(a)) aR = this.extractor(a[0]);\n else if (this.isRealNode(a)) aR = this.extractor(a.key);\n else aR = this.extractor(a);\n\n if (this.isEntry(b)) bR = this.extractor(b[0]);\n else if (this.isRealNode(b)) bR = this.extractor(b.key);\n else bR = this.extractor(b);\n\n return aR - bR;\n });\n\n const _dfs = (arr: BTNodePureExemplar<K, V, N>[]) => {\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 === IterationType.RECURSIVE) {\n _dfs(sorted);\n } else {\n _iterate();\n }\n\n return inserted;\n }\n\n\n /**\n * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.\n * Space Complexity: O(n) - Additional space is required for the sorted array.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(1) - Constant space is used.\n *\n * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the\n * leftmost node if the comparison result is greater than.\n * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of\n * type `K`, `N`, or `undefined`. It represents the starting point for finding the last key in\n * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).\n * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to\n * be performed. It can have one of the following values:\n * @returns the key of the rightmost node in the binary tree if the comparison result is less than,\n * the key of the leftmost node if the comparison result is greater than, and the key of the\n * rightmost node otherwise. If no node is found, it returns 0.\n */\n lastKey(beginRoot: BSTNKeyOrNode<K, N> = this.root): K | undefined {\n let current = this.ensureNode(beginRoot);\n if (!current) return undefined;\n\n if (this._variant === BSTVariant.MIN) {\n // For BSTVariant.MIN, find the rightmost node\n while (current.right !== undefined) {\n current = current.right;\n }\n } else {\n // For BSTVariant.MAX, find the leftmost node\n while (current.left !== undefined) {\n current = current.left;\n }\n }\n return current.key;\n }\n\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(1) - Constant space is used.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using\n * either recursive or iterative methods.\n * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.\n * It is used to identify the node that we want to retrieve.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when searching for a node in the binary tree. It can have two possible\n * values:\n * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is\n * found in the binary tree. If no node is found, it returns `undefined`.\n */\n override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {\n if (!this.root) return undefined;\n if (iterationType === IterationType.RECURSIVE) {\n const _dfs = (cur: N): N | undefined => {\n if (cur.key === key) return cur;\n if (!cur.left && !cur.right) return;\n\n if (this._compare(cur.key, key) === CP.gt && cur.left) return _dfs(cur.left);\n if (this._compare(cur.key, key) === CP.lt && cur.right) return _dfs(cur.right);\n };\n\n return _dfs(this.root);\n } else {\n const queue = new Queue<N>([this.root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n if (this._compare(cur.key, key) === CP.eq) return cur;\n if (this._compare(cur.key, key) === CP.gt) cur.left && queue.push(cur.left);\n if (this._compare(cur.key, key) === CP.lt) cur.right && queue.push(cur.right);\n }\n }\n }\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof BSTNode)\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n */\n\n /**\n * The function `ensureNode` returns the node corresponding to the given key if it is a node key,\n * otherwise it returns the key itself.\n * @param {K | N | undefined} key - The `key` parameter can be of type `K`, `N`, or\n * `undefined`.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.\n * @returns either a node object (N) or undefined.\n */\n override ensureNode(key: BSTNKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | undefined {\n return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The function `getNodes` returns an array of nodes that match a given identifier, using either a\n * recursive or iterative approach.\n * @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you\n * want to search for in the nodes of the binary tree. It can be of any type that is returned by the\n * callback function `C`.\n * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` as its\n * argument and returns a value of type `ReturnType<C>`. The `C` type parameter represents a callback\n * function type that extends the `BTNCallback<N>` type. The `BTNCallback<N>` type is\n * @param [onlyOne=false] - A boolean flag indicating whether to stop searching after finding the\n * first node that matches the identifier. If set to true, the function will return an array\n * containing only the first matching node. If set to false (default), the function will continue\n * searching for all nodes that match the identifier and return an array containing\n * @param {K | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node\n * for the traversal. It can be either a key value or a node object. If it is undefined, the\n * traversal will start from the root of the tree.\n * @param iterationType - The `iterationType` parameter determines the type of iteration to be\n * performed on the binary tree. It can have two possible values:\n * @returns The method returns an array of nodes (`N[]`).\n */\n override getNodes<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | undefined,\n callback: C = this._defaultOneParamCallback as C,\n onlyOne = false,\n beginRoot: BSTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: N[] = [];\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N) => {\n const callbackResult = callback(cur);\n if (callbackResult === identifier) {\n ans.push(cur);\n if (onlyOne) return;\n }\n\n if (!cur.left && !cur.right) return;\n // TODO potential bug\n if (callback === this._defaultOneParamCallback) {\n if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && _traverse(cur.left);\n if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && _traverse(cur.right);\n } else {\n cur.left && _traverse(cur.left);\n cur.right && _traverse(cur.right);\n }\n };\n\n _traverse(beginRoot);\n } else {\n const queue = new Queue<N>([beginRoot]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n const callbackResult = callback(cur);\n if (callbackResult === identifier) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n // TODO potential bug\n if (callback === this._defaultOneParamCallback) {\n if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && queue.push(cur.left);\n if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && queue.push(cur.right);\n } else {\n cur.left && queue.push(cur.left);\n cur.right && queue.push(cur.right);\n }\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The `lesserOrGreaterTraverse` function traverses a binary tree and returns an array of nodes that\n * are either lesser or greater than a target node, depending on the specified comparison type.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * that satisfies the condition specified by the `lesserOrGreater` parameter. It takes a single\n * parameter of type `N` (the node type) 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 than, greater than, or equal to the `targetNode`. It is of type\n * `CP`, which is a custom type representing the comparison operator. The possible values for\n * `lesserOrGreater` are\n * @param {K | N | undefined} targetNode - The `targetNode` parameter represents the node in the\n * binary tree that you want to traverse from. It can be specified either by its key, by the node\n * object itself, or it can be left undefined to start the traversal from the root of the tree.\n * @param iterationType - The `iterationType` parameter determines the type of traversal to be\n * 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<N>>(\n callback: C = this._defaultOneParamCallback as C,\n lesserOrGreater: CP = CP.lt,\n targetNode: BSTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): ReturnType<C>[] {\n targetNode = this.ensureNode(targetNode);\n const ans: ReturnType<BTNCallback<N>>[] = [];\n if (!targetNode) return ans;\n if (!this.root) return ans;\n\n const targetKey = targetNode.key;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N) => {\n const compared = this._compare(cur.key, targetKey);\n if (compared === lesserOrGreater) ans.push(callback(cur));\n\n if (!cur.left && !cur.right) return;\n if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) _traverse(cur.left);\n if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) _traverse(cur.right);\n };\n\n _traverse(this.root);\n return ans;\n } else {\n const queue = new Queue<N>([this.root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n const compared = this._compare(cur.key, targetKey);\n if (compared === lesserOrGreater) ans.push(callback(cur));\n\n if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) queue.push(cur.left);\n if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) queue.push(cur.right);\n }\n }\n return ans;\n }\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n */\n\n /**\n * Time Complexity: O(n) - Building a balanced tree from a sorted array.\n * Space Complexity: O(n) - Additional space is required for the sorted array.\n *\n * The `perfectlyBalance` function balances a binary search tree by adding nodes in a way that\n * ensures the tree is perfectly balanced.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when building a balanced binary search tree. It can have two possible\n * values:\n * @returns The function `perfectlyBalance` returns a boolean value.\n */\n perfectlyBalance(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 === 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 * Balancing Adjustment:\n * Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree.\n * AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed.\n *\n * Use Cases and Efficiency:\n * Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction.\n * AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n).\n */\n\n /**\n * Time Complexity: O(n) - Building a balanced tree from a sorted array.\n * Space Complexity: O(n) - Additional space is required for the sorted array.\n */\n\n /**\n * Time Complexity: O(n) - Visiting each node once.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The function checks if a binary tree is AVL balanced using either recursive or iterative approach.\n * @param iterationType - The `iterationType` parameter is used to determine the method of iteration\n * to check if the AVL tree is balanced. It can have two possible values:\n * @returns a boolean value.\n */\n isAVLBalanced(iterationType = this.iterationType): boolean {\n if (!this.root) return true;\n\n let balanced = true;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _height = (cur: N | undefined): 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: N[] = [];\n let node: N | undefined = this.root,\n last: N | undefined = undefined;\n const depths: Map<N, 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 : -1;\n const right = node.right ? depths.get(node.right) ?? -1 : -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\n protected _setRoot(v: N | undefined) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n\n /**\n * The function compares two values using a comparator function and returns whether the first value\n * is greater than, less than, or equal to the second value.\n * @param {K} a - The parameter \"a\" is of type K.\n * @param {K} b - The parameter \"b\" in the above code represents a K.\n * @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater\n * than), CP.lt (less than), or CP.eq (equal).\n */\n protected _compare(a: K, b: K): CP {\n const extractedA = this.extractor(a);\n const extractedB = this.extractor(b);\n const compared = this.variant === BSTVariant.MIN ? extractedA - extractedB : extractedB - extractedA;\n\n return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;\n }\n\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 { 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 get freqMap(): Record<number, number> {\n return this._freqMap;\n }\n\n protected _msb: number;\n\n get msb(): number {\n return this._msb;\n }\n\n protected _negativeCount: number;\n\n get negativeCount(): number {\n return this._negativeCount;\n }\n\n get freq(): number {\n return this._freq;\n }\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type { SegmentTreeNodeVal } from '../../types';\n\nexport class SegmentTreeNode {\n start = 0;\n end = 0;\n value: SegmentTreeNodeVal | undefined = undefined;\n sum = 0;\n left: SegmentTreeNode | undefined = undefined;\n right: SegmentTreeNode | undefined = undefined;\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\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 get values(): number[] {\n return this._values;\n }\n\n protected _start = 0;\n\n get start(): number {\n return this._start;\n }\n\n protected _end: number;\n\n get end(): number {\n return this._end;\n }\n\n protected _root: SegmentTreeNode | undefined;\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler 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 BTNCallback,\n BTNExemplar,\n BTNKeyOrNode\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNodeNested<K, V>> extends BSTNode<K, V, N> {\n height: number;\n\n constructor(key: K, value?: V) {\n super(key, value);\n this.height = 0;\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<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>, TREE extends AVLTree<K, V, N, TREE> = AVLTree<K, V, N, AVLTreeNested<K, V, N>>>\n extends BST<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n\n /**\n * The constructor function initializes an AVLTree object with optional elements and options.\n * @param [elements] - The `elements` parameter is an optional iterable of `BTNExemplar<K, V, N>`\n * objects. It represents a collection of elements that will be added to the AVL tree during\n * initialization.\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the AVL tree. It is of type `Partial<AVLTreeOptions>`, which means that you can\n * provide only a subset of the properties defined in the `AVLTreeOptions` interface.\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<AVLTreeOptions<K>>) {\n super([], options);\n if (elements) super.addMany(elements);\n }\n\n /**\n * The function creates a new AVL tree node with the specified key and value.\n * @param {K} key - The key parameter is the key value that will be associated with\n * the new node. It is used to determine the position of the node in the binary search tree.\n * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It is of\n * type `V`, which means it can be any value that is assignable to the `value` property of the\n * node type `N`.\n * @returns a new AVLTreeNode object with the specified key and value.\n */\n override createNode(key: K, value?: V): N {\n return new AVLTreeNode<K, V, N>(key, value) as N;\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>): TREE {\n return new AVLTree<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of AVLTreeNode.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the AVLTreeNode class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof AVLTreeNode;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof AVLTreeNode)\n }\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the add method of a binary tree node and balances the tree after inserting\n * a new node.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an\n * entry.\n * @param {V} [value] - The `value` parameter represents the value associated with the key that is\n * being added to the binary tree.\n * @returns The method is returning either the inserted node or undefined.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | undefined {\n if (keyOrNodeOrEntry === null) return undefined;\n const inserted = super.add(keyOrNodeOrEntry, value);\n if (inserted) this._balancePath(inserted);\n return inserted;\n }\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The delete method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the delete method of a binary tree, performs the deletion, and then\n * balances the tree if necessary.\n * @param identifier - The `identifier` parameter is the value or condition used to identify the\n * node(s) to be deleted from the binary tree. It can be of any type and is the return type of the\n * `callback` function.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * that is deleted from the binary tree. It is an optional parameter and if not provided, it will\n * default to the `_defaultOneParamCallback` function. The `callback` function should have a single\n * parameter of type `N\n * @returns The method is returning an array of `BinaryTreeDeleteResult<N>`.\n */\n override delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C = this._defaultOneParamCallback as C\n ): BinaryTreeDeleteResult<N>[] {\n if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;\n const deletedResults = super.delete(identifier, callback);\n for (const { needBalanced } of deletedResults) {\n if (needBalanced) {\n this._balancePath(needBalanced);\n }\n }\n return deletedResults;\n }\n\n\n /**\n * The `_swapProperties` function swaps the key, value, and height properties between two nodes in a binary\n * tree.\n * @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node that\n * needs to be swapped with the destination node. It can be of type `K`, `N`, or `undefined`.\n * @param {K | N | undefined} destNode - The `destNode` parameter represents the destination\n * node where the values from the source node will be swapped to.\n * @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`\n * if either `srcNode` or `destNode` is undefined.\n */\n protected override _swapProperties(srcNode: BSTNKeyOrNode<K, N>, destNode: BSTNKeyOrNode<K, N>): N | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n\n if (srcNode && destNode) {\n const { key, value, height } = destNode;\n const tempNode = this.createNode(key, value);\n\n if (tempNode) {\n tempNode.height = height;\n\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n destNode.height = srcNode.height;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n srcNode.height = tempNode.height;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n *\n * The function calculates the balance factor of a node in a binary tree.\n * @param {N} node - The parameter \"node\" represents a node in a 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: N): 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) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\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 {N} node - The parameter \"node\" represents a node in a binary tree data structure.\n */\n protected _updateHeight(node: N): 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(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The method traverses the path from the inserted node to the root.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The method traverses the path from the inserted node to the root.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\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 {N} node - The `node` parameter in the `_balancePath` function represents the node in the\n * AVL tree that needs to be balanced.\n */\n protected _balancePath(node: N): void {\n const path = this.getPathToRoot(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 // 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 * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The function `_balanceLL` performs a left-left rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceLL(A: N): 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) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The `_balanceLR` function performs a left-right rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceLR(A: N): 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 B && this._updateHeight(B);\n C && this._updateHeight(C);\n }\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The function `_balanceRR` performs a right-right rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceRR(A: N): 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 B && this._updateHeight(B);\n }\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The function `_balanceRL` performs a right-left rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceRL(A: N): 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 B && this._updateHeight(B);\n C && this._updateHeight(C);\n }\n\n protected _replaceNode(oldNode: N, newNode: N): N {\n newNode.height = oldNode.height;\n\n return super._replaceNode(oldNode, newNode)\n }\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 */\n\nimport {\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNCallback,\n BTNExemplar,\n BTNKeyOrNode,\n IterationType,\n RBTNColor,\n RBTreeOptions,\n RedBlackTreeNested,\n RedBlackTreeNodeNested\n} from '../../types';\nimport { BST, BSTNode } from './bst';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>> extends BSTNode<\n K, V,\n N\n> {\n color: RBTNColor;\n\n constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {\n super(key, value);\n this.color = color;\n }\n}\n\n/**\n * 1. Each node is either red or black.\n * 2. The root node is always black.\n * 3. Leaf nodes are typically Sentinel nodes and are considered black.\n * 4. Red nodes must have black children.\n * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.\n */\nexport class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>, TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>>\n extends BST<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n Sentinel: N = new RedBlackTreeNode<K, V>(NaN as K) as unknown as N;\n\n /**\n * This is the constructor function for a Red-Black Tree data structure in TypeScript, which\n * initializes the tree with optional elements and options.\n * @param [elements] - The `elements` parameter is an optional iterable of `BTNExemplar<K, V, N>`\n * objects. It represents the initial elements that will be added to the RBTree during its\n * construction. If this parameter is provided, the `addMany` method is called to add all the\n * elements to the\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the RBTree. It is of type `Partial<RBTreeOptions>`, which means that you can provide\n * only a subset of the properties defined in the `RBTreeOptions` interface.\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<RBTreeOptions<K>>) {\n super([], options);\n\n this._root = this.Sentinel;\n if (elements) super.addMany(elements);\n }\n\n protected _root: N;\n\n get root(): N {\n return this._root;\n }\n\n protected _size: number = 0;\n\n get size(): number {\n return this._size;\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 is the key value associated with the node. It is used to\n * identify and compare nodes in the Red-Black Tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the node. It is of type `V`, which is a generic type that can be replaced with any\n * specific type when using the `createNode` method.\n * @param {RBTNColor} color - The \"color\" parameter is used to specify the color of the node in a\n * Red-Black Tree. It can be either \"RED\" or \"BLACK\". By default, the color is set to \"BLACK\".\n * @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,\n * value, and color.\n */\n override createNode(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK): N {\n return new RedBlackTreeNode<K, V, N>(key, value, color) as N;\n }\n\n /**\n * The function creates a Red-Black Tree with the specified options and returns it.\n * @param {RBTreeOptions} [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 `RedBlackTree`\n * class.\n * @returns a new instance of a RedBlackTree object.\n */\n override createTree(options?: RBTreeOptions<K>): TREE {\n return new RedBlackTree<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of the RedBlackTreeNode class.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the RedBlackTreeNode\n * class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof RedBlackTreeNode;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof RedBlackTreeNode)\n }\n\n /**\n * The function `exemplarToNode` takes an exemplar and converts it into a node object if possible.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`, where:\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `exemplarToNode` function. It represents the value associated with the exemplar node. If a value\n * is provided, it will be used when creating the new node. If no value is provided, the new node\n * @returns a node of type N or undefined.\n */\n override exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V): N | undefined {\n let node: N | undefined;\n\n if (exemplar === null || exemplar === undefined) {\n return;\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined || key === null) {\n return;\n } else {\n node = this.createNode(key, value, RBTNColor.RED);\n }\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value, RBTNColor.RED);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The `add` function adds a new node to a binary search tree and performs necessary rotations and\n * color changes to maintain the red-black tree properties.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an\n * entry.\n * @param {V} [value] - The `value` parameter represents the value associated with the key that is\n * being added to the binary search tree.\n * @returns The method `add` returns either the newly added node (`N`) or `undefined`.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);\n if (newNode === undefined) return;\n\n newNode.left = this.Sentinel;\n newNode.right = this.Sentinel;\n\n let y: N | undefined = undefined;\n let x: N | undefined = this.root;\n\n while (x !== this.Sentinel) {\n y = x;\n if (x) {\n if (newNode.key < x.key) {\n x = x.left;\n } else if (newNode.key > x.key) {\n x = x?.right;\n } else {\n if (newNode !== x) {\n this._replaceNode(x, newNode)\n }\n return;\n }\n }\n\n }\n\n newNode.parent = y;\n if (y === undefined) {\n this._setRoot(newNode);\n } else if (newNode.key < y.key) {\n y.left = newNode;\n } else {\n y.right = newNode;\n }\n\n if (newNode.parent === undefined) {\n newNode.color = RBTNColor.BLACK;\n this._size++;\n return;\n }\n\n if (newNode.parent.parent === undefined) {\n this._size++;\n return;\n }\n\n this._fixInsert(newNode);\n this._size++;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a node from a binary tree based on a given identifier and updates\n * the tree accordingly.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * that you want to use to identify the node that you want to delete from the binary tree. It can be\n * of any type that is returned by the callback function `C`. It can also be `null` or `undefined` if\n * you don't want to\n * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` and\n * returns a value of type `ReturnType<C>`. It is used to determine if a node should be deleted based\n * on its identifier. The `callback` function is optional and defaults to `this._defaultOneParam\n * @returns an array of `BinaryTreeDeleteResult<N>`.\n */\n delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C\n ): BinaryTreeDeleteResult<N>[] {\n const ans: BinaryTreeDeleteResult<N>[] = [];\n if (identifier === null) return ans;\n const helper = (node: N | undefined): void => {\n let z: N = this.Sentinel;\n let x: N | undefined, y: N;\n while (node !== this.Sentinel) {\n if (node && callback(node) === identifier) {\n z = node;\n }\n\n if (node && identifier && callback(node) <= identifier) {\n node = node.right;\n } else {\n node = node?.left;\n }\n }\n\n if (z === this.Sentinel) {\n this._size--;\n return;\n }\n\n y = z;\n let yOriginalColor: number = y.color;\n if (z.left === this.Sentinel) {\n x = z.right;\n this._rbTransplant(z, z.right!);\n } else if (z.right === this.Sentinel) {\n x = z.left;\n this._rbTransplant(z, z.left!);\n } else {\n y = this.getLeftMost(z.right)!;\n yOriginalColor = y.color;\n x = y.right;\n if (y.parent === z) {\n x!.parent = y;\n } else {\n this._rbTransplant(y, y.right!);\n y.right = z.right;\n y.right!.parent = y;\n }\n\n this._rbTransplant(z, y);\n y.left = z.left;\n y.left!.parent = y;\n y.color = z.color;\n }\n if (yOriginalColor === RBTNColor.BLACK) {\n this._fixDelete(x!);\n }\n this._size--;\n };\n helper(this.root);\n // TODO\n return ans;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n override isRealNode(node: N | undefined): node is N {\n if (node === this.Sentinel || node === undefined) return false;\n return node instanceof RedBlackTreeNode;\n }\n\n getNode<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: N | undefined,\n iterationType?: IterationType\n ): N | undefined;\n\n getNode<C extends BTNCallback<N, N>>(\n identifier: N | undefined,\n callback?: C,\n beginRoot?: N | undefined,\n iterationType?: IterationType\n ): N | undefined;\n\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n beginRoot?: N | undefined,\n iterationType?: IterationType\n ): N | undefined;\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The function `getNode` retrieves a single node from a binary tree based on a given identifier and\n * callback function.\n * @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value used to\n * identify the node you want to retrieve. It can be of any type that is the return type of the `C`\n * callback function. If the `identifier` is `undefined`, it means you want to retrieve the first\n * node that matches the other criteria\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the binary tree. It is used to determine if a node matches the given identifier. The `callback`\n * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and\n * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is the starting point for\n * searching for a node in a binary tree. It can be either a key value or a node object. If it is not\n * provided, the search will start from the root of the binary tree.\n * @param iterationType - The `iterationType` parameter is a variable that determines the type of\n * iteration to be performed when searching for nodes in the binary tree. It is used in the\n * `getNodes` method, which is called within the `getNode` method.\n * @returns a value of type `N`, `null`, or `undefined`.\n */\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BSTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C;\n beginRoot = this.ensureNode(beginRoot);\n return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function returns the predecessor of a given node in a red-black tree.\n * @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a\n * Red-Black Tree.\n * @returns the predecessor of the given RedBlackTreeNode 'x'.\n */\n override getPredecessor(x: N): N {\n if (this.isRealNode(x.left)) {\n return this.getRightMost(x.left)!;\n }\n\n let y: N | undefined = x.parent;\n while (this.isRealNode(y) && x === y.left) {\n x = y!;\n y = y!.parent;\n }\n\n return y!;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n override clear() {\n this._root = this.Sentinel;\n this._size = 0;\n }\n\n protected override _setRoot(v: N) {\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function performs a left rotation on a binary tree node.\n * @param {RedBlackTreeNode} x - The parameter `x` is of type `N`, which likely represents a node in a binary tree.\n */\n protected _leftRotate(x: N): void {\n if (x.right) {\n const y: N = x.right;\n x.right = y.left;\n if (y.left !== this.Sentinel) {\n if (y.left) y.left.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === undefined) {\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 y.left = x;\n x.parent = y;\n }\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 performs a right rotation on a red-black tree node.\n * @param {RedBlackTreeNode} x - x is a RedBlackTreeNode, which represents the node that needs to be right\n * rotated.\n */\n protected _rightRotate(x: N): void {\n if (x.left) {\n const y: N = x.left;\n x.left = y.right;\n if (y.right !== this.Sentinel) {\n if (y.right) y.right.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === undefined) {\n this._setRoot(y);\n } else if (x === x.parent.right) {\n x.parent.right = y;\n } else {\n x.parent.left = y;\n }\n y.right = x;\n x.parent = y;\n }\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The function `_fixDelete` is used to fix the red-black tree after a node deletion.\n * @param {RedBlackTreeNode} x - The parameter `x` represents a node in a Red-Black Tree (RBT).\n */\n protected _fixDelete(x: N): void {\n let s: N | undefined;\n while (x !== this.root && x.color === RBTNColor.BLACK) {\n if (x.parent && x === x.parent.left) {\n s = x.parent.right!;\n if (s.color === 1) {\n s.color = RBTNColor.BLACK;\n x.parent.color = RBTNColor.RED;\n this._leftRotate(x.parent);\n s = x.parent.right!;\n }\n\n if (s.left !== undefined && s.left.color === RBTNColor.BLACK && s.right && s.right.color === RBTNColor.BLACK) {\n s.color = RBTNColor.RED;\n x = x.parent;\n } else {\n if (s.right && s.right.color === RBTNColor.BLACK) {\n if (s.left) s.left.color = RBTNColor.BLACK;\n s.color = RBTNColor.RED;\n this._rightRotate(s);\n s = x.parent.right;\n }\n\n if (s) s.color = x.parent.color;\n x.parent.color = RBTNColor.BLACK;\n if (s && s.right) s.right.color = RBTNColor.BLACK;\n this._leftRotate(x.parent);\n x = this.root;\n }\n } else {\n s = x.parent!.left!;\n if (s.color === 1) {\n s.color = RBTNColor.BLACK;\n x.parent!.color = RBTNColor.RED;\n this._rightRotate(x.parent!);\n s = x.parent!.left;\n }\n\n if (s && s.right && s.right.color === RBTNColor.BLACK && s.right.color === RBTNColor.BLACK) {\n s.color = RBTNColor.RED;\n x = x.parent!;\n } else {\n if (s && s.left && s.left.color === RBTNColor.BLACK) {\n if (s.right) s.right.color = RBTNColor.BLACK;\n s.color = RBTNColor.RED;\n this._leftRotate(s);\n s = x.parent!.left;\n }\n\n if (s) s.color = x.parent!.color;\n x.parent!.color = RBTNColor.BLACK;\n if (s && s.left) s.left.color = RBTNColor.BLACK;\n this._rightRotate(x.parent!);\n x = this.root;\n }\n }\n }\n x.color = RBTNColor.BLACK;\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 `_rbTransplant` replaces one node in a red-black tree with another node.\n * @param {RedBlackTreeNode} u - The parameter \"u\" represents a RedBlackTreeNode object.\n * @param {RedBlackTreeNode} v - The parameter \"v\" is a RedBlackTreeNode object.\n */\n protected _rbTransplant(u: N, v: N): void {\n if (u.parent === undefined) {\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 v.parent = u.parent;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The `_fixInsert` function is used to fix the red-black tree after an insertion operation.\n * @param {RedBlackTreeNode} k - The parameter `k` is a RedBlackTreeNode object, which represents a node in a\n * red-black tree.\n */\n protected _fixInsert(k: N): void {\n let u: N | undefined;\n while (k.parent && k.parent.color === 1) {\n if (k.parent.parent && k.parent === k.parent.parent.right) {\n u = k.parent.parent.left;\n if (u && u.color === 1) {\n u.color = RBTNColor.BLACK;\n k.parent.color = RBTNColor.BLACK;\n k.parent.parent.color = RBTNColor.RED;\n k = k.parent.parent;\n } else {\n if (k === k.parent.left) {\n k = k.parent;\n this._rightRotate(k);\n }\n\n k.parent!.color = RBTNColor.BLACK;\n k.parent!.parent!.color = RBTNColor.RED;\n this._leftRotate(k.parent!.parent!);\n }\n } else {\n u = k.parent.parent!.right;\n\n if (u && u.color === 1) {\n u.color = RBTNColor.BLACK;\n k.parent.color = RBTNColor.BLACK;\n k.parent.parent!.color = RBTNColor.RED;\n k = k.parent.parent!;\n } else {\n if (k === k.parent.right) {\n k = k.parent;\n this._leftRotate(k);\n }\n\n k.parent!.color = RBTNColor.BLACK;\n k.parent!.parent!.color = RBTNColor.RED;\n this._rightRotate(k.parent!.parent!);\n }\n }\n if (k === this.root) {\n break;\n }\n }\n this.root.color = RBTNColor.BLACK;\n }\n\n /**\n * The function replaces an old node with a new node while preserving the color of the old node.\n * @param {N} oldNode - The `oldNode` parameter represents the node that needs to be replaced in a\n * data structure. It is of type `N`, which is the type of the nodes in the data structure.\n * @param {N} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the\n * data structure.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, passing in the `oldNode` and `newNode` as arguments.\n */\n protected _replaceNode(oldNode: N, newNode: N): N {\n newNode.color = oldNode.color;\n\n return super._replaceNode(oldNode, newNode)\n }\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 {\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNCallback,\n BTNExemplar,\n BTNKeyOrNode,\n TreeMultimapNested,\n TreeMultimapNodeNested,\n TreeMultimapOptions\n} from '../../types';\nimport { FamilyPosition, IterationType } from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { AVLTree, AVLTreeNode } from './avl-tree';\n\nexport class TreeMultimapNode<\n K = any,\n V = any,\n N extends TreeMultimapNode<K, V, N> = TreeMultimapNodeNested<K, V>\n> extends AVLTreeNode<K, V, N> {\n count: number;\n\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\n/**\n * The only distinction between a TreeMultimap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.\n */\nexport class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,\n TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>>\n extends AVLTree<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<TreeMultimapOptions<K>>) {\n super([], options);\n if (elements) this.addMany(elements);\n }\n\n private _count = 0;\n\n // TODO the _count is not accurate after nodes count modified\n get count(): number {\n let sum = 0;\n this.subTreeTraverse(node => sum += node.count);\n return sum;\n }\n\n /**\n * The function creates a new BSTNode with the given key, value, and count.\n * @param {K} key - The key parameter is the unique identifier for the binary tree node. It is used to\n * distinguish one node from another in the tree.\n * @param {N} value - The `value` parameter represents the value that will be stored in the binary search tree node.\n * @param {number} [count] - The \"count\" parameter is an optional parameter of type number. It represents the number of\n * occurrences of the value in the binary search tree node. If not provided, the count will default to 1.\n * @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).\n */\n override createNode(key: K, value?: V, count?: number): N {\n return new TreeMultimapNode(key, value, count) as N;\n }\n\n override createTree(options?: TreeMultimapOptions<K>): TREE {\n return new TreeMultimap<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of the TreeMultimapNode class.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the TreeMultimapNode\n * class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof TreeMultimapNode;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof TreeMultimapNode)\n }\n\n /**\n * The function `exemplarToNode` converts an exemplar object into a node object.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`, which means it\n * can be one of the following:\n * @param {V} [value] - The `value` parameter is an optional argument that represents the value\n * associated with the node. It is of type `V`, which can be any data type. If no value is provided,\n * it defaults to `undefined`.\n * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of\n * times the value should be added to the node. If not provided, it defaults to 1.\n * @returns a node of type `N` or `undefined`.\n */\n override exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V, count = 1): N | undefined {\n let node: N | undefined;\n if (exemplar === undefined || exemplar === null) {\n return;\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined || key === null) {\n return;\n } else {\n node = this.createNode(key, value, count);\n }\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value, count);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the add method of a binary tree node and adds a new node to the tree.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an\n * entry. It represents the key, node, or entry that you want to add to the binary tree.\n * @param {V} [value] - The `value` parameter represents the value associated with the key in the\n * binary tree node. It is an optional parameter, meaning it can be omitted when calling the `add`\n * method.\n * @param [count=1] - The `count` parameter represents the number of times the key-value pair should\n * be added to the binary tree. By default, it is set to 1, meaning that the key-value pair will be\n * added once. However, you can specify a different value for `count` if you want to add\n * @returns The method is returning either the newly inserted node or `undefined` if the insertion\n * was not successful.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V, count = 1): N | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value, count);\n if (newNode === undefined) return;\n\n const orgNodeCount = newNode?.count || 0;\n const inserted = super.add(newNode);\n if (inserted) {\n this._count += orgNodeCount;\n }\n return inserted;\n }\n\n /**\n * Time Complexity: O(k log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(k log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the addMany method to add multiple keys, nodes, or entries to a data\n * structure.\n * @param keysOrNodesOrEntries - The parameter `keysOrNodesOrEntries` is an iterable that can contain\n * either keys, nodes, or entries.\n * @returns The method is returning an array of type `N | undefined`.\n */\n override addMany(keysOrNodesOrEntries: Iterable<BTNExemplar<K, V, N>>): (N | undefined)[] {\n return super.addMany(keysOrNodesOrEntries);\n }\n\n /**\n * Time Complexity: O(1) - constant time, as it performs basic pointer assignments.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(n log n) - logarithmic time for each insertion, where \"n\" is the number of nodes in the tree. This is because the method calls the add method for each node.\n * Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes.\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 - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when building the balanced binary search tree. It can have two possible\n * values:\n * @returns a boolean value.\n */\n override perfectlyBalance(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 === 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(k log n) - logarithmic time for each insertion, where \"n\" is the number of nodes in the tree, and \"k\" is the number of keys to be inserted. This is because the method iterates through the keys and calls the add method for each.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The delete method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The `delete` function in TypeScript is used to remove a node from a binary tree, taking into\n * account the count of the node and balancing the tree if necessary.\n * @param identifier - The identifier is the value or key that is used to identify the node that\n * needs to be deleted from the binary tree. It can be of any type that is returned by the callback\n * function.\n * @param {C} callback - The `callback` parameter is a function that is used to determine if a node\n * should be deleted. It is optional and defaults to a default callback function. The `callback`\n * function takes one parameter, which is the identifier of the node, and returns a value that is\n * used to identify the node to\n * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node\n * being deleted. If set to true, the count of the node will not be considered and the node will be\n * deleted regardless of its count. If set to false (default), the count of the node will be\n * decremented by 1 and\n * @returns an array of `BinaryTreeDeleteResult<N>`.\n */\n override delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C = this._defaultOneParamCallback as C,\n ignoreCount = false\n ): BinaryTreeDeleteResult<N>[] {\n const deletedResult: BinaryTreeDeleteResult<N>[] = [];\n if (!this.root) return deletedResult;\n\n const curr: N | undefined = this.getNode(identifier, callback) ?? undefined;\n if (!curr) return deletedResult;\n\n const parent: N | undefined = curr?.parent ? curr.parent : undefined;\n let needBalanced: N | undefined = undefined,\n orgCurrent: N | 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 === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {\n parent.left = curr.right;\n } else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {\n parent.right = curr.right;\n }\n needBalanced = parent;\n }\n } else {\n const leftSubTreeRightMost = curr.left ? this.getRightMost(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(n log n) - logarithmic time for each insertion, where \"n\" is the number of nodes in the tree. This is because the method calls the add method for each node.\n * Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes.\n */\n\n /**\n * The clear() function clears the contents of a data structure and sets the count to zero.\n */\n override clear() {\n super.clear();\n this._count = 0;\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 `clone` function creates 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) - constant time, as it performs basic pointer assignments.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n *\n * The function adds a new node to a binary tree, either as the left child or the right child of a\n * given parent node.\n * @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be\n * added to the binary tree. It can be of type `N` (which represents a node in the binary tree) or\n * `undefined` if there is no node to add.\n * @param {K | N | undefined} parent - The `parent` parameter represents the parent node to\n * which the new node will be added as a child. It can be either a node object (`N`) or a key value\n * (`K`).\n * @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was\n * added, or `undefined` if no node was added.\n */\n protected override _addTo(newNode: N | undefined, parent: BSTNKeyOrNode<K, N>): N | undefined {\n parent = this.ensureNode(parent);\n if (parent) {\n if (parent.left === undefined) {\n parent.left = newNode;\n if (newNode !== undefined) {\n this._size = this.size + 1;\n this._count += newNode.count;\n }\n\n return parent.left;\n } else if (parent.right === undefined) {\n parent.right = newNode;\n if (newNode !== undefined) {\n this._size = this.size + 1;\n this._count += newNode.count;\n }\n return parent.right;\n } else {\n return;\n }\n } else {\n return;\n }\n }\n\n /**\n * The `_swapProperties` function swaps the key, value, count, and height properties between two nodes.\n * @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node from\n * which the values will be swapped. It can be of type `K`, `N`, or `undefined`.\n * @param {K | N | undefined} destNode - The `destNode` parameter represents the destination\n * node where the values from the source node will be swapped to.\n * @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`\n * if either `srcNode` or `destNode` is undefined.\n */\n protected override _swapProperties(srcNode: BSTNKeyOrNode<K, N>, destNode: BSTNKeyOrNode<K, N>): N | 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 protected _replaceNode(oldNode: N, newNode: N): N {\n newNode.count = oldNode.count + newNode.count\n return super._replaceNode(oldNode, newNode);\n }\n}\n","export class TreeNode<V = any> {\n key: string;\n value?: V | undefined;\n children?: TreeNode<V>[] | undefined;\n\n constructor(key: string, value?: V, children?: TreeNode<V>[]) {\n this.key = key;\n this.value = value || undefined;\n this.children = children || [];\n }\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 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","/**\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 { 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> extends Heap<E> {\n constructor(elements?: Iterable<E>, options?: PriorityQueueOptions<E>) {\n super(elements, options);\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 { PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MinPriorityQueue<E = any> extends PriorityQueue<E> {\n constructor(elements?: Iterable<E>,\n options: PriorityQueueOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return a - b;\n }\n }\n }\n ) {\n super(elements, options);\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 { PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MaxPriorityQueue<E = any> extends PriorityQueue<E> {\n constructor(\n elements?: Iterable<E>,\n options: PriorityQueueOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return b - a;\n }\n }\n }\n ) {\n super(elements, options);\n }\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 */\n// todo need to be improved\nexport class MatrixNTI2D<V = any> {\n protected readonly _matrix: Array<Array<V>>;\n\n /**\n * The constructor creates a matrix with the specified number of rows and columns, and initializes all elements to a\n * given initial value or 0 if not provided.\n * @param options - An object containing the following properties:\n */\n constructor(options: { row: number; col: number; initialVal?: V }) {\n const { row, col, initialVal } = options;\n this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));\n }\n\n /* The `toArray` method returns the matrix as a two-dimensional array. It converts the internal representation of the\n matrix, which is an array of arrays, into a format that is more commonly used in JavaScript. */\n toArray(): Array<Array<V>> {\n return this._matrix;\n }\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 */\nexport class Vector2D {\n constructor(\n public x: number = 0,\n public y: number = 0,\n public w: number = 1 // needed for matrix multiplication\n ) {\n }\n\n /**\n * The function checks if the x and y values of a point are both zero.\n * @returns A boolean value indicating whether both the x and y properties of the object are equal to 0.\n */\n get isZero(): boolean {\n return this.x === 0 && this.y === 0;\n }\n\n /**\n * The above function calculates the length of a vector using the Pythagorean theorem.\n * @returns The length of a vector, calculated using the Pythagorean theorem.\n */\n get length(): number {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n }\n\n /**\n * The function calculates the square of the length of a vector.\n * @returns The method is returning the sum of the squares of the x and y values.\n */\n get lengthSq(): number {\n return this.x * this.x + this.y * this.y;\n }\n\n /**\n * The \"rounded\" function returns a new Vector2D object with the x and y values rounded to the nearest whole number.\n * @returns The method is returning a new instance of the Vector2D class with the x and y values rounded to the nearest\n * whole number.\n */\n get rounded(): Vector2D {\n return new Vector2D(Math.round(this.x), Math.round(this.y));\n }\n\n /**\n * The function \"add\" takes two Vector2D objects as parameters and returns a new Vector2D object with the sum of their\n * x and y components.\n * @param {Vector2D} vector1 - The parameter `vector1` is an instance of the `Vector2D` class. It represents a\n * 2-dimensional vector with an `x` and `y` component.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is of type Vector2D. It represents a 2-dimensional vector with\n * an x and y component.\n * @returns The method is returning a new instance of the Vector2D class with the x and y components of the two input\n * vectors added together.\n */\n static add(vector1: Vector2D, vector2: Vector2D): Vector2D {\n return new Vector2D(vector1.x + vector2.x, vector1.y + vector2.y);\n }\n\n /**\n * The subtract function takes two Vector2D objects as parameters and returns a new Vector2D object with the x and y\n * components subtracted.\n * @param {Vector2D} vector1 - The parameter `vector1` is an instance of the `Vector2D` class, representing a\n * 2-dimensional vector. It has properties `x` and `y` which represent the x and y components of the vector\n * respectively.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is a Vector2D object. It represents the second vector that you\n * want to subtract from the first vector.\n * @returns The method is returning a new Vector2D object with the x and y components subtracted from vector1 and\n * vector2.\n */\n static subtract(vector1: Vector2D, vector2: Vector2D): Vector2D {\n return new Vector2D(vector1.x - vector2.x, vector1.y - vector2.y);\n }\n\n /**\n * The function subtracts a given value from the x and y components of a Vector2D object and returns a new Vector2D\n * object.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector with\n * x and y components.\n * @param {number} value - The \"value\" parameter is a number that will be subtracted from both the x and y components\n * of the \"vector\" parameter.\n * @returns A new Vector2D object with the x and y values subtracted by the given value.\n */\n static subtractValue(vector: Vector2D, value: number): Vector2D {\n return new Vector2D(vector.x - value, vector.y - value);\n }\n\n /**\n * The function multiplies a Vector2D object by a given value.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector with\n * x and y components.\n * @param {number} value - The \"value\" parameter is a number that represents the value by which the x and y components\n * of the vector will be multiplied.\n * @returns A new Vector2D object with the x and y values multiplied by the given value.\n */\n static multiply(vector: Vector2D, value: number): Vector2D {\n return new Vector2D(vector.x * value, vector.y * value);\n }\n\n /**\n * The function divides the x and y components of a Vector2D by a given value and returns a new Vector2D.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector with\n * x and y components.\n * @param {number} value - The value parameter is a number that will be used to divide the x and y components of the\n * vector.\n * @returns A new instance of the Vector2D class with the x and y values divided by the given value.\n */\n static divide(vector: Vector2D, value: number): Vector2D {\n return new Vector2D(vector.x / value, vector.y / value);\n }\n\n /**\n * The function checks if two Vector2D objects are equal by comparing their x and y values.\n * @param {Vector2D} vector1 - The parameter `vector1` is of type `Vector2D`, which represents a 2-dimensional vector.\n * It has two properties: `x` and `y`, which represent the x and y components of the vector, respectively.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is of type Vector2D.\n * @returns a boolean value, which indicates whether the two input vectors are equal or not.\n */\n static equals(vector1: Vector2D, vector2: Vector2D): boolean {\n return vector1.x === vector2.x && vector1.y === vector2.y;\n }\n\n /**\n * The function checks if two Vector2D objects are equal within a specified rounding factor.\n * @param {Vector2D} vector1 - The first vector to compare.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is a Vector2D object, which represents a 2-dimensional vector.\n * It is used as one of the inputs for the \"equalsRounded\" function.\n * @param [roundingFactor=12] - The roundingFactor parameter is used to determine the threshold for considering two\n * vectors as equal. If the absolute difference in the x and y components of the vectors is less than the\n * roundingFactor, the vectors are considered equal.\n * @returns a boolean value.\n */\n static equalsRounded(vector1: Vector2D, vector2: Vector2D, roundingFactor = 12): boolean {\n const vector = Vector2D.abs(Vector2D.subtract(vector1, vector2));\n if (vector.x < roundingFactor && vector.y < roundingFactor) {\n return true;\n }\n\n return false;\n }\n\n /**\n * The normalize function takes a vector as input and returns a normalized version of the vector.Normalizes the vector if it matches a certain condition\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D.\n * @returns the normalized vector if its length is greater than a very small value (epsilon), otherwise it returns the\n * original vector.\n */\n static normalize(vector: Vector2D): Vector2D {\n const length = vector.length;\n if (length > 2.220446049250313e-16) {\n // Epsilon\n return Vector2D.divide(vector, length);\n }\n\n return vector;\n }\n\n /**\n * The function truncates a vector to a maximum length if it exceeds that length.Adjusts x and y so that the length of the vector does not exceed max\n * @param {Vector2D} vector - A 2D vector represented by the Vector2D class.\n * @param {number} max - The `max` parameter is a number that represents the maximum length that the `vector` should\n * have.\n * @returns either the original vector or a truncated version of the vector, depending on whether the length of the\n * vector is greater than the maximum value specified.\n */\n static truncate(vector: Vector2D, max: number): Vector2D {\n if (vector.length > max) {\n return Vector2D.multiply(Vector2D.normalize(vector), max);\n }\n\n return vector;\n }\n\n /**\n * The function returns a new Vector2D object that is perpendicular to the input vector.The vector that is perpendicular to this one\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D.\n * @returns A new Vector2D object is being returned.\n */\n static perp(vector: Vector2D): Vector2D {\n return new Vector2D(-vector.y, vector.x);\n }\n\n /**\n * The reverse function takes a Vector2D object and returns a new Vector2D object with the negated x and y values.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector. It\n * has two properties: \"x\" and \"y\", which represent the x and y components of the vector, respectively.\n * @returns A new Vector2D object with the negated x and y values of the input vector. Returns the vector that is the reverse of this vector\n */\n static reverse(vector: Vector2D): Vector2D {\n return new Vector2D(-vector.x, -vector.y);\n }\n\n /**\n * The function takes a Vector2D object as input and returns a new Vector2D object with the absolute values of its x\n * and y components.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector. It\n * has two properties: \"x\" and \"y\", which represent the x and y components of the vector, respectively.\n * @returns The method is returning a new Vector2D object with the absolute values of the x and y components of the\n * input vector.\n */\n static abs(vector: Vector2D): Vector2D {\n return new Vector2D(Math.abs(vector.x), Math.abs(vector.y));\n }\n\n /**\n * The dot function calculates the dot product of two 2D vectors.The dot product of v1 and v2\n * @param {Vector2D} vector1 - The parameter `vector1` represents a 2D vector with its x and y components.\n * @param {Vector2D} vector2 - The \"vector2\" parameter is a Vector2D object. It represents a two-dimensional vector\n * with an x and y component.\n * @returns The dot product of the two input vectors.\n */\n static dot(vector1: Vector2D, vector2: Vector2D): number {\n return vector1.x * vector2.x + vector1.y * vector2.y;\n }\n\n // /**\n // * Transform vectors based on the current tranformation matrices: translation, rotation and scale\n // * @param vectors The vectors to transform\n // */\n // static transform(vector: Vector2D, transformation: Matrix2D): Vector2D {\n // return Matrix2D.multiplyByVector(transformation, vector)\n // }\n\n // /**\n // * Transform vectors based on the current tranformation matrices: translation, rotation and scale\n // * @param vectors The vectors to transform\n // */\n // static transformList(vectors: Vector2D[], transformation: Matrix2D): Vector2D[] {\n // return vectors.map(vector => Matrix2D.multiplyByVector(transformation, vector))\n // }\n\n /**\n * The function calculates the distance between two points in a two-dimensional space.\n * @param {Vector2D} vector1 - The parameter `vector1` represents the first vector in 2D space, while `vector2`\n * represents the second vector. Each vector has an `x` and `y` component, which represent their respective coordinates\n * in the 2D space.\n * @param {Vector2D} vector2 - The `vector2` parameter represents the second vector in the calculation of distance. It\n * is an instance of the `Vector2D` class, which typically has properties `x` and `y` representing the coordinates of\n * the vector in a 2D space.\n * @returns The distance between vector1 and vector2.\n */\n static distance(vector1: Vector2D, vector2: Vector2D): number {\n const ySeparation = vector2.y - vector1.y;\n const xSeparation = vector2.x - vector1.x;\n return Math.sqrt(ySeparation * ySeparation + xSeparation * xSeparation);\n }\n\n /**\n * The function calculates the squared distance between two 2D vectors.\n * @param {Vector2D} vector1 - The parameter `vector1` represents the first vector, which is an instance of the\n * `Vector2D` class. It contains the x and y coordinates of the vector.\n * @param {Vector2D} vector2 - The `vector2` parameter represents the second vector in a two-dimensional space. It has\n * properties `x` and `y` which represent the coordinates of the vector.\n * @returns the square of the distance between the two input vectors.\n */\n static distanceSq(vector1: Vector2D, vector2: Vector2D): number {\n const ySeparation = vector2.y - vector1.y;\n const xSeparation = vector2.x - vector1.x;\n return ySeparation * ySeparation + xSeparation * xSeparation;\n }\n\n /**\n * The sign function determines the sign of the cross product between two 2D vectors.\n * (assuming the Y axis is pointing down, X axis to right like a Window app)\n * @param {Vector2D} vector1 - The parameter `vector1` is of type `Vector2D`, which represents a 2-dimensional vector.\n * It likely has properties `x` and `y` representing the x and y components of the vector, respectively.\n * @param {Vector2D} vector2 - The above code defines a function called \"sign\" that takes two parameters: vector1 and\n * vector2. Both vector1 and vector2 are of type Vector2D.\n * @returns either -1 or 1. Returns positive if v2 is clockwise of this vector, negative if counterclockwise\n */\n static sign(vector1: Vector2D, vector2: Vector2D): number {\n if (vector1.y * vector2.x > vector1.x * vector2.y) {\n return -1;\n }\n\n return 1;\n }\n\n /**\n * The function calculates the angle between a given vector and the negative y-axis.\n * @param {Vector2D} vector - The \"vector\" parameter is an instance of the Vector2D class, which represents a\n * 2-dimensional vector. It has two properties: \"x\" and \"y\", which represent the x and y components of the vector,\n * respectively.\n * @returns the angle between the given vector and the vector (0, -1) in radians.Returns the angle between origin and the given vector in radians\n */\n static angle(vector: Vector2D): number {\n const origin = new Vector2D(0, -1);\n const radian = Math.acos(Vector2D.dot(vector, origin) / (vector.length * origin.length));\n return Vector2D.sign(vector, origin) === 1 ? Math.PI * 2 - radian : radian;\n }\n\n /**\n * The function \"random\" generates a random Vector2D object with x and y values within the specified range.\n * @param {number} maxX - The maxX parameter represents the maximum value for the x-coordinate of the random vector.\n * @param {number} maxY - The `maxY` parameter represents the maximum value for the y-coordinate of the generated\n * random vector.\n * @returns a new instance of the Vector2D class with random x and y values.\n */\n static random(maxX: number, maxY: number): Vector2D {\n const randX = Math.floor(Math.random() * maxX - maxX / 2);\n const randY = Math.floor(Math.random() * maxY - maxY / 2);\n return new Vector2D(randX, randY);\n }\n\n /**\n * The function sets the values of x and y to zero.\n */\n zero(): void {\n this.x = 0;\n this.y = 0;\n }\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 { Vector2D } from './vector2d';\n\nexport class Matrix2D {\n protected readonly _matrix: number[][];\n\n /**\n * The constructor function initializes a Matrix2D object with either a default identity matrix, or a provided matrix\n * or Vector2D object.\n * @param {number[][] | Vector2D} [value] - The `value` parameter can be either a 2D array of numbers (`number[][]`) or\n * an instance of the `Vector2D` class.\n */\n constructor(value?: number[][] | Vector2D) {\n if (typeof value === 'undefined') {\n this._matrix = Matrix2D.identity;\n } else if (value instanceof Vector2D) {\n this._matrix = Matrix2D.identity;\n this._matrix[0][0] = value.x;\n this._matrix[1][0] = value.y;\n this._matrix[2][0] = value.w;\n } else {\n this._matrix = value;\n }\n }\n\n /**\n * The function returns a 2D array with three empty arrays.\n * @returns An empty 2-dimensional array with 3 empty arrays inside.\n */\n static get empty(): number[][] {\n return [[], [], []];\n }\n\n /**\n * The above function returns a 3x3 identity matrix.\n * @returns The method is returning a 2-dimensional array of numbers representing the identity matrix.\n */\n static get identity(): number[][] {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1]\n ];\n }\n\n /**\n * The function returns a two-dimensional array of numbers.\n * @returns The getter method is returning the value of the private variable `_matrix`, which is a two-dimensional\n * array of numbers.\n */\n get m(): number[][] {\n return this._matrix;\n }\n\n /**\n * The function takes two 2D matrices as input and returns their sum as a new 2D matrix.\n * @param {Matrix2D} matrix1 - Matrix2D - The first matrix to be added.\n * @param {Matrix2D} matrix2 - The parameter `matrix2` is a Matrix2D object.\n * @returns a new instance of the Matrix2D class, which is created using the result array.\n */\n static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = matrix1.m[i][j] + matrix2.m[i][j];\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function subtracts two 2D matrices and returns the result as a new Matrix2D object.\n * @param {Matrix2D} matrix1 - Matrix2D - The first matrix to subtract from.\n * @param {Matrix2D} matrix2 - Matrix2D is a class representing a 2D matrix. It has a property `m` which is a 2D array\n * representing the matrix elements.\n * @returns a new instance of the Matrix2D class, which is created using the result array.\n */\n static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = matrix1.m[i][j] - matrix2.m[i][j];\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function multiplies two 2D matrices and returns the result as a new Matrix2D object.\n * @param {Matrix2D} matrix1 - A 2D matrix represented by the Matrix2D class.\n * @param {Matrix2D} matrix2 - The parameter `matrix2` is a 2D matrix of size 3x3.\n * @returns a new instance of the Matrix2D class, created using the result array.\n */\n static multiply(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = 0;\n for (let k = 0; k < 3; k++) {\n result[i][j] += matrix1.m[i][k] * matrix2.m[k][j];\n }\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function multiplies each element of a 2D matrix by a given value and returns the resulting matrix.\n * @param {Matrix2D} matrix - The `matrix` parameter is an instance of the `Matrix2D` class, which represents a 2D\n * matrix. It contains a property `m` that is a 2D array representing the matrix elements.\n * @param {number} value - The `value` parameter is a number that you want to multiply each element of the `matrix` by.\n * @returns a new instance of the Matrix2D class, which is created using the result array.\n */\n static multiplyByValue(matrix: Matrix2D, value: number): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = matrix.m[i][j] * value;\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function multiplies a 2D matrix by a 2D vector and returns the result as a 2D vector.\n * @param {Matrix2D} matrix - The parameter \"matrix\" is of type Matrix2D. It represents a 2-dimensional matrix.\n * @param {Vector2D} vector - The \"vector\" parameter is a 2D vector, represented by an object of type Vector2D.\n * @returns a Vector2D.\n */\n static multiplyByVector(matrix: Matrix2D, vector: Vector2D): Vector2D {\n const resultMatrix = Matrix2D.multiply(matrix, new Matrix2D(vector));\n return resultMatrix.toVector();\n }\n\n /**\n * The function returns a 2D matrix that scales and flips a vector around the center of a given width and height.\n * @param {number} width - The width parameter represents the width of the view or the canvas. It is a number that\n * specifies the width in pixels or any other unit of measurement.\n * @param {number} height - The height parameter represents the height of the view or the canvas. It is used to\n * calculate the centerY value, which is the vertical center of the view.\n * @returns a Matrix2D object.\n */\n static view(width: number, height: number): Matrix2D {\n const scaleStep = 1; // Scale every vector * scaleStep\n const centerX = width / 2;\n const centerY = height / 2;\n const flipX = Math.cos(Math.PI); // rotate 180deg / 3.14radian around X-axis\n\n return new Matrix2D([\n [scaleStep, 0, centerX],\n [0, flipX * scaleStep, centerY],\n [0, 0, 1]\n ]);\n }\n\n /**\n * The function scales a matrix by a given factor.\n * @param {number} factor - The factor parameter is a number that represents the scaling factor by which the matrix\n * should be scaled.\n * @returns the result of multiplying a new instance of Matrix2D by the given factor.\n */\n static scale(factor: number) {\n return Matrix2D.multiplyByValue(new Matrix2D(), factor);\n }\n\n /**\n * The function \"rotate\" takes an angle in radians and returns a 2D transformation matrix for rotating objects.\n * @param {number} radians - The \"radians\" parameter is the angle in radians by which you want to rotate an object.\n * @returns The code is returning a new instance of a Matrix2D object.\n */\n static rotate(radians: number) {\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n\n return new Matrix2D([\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1]\n ]);\n }\n\n /**\n * The translate function takes a 2D vector and returns a 2D matrix that represents a translation transformation.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D. It represents a 2D vector with components x\n * and y, and an optional w component.\n * @returns The method is returning a new instance of the Matrix2D class.\n */\n static translate(vector: Vector2D): Matrix2D {\n return new Matrix2D([\n [1, 0, vector.x],\n [0, 1, vector.y],\n [0, 0, vector.w]\n ]);\n }\n\n /**\n * The function \"toVector\" returns a new Vector2D object with the values from the first and second elements of the\n * _matrix array.\n * @returns A new instance of the Vector2D class is being returned. The values of the returned vector are taken from\n * the first column of the matrix.\n */\n toVector(): Vector2D {\n return new Vector2D(this._matrix[0][0], this._matrix[1][0]);\n }\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 { 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 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 this.onMove && this.onMove(this._cur);\n }\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 { ElementCallback } 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 key: string;\n children: Map<string, TrieNode>;\n isEnd: boolean;\n\n constructor(key: string) {\n this.key = key;\n this.isEnd = false;\n this.children = new Map<string, TrieNode>();\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 extends IterableElementBase<string> {\n constructor(words?: string[], caseSensitive = true) {\n super();\n this._root = new TrieNode('');\n this._caseSensitive = caseSensitive;\n this._size = 0;\n if (words) {\n for (const word of words) {\n this.add(word);\n }\n }\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n protected _caseSensitive: boolean;\n\n get caseSensitive(): boolean {\n return this._caseSensitive;\n }\n\n protected _root: TrieNode;\n\n get root() {\n return this._root;\n }\n\n /**\n * Time Complexity: O(M), where M is the length of the word being added.\n * Space Complexity: O(M) - Each character in the word adds a TrieNode.\n */\n\n /**\n * Time Complexity: O(M), where M is the length of the word being added.\n * Space Complexity: O(M) - 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(M), where M is the length of the input word.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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 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(M), where M is the length of the word being deleted.\n * Space Complexity: O(M) - Due to the recursive DFS approach.\n */\n\n /**\n * Time Complexity: O(M), where M is the length of the word being deleted.\n * Space Complexity: O(M) - 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 /**\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(M), where M is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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(M), where M is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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(M), where M is the length of the input prefix.\n */\n\n /**\n * Time Complexity: O(N), where N is the total number of nodes in the trie.\n * Space Complexity: O(M), where M 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(M), where M is the length of the longest common prefix.\n */\n\n /**\n * Time Complexity: O(N), where N is the total number of nodes in the trie.\n * Space Complexity: O(M), where M 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(K * L), where K is the number of words retrieved, and L is the average length of the words.\n * Space Complexity: O(K * L) - The space required for the output array.\n */\n\n /**\n * Time Complexity: O(K * L), where K is the number of words retrieved, and L is the average length of the words.\n * Space Complexity: O(K * 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) startNode = nodeC;\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\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, boolean>, thisArg?: any): Trie {\n const results: Trie = new Trie();\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\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 Trie.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * Trie. It takes three arguments: the current element in the Trie, the index of the current element,\n * and the Trie itself. The callback function should return a new value for the element.\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 `map` function is returning a new Trie object.\n */\n map(callback: ElementCallback<string, string>, thisArg?: any): Trie {\n const newTrie = new Trie();\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 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(M), where M is the length of the input string.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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"],"mappings":"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","names":["src_exports","__export","AVLTree","AVLTreeNode","AbstractEdge","AbstractGraph","AbstractVertex","BST","BSTNode","BSTVariant","BinaryIndexedTree","BinaryTree","BinaryTreeNode","CP","Character","Deque","DirectedEdge","DirectedGraph","DirectedVertex","DoublyLinkedList","DoublyLinkedListNode","FamilyPosition","FibonacciHeap","FibonacciHeapNode","HashMap","HashTable","HashTableNode","Heap","IterableElementBase","IterableEntryBase","IterationType","LinkedHashMap","LinkedListQueue","MapEdge","MapGraph","MapVertex","Matrix2D","MatrixNTI2D","MaxHeap","MaxPriorityQueue","MinHeap","MinPriorityQueue","Navigator","PriorityQueue","Queue","RBTNColor","RedBlackTree","RedBlackTreeNode","SegmentTree","SegmentTreeNode","SinglyLinkedList","SinglyLinkedListNode","SkipList","SkipListNode","Stack","THUNK_SYMBOL","TreeMultimap","TreeMultimapNode","TreeNode","Trie","TrieNode","UndirectedEdge","UndirectedGraph","UndirectedVertex","Vector2D","arrayRemove","calcMinUnitsRequired","getMSB","isThunk","isWeakKey","rangeCheck","throwRangeError","toThunk","trampoline","trampolineAsync","uuidV4","HashTableNode","key","value","__publicField","_HashTable","capacity","hashFn","index","newNode","currentNode","prevNode","bucket","callback","entry","predicate","newTable","initialValue","accumulator","keyString","hash","i","charCode","A","M","char","newCapacity","newBuckets","newIndex","currentNewNode","HashTable","IterableEntryBase","args","__yieldStar","item","predicate","thisArg","index","callbackfn","key","value","initialValue","accumulator","elementValue","IterableElementBase","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","HashMap","_HashMap","IterableEntryBase","elements","options","__publicField","key","hashFn","value","strKey","results","_a","callbackfn","thisArg","resultMap","index","predicate","filteredMap","node","keyType","LinkedHashMap","_LinkedHashMap","objHashFn","el","isNewKey","isWeakKey","hash","entries","entry","rangeCheck","cloned","callback","mappedMap","newValue","prev","next","SinglyLinkedListNode","value","__publicField","SinglyLinkedList","_SinglyLinkedList","IterableElementBase","elements","el","data","singlyLinkedList","item","newNode","current","removedNode","index","i","prevNode","valueOrNode","prev","array","next","callback","existingValueOrNode","newValue","existingValue","existingNode","count","thisArg","filteredList","mappedList","DoublyLinkedListNode","value","__publicField","DoublyLinkedList","_DoublyLinkedList","IterableElementBase","elements","el","_a","data","doublyLinkedList","item","newNode","removedNode","index","current","i","prevNode","nextNode","existingValueOrNode","newValue","existingNode","valOrNode","node","callback","next","array","thisArg","filteredList","mappedList","SkipListNode","key","value","level","__publicField","SkipList","maxLevel","probability","firstNode","current","i","newNode","update","nextNode","lastLess","Stack","_Stack","IterableElementBase","elements","__publicField","el","element","predicate","thisArg","newStack","index","callback","i","Queue","_Queue","IterableElementBase","elements","__publicField","element","first","value","index","predicate","thisArg","newDeque","el","callback","item","LinkedListQueue","SinglyLinkedList","_a","Deque","_Deque","IterableElementBase","elements","bucketSize","__publicField","_size","calcMinUnitsRequired","i","needBucketNum","element","index","pos","rangeCheck","bucketIndex","indexInBucket","num","length","arr","curBucket","curPointer","nextBucket","nextPointer","size","oldElement","bucket","_bucketFirst","_bucketLast","_firstInBucket","_lastInBucket","prev","cur","comparator","newBuckets","callback","predicate","thisArg","newDeque","el","addBucketNum","overallIndex","Heap","_Heap","IterableElementBase","elements","options","__publicField","defaultComparator","a","b","el","_a","element","value","last","index","order","result","_dfs","left","right","clonedHeap","visitedNode","cloned","top","results","i","callback","thisArg","filteredList","current","comparator","mappedHeap","parent","parentItem","halfLength","minItem","FibonacciHeapNode","degree","FibonacciHeap","node","head","flag","z","heapToMerge","thisRoot","otherRoot","thisRootRight","otherRootLeft","y","x","A","d","t","MaxHeap","Heap","elements","options","a","b","MinHeap","Heap","elements","options","a","b","AbstractVertex","key","value","__publicField","AbstractEdge","weight","uuidV4","AbstractGraph","IterableEntryBase","vertexKey","vertexOrKey","keyOrVertex","newVertex","potentialKey","potentialKeyType","vertexMap","removed","v","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","needCutVertexes","needBridges","needSCCs","needCycles","dfnMap","lowMap","root","cutVertexes","bridges","dfn","childCount","childLow","curLow","edgeCurToNeighbor","SCCs","low","cycles","visitedMap","findCyclesDFS","cycleStartIndex","cycle","cycleLow","isInclude2Cycle","currentPath","uniqueCycles","sorted","cycleString","predicate","thisArg","filtered","callback","mapped","DirectedVertex","AbstractVertex","key","value","DirectedEdge","AbstractEdge","src","dest","weight","__publicField","DirectedGraph","AbstractGraph","srcOrKey","destOrKey","edgeMap","srcOutEdges","edge","removed","arrayRemove","destInEdges","edgeOrSrcVertexKey","destVertexKey","vertexOrKey","vertexKey","vertex","v1","v2","v1ToV2","v2ToV1","target","destinations","outgoingEdges","outEdge","child","propertyName","statusMap","entry","sorted","hasCycle","dfs","cur","children","childStatus","outEdges","neighbors","neighbor","srcVertex","destVertex","UndirectedVertex","AbstractVertex","key","value","UndirectedEdge","AbstractEdge","v1","v2","weight","__publicField","UndirectedGraph","AbstractGraph","_a","edgeMap","vertex1","vertex2","e","v1Edges","removed","arrayRemove","v2Edges","edgeOrOneSideVertexKey","otherSideVertexKey","oneSide","otherSide","vertexOrKey","vertexKey","vertex","neighbors","neighbor","neighborEdges","restEdges","edge","edgeSet","end","endVertex","MapVertex","DirectedVertex","key","value","lat","long","__publicField","MapEdge","DirectedEdge","src","dest","weight","MapGraph","DirectedGraph","originCoord","bottomRight","RBTNColor","BSTVariant","CP","IterationType","FamilyPosition","BinaryTreeNode","key","value","__publicField","v","that","BinaryTree","_BinaryTree","IterableEntryBase","elements","options","node","iterationType","extractor","__spreadValues","exemplar","kne","keyOrNodeOrEntry","newNode","queue","Queue","potentialParent","cur","nodes","values","inserted","valuesIterator","valueResult","nodesOrKeysOrEntries","identifier","callback","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","distNode","beginRoot","depth","_getMaxHeight","leftHeight","rightHeight","stack","maxHeight","_a","_b","_c","_getMinHeight","leftMinHeight","rightMinHeight","last","depths","onlyOne","ans","_traverse","_dfs","isReverse","result","trampoline","dfs","min","max","numKey","prev","includeNull","potentialKey","pattern","traverse","level","current","levelSize","i","levelsNodes","_recursive","head","predecessor","x","y","_reverseEdge","pre","next","_printEdge","tail","cloned","predicate","thisArg","newTree","index","opts","root","lines","line","__yieldStar","isShowNull","isShowUndefined","isShowRedBlackNIL","emptyDisplayLayout","width","_buildNodeDisplay","left","right","leftLines","leftWidth","leftMiddle","rightLines","rightWidth","rightMiddle","firstLine","secondLine","mergedLines","leftLine","rightLine","srcNode","destNode","tempNode","oldNode","BSTNode","BinaryTreeNode","key","value","__publicField","v","BST","_BST","BinaryTree","elements","options","variant","__spreadValues","exemplar","node","keyOrNodeOrEntry","newNode","current","keysOrNodesOrEntries","values","isBalanceAdd","iterationType","inserted","valuesIterator","kve","nn","realBTNExemplars","isRealBTNExemplar","sorted","a","aR","bR","_dfs","arr","mid","_iterate","stack","popped","l","r","m","beginRoot","cur","queue","Queue","potentialKey","identifier","callback","onlyOne","ans","_traverse","lesserOrGreater","targetNode","targetKey","n","buildBalanceBST","midNode","_a","_b","balanced","_height","leftHeight","rightHeight","last","depths","left","right","b","extractedA","extractedB","compared","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","elements","options","__spreadValues","exemplar","potentialKey","keyOrNodeOrEntry","inserted","identifier","callback","node","deletedResults","needBalanced","srcNode","destNode","height","tempNode","rightHeight","path","i","A","parentOfA","B","C","oldNode","newNode","RedBlackTreeNode","BSTNode","key","value","color","__publicField","RedBlackTree","_RedBlackTree","BST","elements","options","__spreadValues","exemplar","potentialKey","node","keyOrNodeOrEntry","newNode","y","x","identifier","callback","ans","z","yOriginalColor","beginRoot","iterationType","_a","v","s","u","k","oldNode","TreeMultimapNode","AVLTreeNode","key","value","count","__publicField","TreeMultimap","_TreeMultimap","AVLTree","elements","options","sum","node","__spreadValues","exemplar","potentialKey","keyOrNodeOrEntry","newNode","orgNodeCount","inserted","keysOrNodesOrEntries","iterationType","sorted","n","buildBalanceBST","l","r","m","midNode","stack","popped","identifier","callback","ignoreCount","_a","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","cloned","srcNode","destNode","height","tempNode","oldNode","TreeNode","_TreeNode","key","value","children","__publicField","maxDepth","bfs","node","level","i","len","PriorityQueue","Heap","elements","options","MinPriorityQueue","PriorityQueue","elements","options","a","b","MaxPriorityQueue","PriorityQueue","elements","options","a","b","MatrixNTI2D","options","__publicField","row","col","initialVal","Vector2D","_Vector2D","x","y","w","vector1","vector2","vector","value","roundingFactor","length","max","ySeparation","xSeparation","origin","radian","maxX","maxY","randX","randY","Matrix2D","_Matrix2D","value","__publicField","Vector2D","matrix1","matrix2","result","i","j","k","matrix","vector","width","height","centerX","centerY","flipX","factor","radians","cos","sin","Character","_Character","direction","turning","__publicField","Navigator","matrix","onMove","cur","charDir","VISITED","forward","row","j","i","TrieNode","key","__publicField","Trie","_Trie","IterableElementBase","words","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","newTrie","_dfs","path","childNode","__yieldStar","str"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/data-structures/hash/hash-table.ts","../../src/data-structures/base/iterable-base.ts","../../src/utils/utils.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/types/data-structures/binary-tree/rb-tree.ts","../../src/types/common.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/tree-multimap.ts","../../src/data-structures/tree/tree.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/vector2d.ts","../../src/data-structures/matrix/matrix2d.ts","../../src/data-structures/matrix/navigator.ts","../../src/data-structures/trie/trie.ts"],"sourcesContent":["export * from './data-structures';\nexport * from './utils';\nexport * from './interfaces';\nexport * from './types';\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 */\n\nimport type { HashFunction } from '../../types';\n\nexport class HashTableNode<K = any, V = any> {\n key: K;\n value: V;\n next: HashTableNode<K, V> | undefined;\n\n constructor(key: K, value: V) {\n this.key = key;\n this.value = value;\n this.next = undefined;\n }\n}\n\nexport class HashTable<K = any, V = any> {\n protected static readonly DEFAULT_CAPACITY = 16;\n protected static readonly LOAD_FACTOR = 0.75;\n\n constructor(capacity: number = HashTable.DEFAULT_CAPACITY, hashFn?: HashFunction<K>) {\n this._hashFn = hashFn || this._defaultHashFn;\n this._capacity = Math.max(capacity, HashTable.DEFAULT_CAPACITY);\n this._size = 0;\n this._buckets = new Array<HashTableNode<K, V> | undefined>(this._capacity).fill(undefined);\n }\n\n protected _capacity: number;\n\n get capacity(): number {\n return this._capacity;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n protected _buckets: Array<HashTableNode<K, V> | undefined>;\n\n get buckets(): Array<HashTableNode<K, V> | undefined> {\n return this._buckets;\n }\n\n protected _hashFn: HashFunction<K>;\n\n get hashFn(): HashFunction<K> {\n return this._hashFn;\n }\n\n /**\n * The set function adds a key-value pair to the hash table, handling collisions and resizing if necessary.\n * @param {K} key - The key parameter represents the key of the key-value pair that you want to insert into the hash\n * table. It is of type K, which is a generic type representing the key's data type.\n * @param {V} value - The parameter `value` represents the value that you want to associate with the given key in the hash\n * table.\n * @returns Nothing is being returned. The return type of the `put` method is `void`, which means it does not return any\n * value.\n */\n set(key: K, value: V): void {\n const index = this._hash(key);\n const newNode = new HashTableNode<K, V>(key, value);\n\n if (!this._buckets[index]) {\n this._buckets[index] = newNode;\n } else {\n // Handle collisions, consider using open addressing, etc.\n let currentNode = this._buckets[index]!;\n while (currentNode) {\n if (currentNode.key === key) {\n // If the key already exists, update the value\n currentNode.value = value;\n return;\n }\n if (!currentNode.next) {\n break;\n }\n currentNode = currentNode.next;\n }\n // Add to the end of the linked list\n currentNode.next = newNode;\n }\n this._size++;\n\n // If the load factor is too high, resize the hash table\n if (this._size / this._capacity >= HashTable.LOAD_FACTOR) {\n this._expand();\n }\n }\n\n /**\n * The `get` function retrieves the value associated with a given key from a hash table.\n * @param {K} key - The `key` parameter represents the key of the element that we want to retrieve from the data\n * structure.\n * @returns The method is returning the value associated with the given key if it exists in the hash table. If the key is\n * not found, it returns `undefined`.\n */\n get(key: K): V | undefined {\n const index = this._hash(key);\n let currentNode = this._buckets[index];\n\n while (currentNode) {\n if (currentNode.key === key) {\n return currentNode.value;\n }\n currentNode = currentNode.next;\n }\n return undefined; // Key not found\n }\n\n /**\n * The delete function removes a key-value pair from a hash table.\n * @param {K} key - The `key` parameter represents the key of the key-value pair that needs to be removed from the hash\n * table.\n * @returns Nothing is being returned. The `delete` method has a return type of `void`, which means it does not return\n * any value.\n */\n delete(key: K): void {\n const index = this._hash(key);\n let currentNode = this._buckets[index];\n let prevNode: HashTableNode<K, V> | undefined = undefined;\n\n while (currentNode) {\n if (currentNode.key === key) {\n if (prevNode) {\n prevNode.next = currentNode.next;\n } else {\n this._buckets[index] = currentNode.next;\n }\n this._size--;\n currentNode.next = undefined; // Release memory\n return;\n }\n prevNode = currentNode;\n currentNode = currentNode.next;\n }\n }\n\n * [Symbol.iterator](): Generator<[K, V], void, undefined> {\n for (const bucket of this._buckets) {\n let currentNode = bucket;\n while (currentNode) {\n yield [currentNode.key, currentNode.value];\n currentNode = currentNode.next;\n }\n }\n }\n\n forEach(callback: (entry: [K, V], index: number, table: HashTable<K, V>) => void): void {\n let index = 0;\n for (const entry of this) {\n callback(entry, index, this);\n index++;\n }\n }\n\n filter(predicate: (entry: [K, V], index: number, table: HashTable<K, V>) => boolean): HashTable<K, V> {\n const newTable = new HashTable<K, V>();\n let index = 0;\n for (const [key, value] of this) {\n if (predicate([key, value], index, this)) {\n newTable.set(key, value);\n }\n index++;\n }\n return newTable;\n }\n\n map<T>(callback: (entry: [K, V], index: number, table: HashTable<K, V>) => T): HashTable<K, T> {\n const newTable = new HashTable<K, T>();\n let index = 0;\n for (const [key, value] of this) {\n newTable.set(key, callback([key, value], index, this));\n index++;\n }\n return newTable;\n }\n\n reduce<T>(callback: (accumulator: T, entry: [K, V], index: number, table: HashTable<K, V>) => T, initialValue: T): T {\n let accumulator = initialValue;\n let index = 0;\n for (const entry of this) {\n accumulator = callback(accumulator, entry, index, this);\n index++;\n }\n return accumulator;\n }\n\n /**\n * The function `_defaultHashFn` calculates the hash value of a given key and returns the remainder when divided by the\n * capacity of the data structure.\n * @param {K} key - The `key` parameter is the input value that needs to be hashed. It can be of any type, but in this\n * code snippet, it is checked whether the key is a string or an object. If it is a string, the `_murmurStringHashFn`\n * function is used to\n * @returns the hash value of the key modulo the capacity of the data structure.\n */\n protected _defaultHashFn(key: K): number {\n // Can be replaced with other hash functions as needed\n const hashValue = typeof key === 'string' ? this._murmurStringHashFn(key) : this._objectHash(key);\n return hashValue % this._capacity;\n }\n\n /**\n * The `_multiplicativeStringHashFn` function calculates a hash value for a given string key using the multiplicative\n * string hash function.\n * @param {K} key - The `key` parameter is the input value for which we want to calculate the hash. It can be of any\n * type, as it is generic (`K`). The function converts the `key` to a string using the `String()` function.\n * @returns a number, which is the result of the multiplicative string hash function applied to the input key.\n */\n protected _multiplicativeStringHashFn<K>(key: K): number {\n const keyString = String(key);\n let hash = 0;\n for (let i = 0; i < keyString.length; i++) {\n const charCode = keyString.charCodeAt(i);\n // Some constants for adjusting the hash function\n const A = 0.618033988749895;\n const M = 1 << 30; // 2^30\n hash = (hash * A + charCode) % M;\n }\n return Math.abs(hash); // Take absolute value to ensure non-negative numbers\n }\n\n /**\n * The function `_murmurStringHashFn` calculates a hash value for a given string key using the MurmurHash algorithm.\n * @param {K} key - The `key` parameter is the input value for which you want to calculate the hash. It can be of any\n * type, but it will be converted to a string using the `String()` function before calculating the hash.\n * @returns a number, which is the hash value calculated for the given key.\n */\n protected _murmurStringHashFn<K>(key: K): number {\n const keyString = String(key);\n const seed = 0;\n let hash = seed;\n\n for (let i = 0; i < keyString.length; i++) {\n const char = keyString.charCodeAt(i);\n hash = (hash ^ char) * 0x5bd1e995;\n hash = (hash ^ (hash >>> 15)) * 0x27d4eb2d;\n hash = hash ^ (hash >>> 15);\n }\n\n return Math.abs(hash);\n }\n\n /**\n * The _hash function takes a key and returns a number.\n * @param {K} key - The parameter \"key\" is of type K, which represents the type of the key that will be hashed.\n * @returns The hash function is returning a number.\n */\n protected _hash(key: K): number {\n return this.hashFn(key);\n }\n\n /**\n * The function calculates a hash value for a given string using the djb2 algorithm.\n * @param {string} key - The `key` parameter in the `stringHash` function is a string value that represents the input for\n * which we want to calculate the hash value.\n * @returns a number, which is the hash value of the input string.\n */\n protected _stringHash(key: string): number {\n let hash = 0;\n for (let i = 0; i < key.length; i++) {\n hash = (hash * 31 + key.charCodeAt(i)) & 0xffffffff;\n }\n return hash;\n }\n\n /**\n * The function `_objectHash` takes a key and returns a hash value, using a custom hash function for objects.\n * @param {K} key - The parameter \"key\" is of type \"K\", which means it can be any type. It could be a string, number,\n * boolean, object, or any other type of value. The purpose of the objectHash function is to generate a hash value for\n * the key, which can be used for\n * @returns a number, which is the hash value of the key.\n */\n protected _objectHash(key: K): number {\n // If the key is an object, you can write a custom hash function\n // For example, convert the object's properties to a string and use string hashing\n // This is just an example; you should write a specific object hash function as needed\n return this._stringHash(JSON.stringify(key));\n }\n\n /**\n * The `expand` function increases the capacity of a hash table by creating a new array of buckets with double the\n * capacity and rehashing all the existing key-value pairs into the new buckets.\n */\n protected _expand(): void {\n const newCapacity = this._capacity * 2;\n const newBuckets = new Array<HashTableNode<K, V> | undefined>(newCapacity).fill(undefined);\n\n for (const bucket of this._buckets) {\n let currentNode = bucket;\n while (currentNode) {\n const newIndex = this._hash(currentNode.key);\n const newNode = new HashTableNode<K, V>(currentNode.key, currentNode.value);\n\n if (!newBuckets[newIndex]) {\n newBuckets[newIndex] = newNode;\n } else {\n let currentNewNode = newBuckets[newIndex]!;\n while (currentNewNode.next) {\n currentNewNode = currentNewNode.next;\n }\n currentNewNode.next = newNode;\n }\n currentNode = currentNode.next;\n }\n }\n\n this._buckets = newBuckets;\n this._capacity = newCapacity;\n }\n}\n","import { ElementCallback, EntryCallback, ReduceElementCallback, ReduceEntryCallback } from \"../../types\";\n\nexport abstract class IterableEntryBase<K = any, V = any> {\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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 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 /**\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 /**\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 /**\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 /**\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 /**\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 /**\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 /**\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 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(n)\n */\n print(): void {\n console.log([...this])\n }\n\n protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;\n}\n\nexport abstract class IterableElementBase<V> {\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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<V> {\n yield* this._getIterator(...args);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(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<V> {\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 /**\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<V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (!predicate.call(thisArg, item as V, 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 /**\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<V, boolean>, thisArg?: any): boolean {\n let index = 0;\n for (const item of this) {\n if (predicate.call(thisArg, item as V, 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 /**\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<V, void>, thisArg?: any): void {\n let index = 0;\n for (const item of this) {\n callbackfn.call(thisArg, item as V, index++, this)\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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<V, U>, initialValue: U): U {\n let accumulator = initialValue;\n let index = 0;\n for (const item of this) {\n accumulator = callbackfn(accumulator, item as V, index++, this)\n }\n return accumulator;\n }\n\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n */\n print(): void {\n console.log([...this])\n }\n\n protected abstract _getIterator(...args: any[]): IterableIterator<V>;\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 { Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';\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\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\nexport const isThunk = (fnOrValue: any) => {\n return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL;\n};\n\nexport const toThunk = (fn: ToThunkFn): Thunk => {\n const thunk = () => fn();\n thunk.__THUNK__ = THUNK_SYMBOL;\n return thunk;\n};\n\nexport const trampoline = (fn: TrlFn) => {\n const cont = (...args: [...Parameters<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\nexport const trampolineAsync = (fn: TrlAsyncFn) => {\n const cont = (...args: [...Parameters<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\nexport const getMSB = (value: number): number => {\n if (value <= 0) {\n return 0;\n }\n return 1 << (31 - Math.clz32(value));\n};\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\nexport const throwRangeError = (message = 'The value is off-limits.'): void => {\n throw new RangeError(message);\n};\n\nexport const isWeakKey = (input: unknown): input is object => {\n const inputType = typeof input;\n return (inputType === 'object' && input !== null) || inputType === 'function';\n};\n\nexport const calcMinUnitsRequired = (totalQuantity: number, unitSize: number) => Math.floor((totalQuantity + unitSize - 1) / unitSize)\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 { EntryCallback, HashMapLinkedNode, HashMapOptions, HashMapStoreItem } 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 maps to a value.\n * 2. Fast Lookup: It's used when you need to quickly find, insert, or delete elements based on a key.\n * 3. Unique Keys: Keys are unique. If you try to insert another entry with the same key, the old entry will be replaced by the new one.\n * 4. Unordered Collection: HashMap does not guarantee the order of elements, and the order may change over time.\n */\nexport class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {\n protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};\n protected _objMap: Map<object, V> = new Map();\n\n /**\n * The constructor function initializes a new instance of a class with optional elements and options.\n * @param elements - The `elements` parameter is an iterable containing key-value pairs `[K, V]`. It\n * is optional and defaults to an empty array `[]`. This parameter is used to initialize the map with\n * key-value pairs.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the constructor. In this case, it has one property:\n */\n constructor(elements: Iterable<[K, V]> = [], options?: {\n hashFn: (key: K) => string\n }) {\n super();\n if (options) {\n const { hashFn } = options;\n if (hashFn) {\n this._hashFn = hashFn;\n }\n }\n if (elements) {\n this.setMany(elements);\n }\n }\n\n protected _size = 0;\n\n get size(): number {\n return this._size;\n }\n\n isEmpty(): boolean {\n return this.size === 0;\n }\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\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\" sets multiple key-value pairs in a map.\n * @param elements - The `elements` parameter is an iterable containing key-value pairs. Each\n * key-value pair is represented as an array with two elements: the key and the value.\n */\n setMany(elements: Iterable<[K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const [key, value] of elements) results.push(this.set(key, value));\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 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 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\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<U>(callbackfn: EntryCallback<K, V, U>, thisArg?: any): HashMap<K, U> {\n const resultMap = new HashMap<K, U>();\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\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 print(): void {\n console.log([...this.entries()]);\n }\n\n put(key: K, value: V): boolean {\n return this.set(key, value);\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 protected _hashFn: (key: K) => string = (key: K) => String(key);\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 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 elements are inserted. Therefore, when you traverse it, elements 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 elements 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> extends IterableEntryBase<K, V> {\n\n protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};\n protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();\n protected _head: HashMapLinkedNode<K, V | undefined>;\n protected _tail: HashMapLinkedNode<K, V | undefined>;\n protected readonly _sentinel: HashMapLinkedNode<K, V | undefined>;\n protected _hashFn: (key: K) => string;\n protected _objHashFn: (key: K) => object;\n\n\n constructor(elements?: Iterable<[K, V]>, options: HashMapOptions<K> = {\n\n hashFn: (key: K) => String(key),\n objHashFn: (key: K) => (<object>key)\n }) {\n super();\n this._sentinel = <HashMapLinkedNode<K, V>>{};\n this._sentinel.prev = this._sentinel.next = this._head = this._tail = this._sentinel;\n\n const { hashFn, objHashFn } = options;\n this._hashFn = hashFn;\n this._objHashFn = objHashFn;\n if (elements) {\n for (const el of elements) {\n this.set(el[0], el[1]);\n }\n }\n }\n\n protected _size = 0;\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 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 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 setMany(entries: Iterable<[K, V]>): boolean[] {\n const results: boolean[] = [];\n for (const entry of entries) {\n const [key, value] = entry;\n results.push(this.set(key, value));\n }\n return results;\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 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), where n is the index.\n * Space Complexity: O(1)\n *\n * The function `getAt` 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 `getAt(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 getAt(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), where n is the index.\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 * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `clear` function clears all the elements 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 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\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\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<NV>(callback: EntryCallback<K, V, NV>, thisArg?: any): LinkedHashMap<K, NV> {\n const mappedMap = new LinkedHashMap<K, NV>();\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 put(key: K, value: V): boolean {\n return this.set(key, value);\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the LinkedHashMap.\n * Space Complexity: O(1)\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback } from \"../../types\";\nimport { IterableElementBase } from \"../base\";\n\nexport class SinglyLinkedListNode<E = any> {\n value: E;\n next: SinglyLinkedListNode<E> | undefined;\n\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\nexport class SinglyLinkedList<E = any> extends IterableElementBase<E> {\n /**\n * The constructor initializes the linked list with an empty head, tail, and length.\n */\n constructor(elements?: Iterable<E>) {\n super();\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n if (elements) {\n for (const el of elements) this.push(el);\n }\n }\n\n protected _head: SinglyLinkedListNode<E> | undefined;\n\n get head(): SinglyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: SinglyLinkedListNode<E> | undefined;\n\n get tail(): SinglyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the input array, as it performs a loop to push each element into the linked list.\n * Space Complexity: O(n) - Linear space, as it creates a new node for each element in the array.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the input array, as it performs a loop to push each element into the linked list.\n * Space Complexity: O(n) - Linear space, as it creates a new node for each element in the array.\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) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n *\n * The `push` function adds a new node with the given value to the end of a singly linked list.\n * @param {E} value - The \"value\" parameter represents the value that you want to add to the linked list. It can be of\n * any type (E) as specified in the generic type declaration of the class or function.\n */\n push(value: E): boolean {\n const newNode = new SinglyLinkedListNode(value);\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(1) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves basic pointer adjustments.\n * Space Complexity: O(1) - Constant space, as it only creates a new node.\n *\n * The `push` function adds a new node with the given value to the end of a singly linked list.\n * @param {E} value - The \"value\" parameter represents the value that you want to add to the linked list. It can be of\n * any type (E) as specified in the generic type declaration of the class or function.\n */\n addLast(value: E): boolean {\n return this.push(value);\n }\n\n /**\n * Time Complexity: O(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n *\n * The `pop()` function removes and returns the value of the last element in a linked list, updating the head and tail\n * pointers accordingly.\n * @returns The method `pop()` returns the value of the node that is being removed from the end of the linked list. If\n * the linked list is empty, it returns `undefined`.\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(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time in the worst case, as it may need to traverse the list to find the last element.\n * Space Complexity: O(1) - Constant space.\n *\n * The `pollLast()` function removes and returns the value of the last element in a linked list, updating the head and tail\n * pointers accordingly.\n * @returns The method `pop()` returns the value of the node that is being removed from the end of the linked list. If\n * the linked list is empty, it returns `undefined`.\n */\n pollLast(): E | undefined {\n return this.pop();\n }\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The `shift()` function removes and returns the value of the first node in a linked list.\n * @returns The value of the node that is being removed from the beginning of the linked list.\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) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The `pollFirst()` function removes and returns the value of the first node in a linked list.\n * @returns The value of the node that is being removed from the beginning of the linked list.\n */\n pollFirst(): E | undefined {\n return this.shift();\n }\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The unshift function adds a new node with the given value to the beginning of a singly linked list.\n * @param {E} value - The parameter \"value\" represents the value of the new node that will be added to the beginning of the\n * linked list.\n */\n unshift(value: E): boolean {\n const newNode = new SinglyLinkedListNode(value);\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(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(1) - Constant time, as it involves adjusting pointers at the head.\n * Space Complexity: O(1) - Constant space.\n *\n * The addFirst function adds a new node with the given value to the beginning of a singly linked list.\n * @param {E} value - The parameter \"value\" represents the value of the new node that will be added to the beginning of the\n * linked list.\n */\n addFirst(value: E): boolean {\n return this.unshift(value);\n }\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n *\n * The function `getAt` 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 `getAt(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 getAt(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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) 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) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the index, as it may need to traverse the list to find the desired node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to traverse the entire list to convert it to an array.\n * Space Complexity: O(n) - Linear space, as it creates an array with the same length as the list.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to traverse the entire list to convert it to an array.\n * Space Complexity: O(n) - Linear space, as it creates an array with the same length as the list.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n *\n * The `find` function iterates through a linked list and returns the first element that satisfies a given condition.\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 particular value in the linked list satisfies a certain condition.\n * @returns The method `find` returns the first element in the linked list that satisfies the condition specified by\n * the callback function. If no element satisfies the condition, it returns `undefined`.\n */\n find(callback: (value: E) => boolean): E | undefined {\n let current = this.head;\n while (current) {\n if (callback(current.value)) {\n return current.value;\n }\n current = current.next;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(n) - Linear time, where n is the length of the list, as it needs to reverse the pointers of each node.\n * Space Complexity: O(1) - Constant space.\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\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, boolean>, thisArg?: any): SinglyLinkedList<E> {\n const filteredList = new SinglyLinkedList<E>();\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 /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\n */\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new SinglyLinkedList by applying a callback function to each element\n * of the original list.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the linked list. It takes three arguments:\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 `map` function is returning a new `SinglyLinkedList` object that contains the results\n * of applying the provided `callback` function to each element in the original list.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): SinglyLinkedList<T> {\n const mappedList = new SinglyLinkedList<T>();\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 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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback } from '../../types';\nimport { IterableElementBase } from '../base';\n\nexport class DoublyLinkedListNode<E = any> {\n value: E;\n next: DoublyLinkedListNode<E> | undefined;\n prev: DoublyLinkedListNode<E> | undefined;\n\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\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> extends IterableElementBase<E> {\n /**\n * The constructor initializes the linked list with an empty head, tail, and size.\n */\n constructor(elements?: Iterable<E>) {\n super();\n this._head = undefined;\n this._tail = undefined;\n this._size = 0;\n if (elements) {\n for (const el of elements) {\n this.push(el);\n }\n }\n }\n\n protected _head: DoublyLinkedListNode<E> | undefined;\n\n get head(): DoublyLinkedListNode<E> | undefined {\n return this._head;\n }\n\n protected _tail: DoublyLinkedListNode<E> | undefined;\n\n get tail(): DoublyLinkedListNode<E> | undefined {\n return this._tail;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n /**\n * Time Complexity: O(n), where n is the size of the input array.\n * Space Complexity: O(n)\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 * 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\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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(1)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n), where n is the size of the input array.\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 const doublyLinkedList = new DoublyLinkedList<E>();\n for (const item of data) {\n doublyLinkedList.push(item);\n }\n return doublyLinkedList;\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 push function adds a new node with the given value to the end of the doubly linked list.\n * @param {E} value - The value to be added to the linked list.\n */\n push(value: E): boolean {\n const newNode = new DoublyLinkedListNode(value);\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pop()` function removes and returns the value of the last node in a doubly linked list.\n * @returns The method is returning the value of the removed node (removedNode.value) if the list is not empty. If the\n * list is empty, it returns undefined.\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 node in a doubly linked list.\n * @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked\n * list.\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The unshift function adds a new node with the given value to the beginning of a doubly linked list.\n * @param {E} value - The `value` parameter represents the value of the new node that will be added to the beginning of the\n * doubly linked list.\n */\n unshift(value: E): boolean {\n const newNode = new DoublyLinkedListNode(value);\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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * The `getAt` 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 getAt(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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * 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), where n is the number of elements in the linked list.\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(n), where n is the number of elements in the linked list.\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n */\n\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(n), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\n */\n\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), where n is the number of elements in the linked list.\n * Space Complexity: O(1)\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 * The `find` function iterates through a linked list and returns the first element that satisfies a given condition.\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 particular value in the linked list satisfies a certain condition.\n * @returns The method `find` returns the first element in the linked list that satisfies the condition specified by\n * the callback function. If no element satisfies the condition, it returns `undefined`.\n */\n find(callback: (value: E) => boolean): E | undefined {\n let current = this.head;\n while (current) {\n if (callback(current.value)) {\n return current.value;\n }\n current = current.next;\n }\n return 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\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\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 * 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), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\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 * 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\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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), where n is the number of elements in the linked list.\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the linked list.\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(1)\n * Space Complexity: O(1)\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, boolean>, thisArg?: any): DoublyLinkedList<E> {\n const filteredList = new DoublyLinkedList<E>();\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(1)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new DoublyLinkedList by applying a callback function to each element\n * in the original list.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * DoublyLinkedList. It takes three arguments: the current element, the index of the current element,\n * and the DoublyLinkedList itself. The callback function should return a value that will be added to\n * the new DoublyLinkedList that\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 `map` function is returning a new `DoublyLinkedList` object that contains the results\n * of applying the provided `callback` function to each element in the original `DoublyLinkedList`\n * object.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): DoublyLinkedList<T> {\n const mappedList = new DoublyLinkedList<T>();\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 * 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 addLast function adds a new node with the given value to the end of the doubly linked list.\n * @param {E} value - The value to be added to the linked list.\n */\n addLast(value: E): boolean {\n return this.push(value);\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 `pollLast()` function removes and returns the value of the last node in a doubly linked list.\n * @returns The method is returning the value of the removed node (removedNode.value) if the list is not empty. If the\n * list is empty, it returns undefined.\n */\n pollLast(): E | undefined {\n return this.pop();\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The `pollFirst()` function removes and returns the value of the first node in a doubly linked list.\n * @returns The method `shift()` returns the value of the node that is removed from the beginning of the doubly linked\n * list.\n */\n pollFirst(): E | undefined {\n return this.shift();\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The addFirst function adds a new node with the given value to the beginning of a doubly linked list.\n * @param {E} value - The `value` parameter represents the value of the new node that will be added to the beginning of the\n * doubly linked list.\n */\n addFirst(value: E): void {\n this.unshift(value);\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\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 initializes a SkipList with a specified maximum level and probability.\n * @param [maxLevel=16] - The `maxLevel` parameter represents the maximum level that a skip list can have. It determines\n * the maximum number of levels that can be created in the skip list.\n * @param [probability=0.5] - The probability parameter represents the probability of a node being promoted to a higher\n * level in the skip list. It is used to determine the height of each node in the skip list.\n */\n constructor(maxLevel = 16, probability = 0.5) {\n this._head = new SkipListNode<K, V>(undefined as any, undefined as any, maxLevel);\n this._level = 0;\n this._maxLevel = maxLevel;\n this._probability = probability;\n }\n\n protected _head: SkipListNode<K, V>;\n\n get head(): SkipListNode<K, V> {\n return this._head;\n }\n\n protected _level: number;\n\n get level(): number {\n return this._level;\n }\n\n protected _maxLevel: number;\n\n get maxLevel(): number {\n return this._maxLevel;\n }\n\n protected _probability: number;\n\n get probability(): number {\n return this._probability;\n }\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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(1) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n has(key: K): boolean {\n return this.get(key) !== undefined;\n }\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\n */\n\n /**\n * Time Complexity: O(log n) - where n is the number of elements in the SkipList, as it traverses the levels of the SkipList.\n * Space Complexity: O(1) - constant space, as it uses a fixed amount of space regardless of the size of the SkipList.\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) - where maxLevel is the maximum level of the SkipList, as it may iterate up to maxLevel times in the worst case.\n * Space Complexity: O(1) - constant space.\n */\n\n /**\n * Time Complexity: O(maxLevel) - where maxLevel is the maximum level of the SkipList, as it may iterate up to maxLevel times in the worst case.\n * Space Complexity: O(1) - constant space.\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\nimport type { ElementCallback } 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> extends IterableElementBase<E> {\n /**\n * The constructor initializes an array of elements, which can be provided as an optional parameter.\n * @param {E[]} [elements] - The `elements` parameter is an optional parameter of type `E[]`, which represents an array\n * of elements of type `E`. It is used to initialize the `_elements` property of the class. If the `elements` parameter\n * is provided and is an array, it is assigned to the `_elements\n */\n constructor(elements?: Iterable<E>) {\n super();\n this._elements = [];\n if (elements) {\n for (const el of elements) {\n this.push(el);\n }\n }\n }\n\n protected _elements: E[];\n\n get elements(): E[] {\n return this._elements;\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the input array. Similar to the constructor, it requires iterating through each element.\n * Space Complexity: O(n), as it creates a new stack with the elements from the input array.\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), where n is the number of elements in the input array. Similar to the constructor, it requires iterating through each element.\n * Space Complexity: O(n), as it creates a new stack with the elements from the input array.\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), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\n */\n\n /**\n * Time Complexity: O(1), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\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), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\n */\n\n /**\n * Time Complexity: O(1), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\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), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\n */\n\n /**\n * Time Complexity: O(1), as it only involves accessing the last element of the array.\n * Space Complexity: O(1), as it does not use any additional space.\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 * 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 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 * The clear function clears the elements array.\n */\n clear(): void {\n this._elements = [];\n }\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the stack, as it creates a new stack and copies all elements into it.\n * Space Complexity: O(n), as it creates a new stack.\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the stack, as it creates a new stack and copies all elements into it.\n * Space Complexity: O(n), as it creates a new stack.\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> {\n return new Stack(this.elements.slice());\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 `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, boolean>, thisArg?: any): Stack<E> {\n const newStack = new Stack<E>();\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\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\n * the stack. It takes three arguments:\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 `map` method is returning a new `Stack` object.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): Stack<T> {\n const newStack = new Stack<T>();\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 * 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 Tyler Zeng <zrwusa@gmail.com>\n * @class\n */\nimport type { ElementCallback } 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 nodes that are to be visited.\n * 7. Real-time Queuing: Like queuing systems in banks or supermarkets.\n */\nexport class Queue<E = any> extends IterableElementBase<E> {\n /**\n * The constructor initializes an instance of a class with an optional array of elements and sets the offset to 0.\n * @param {E[]} [elements] - The `elements` parameter is an optional array of elements of type `E`. If provided, it\n * will be used to initialize the `_nodes` property of the class. If not provided, the `_nodes` property will be\n * initialized as an empty array.\n */\n constructor(elements?: E[]) {\n super();\n this._nodes = elements || [];\n this._offset = 0;\n }\n\n protected _nodes: E[];\n\n get nodes(): E[] {\n return this._nodes;\n }\n\n protected _offset: number;\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.nodes.length - this.offset;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The `first` function returns the first element of the array `_nodes` if it exists, otherwise it returns `undefined`.\n * @returns The `get first()` method returns the first element of the data structure, represented by the `_nodes` 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.nodes[this.offset] : undefined;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it adds an element to the end of the array.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\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 `_nodes` 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.nodes[this.nodes.length - 1] : undefined;\n }\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. In the worst case, it may need to shift all elements to update the offset.\n * Space Complexity: O(1) - no additional space is used.\n */\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 * @static\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) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it adds an element to the end of the array.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The push function adds an element to the end of the queue and returns the updated queue.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 The `add` method is returning a `Queue<E>` object.\n */\n push(element: E): boolean {\n this.nodes.push(element);\n return true;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. In the worst case, it may need to shift all elements to update the offset.\n * Space Complexity: O(1) - no additional space is used.\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 * 2 < this.nodes.length) return first;\n\n // only delete dequeued elements when reaching half size\n // to decrease latency of shifting elements.\n this._nodes = this.nodes.slice(this.offset);\n this._offset = 0;\n return first;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The `peek` function returns the first element of the array `_nodes` if it exists, otherwise it returns `undefined`.\n * @returns The `peek()` method returns the first element of the data structure, represented by the `_nodes` array at\n * the `_offset` index. If the data structure is empty (size is 0), it returns `undefined`.\n */\n peek(): E | undefined {\n return this.first;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The `peekLast` function returns the last element in an array-like data structure, or undefined if the structure is empty.\n * @returns The method `peekLast()` returns the last element of the `_nodes` array if the array is not empty. If the\n * array is empty, it returns `undefined`.\n */\n peekLast(): E | undefined {\n return this.last;\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the current offset.\n * Space Complexity: O(1) - no additional space is used.\n *\n * The enqueue function adds a value to the end of a queue.\n * @param {E} value - The value parameter represents the value that you want to add to the queue.\n */\n enqueue(value: E): boolean {\n return this.push(value);\n }\n\n /**\n * Time Complexity: O(n) - same as shift().\n * Space Complexity: O(1) - same as shift().\n */\n\n /**\n * Time Complexity: O(n) - same as shift().\n * Space Complexity: O(1) - same as shift().\n *\n * The `dequeue` function removes and returns the first element from a queue, or returns undefined if the queue is empty.\n * @returns The method is returning a value of type E or undefined.\n */\n dequeue(): E | undefined {\n return this.shift();\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\n *\n * @param index\n */\n getAt(index: number): E | undefined {\n return this.nodes[index];\n }\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it retrieves the value at the specified index.\n * Space Complexity: O(1) - no additional space is used.\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) - constant time as it returns a shallow copy of the internal array.\n * Space Complexity: O(n) - where n is the number of elements in the queue.\n */\n\n /**\n * Time Complexity: O(1) - constant time as it returns a shallow copy of the internal array.\n * Space Complexity: O(n) - where n is the number of elements in the queue.\n *\n * The toArray() function returns an array of elements from the current offset to the end of the _nodes array.\n * @returns An array of type E is being returned.\n */\n toArray(): E[] {\n return this.nodes.slice(this.offset);\n }\n\n /**\n * The clear function resets the nodes array and offset to their initial values.\n */\n clear(): void {\n this._nodes = [];\n this._offset = 0;\n }\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. It creates a shallow copy of the internal array.\n * Space Complexity: O(n) - the space required is proportional to the number of elements in the queue.\n */\n\n /**\n * Time Complexity: O(n) - where n is the number of elements in the queue. It creates a shallow copy of the internal array.\n * Space Complexity: O(n) - the space required is proportional to the number of elements in the queue.\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> {\n return new Queue(this.nodes.slice(this.offset));\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 `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, boolean>, thisArg?: any): Queue<E> {\n const newDeque = new Queue<E>([]);\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 /**\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 queue,\n * returning a new queue with the results.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * queue. It takes three arguments: the current element, the index of the current element, and the\n * queue itself. The callback function should return a new value that will be added to the new queue.\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 `map` function is returning a new `Queue` object with the transformed elements.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): Queue<T> {\n const newDeque = new Queue<T>([]);\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\n protected* _getIterator(): IterableIterator<E> {\n for (const item of this.nodes) {\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> extends SinglyLinkedList<E> {\n /**\n * The `get first` function returns the value of the head node in a linked list, or `undefined` if the list is empty.\n * @returns The `get first()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.\n */\n get first(): E | undefined {\n return this.head?.value;\n }\n\n /**\n * The enqueue function adds a value to the end of an array.\n * @param {E} value - The value parameter represents the value that you want to add to the queue.\n */\n enqueue(value: E): boolean {\n return this.push(value);\n }\n\n /**\n * The `dequeue` function removes and returns the first element from a queue, or returns undefined if the queue is empty.\n * @returns The method is returning the element at the front of the queue, or undefined if the queue is empty.\n */\n dequeue(): E | undefined {\n return this.shift();\n }\n\n /**\n * The `peek` function returns the value of the head node in a linked list, or `undefined` if the list is empty.\n * @returns The `peek()` method is returning the value of the `head` node if it exists, otherwise it returns `undefined`.\n */\n peek(): E | undefined {\n return this.first;\n }\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 { 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> extends IterableElementBase<E> {\n protected _bucketFirst = 0;\n protected _firstInBucket = 0;\n protected _bucketLast = 0;\n protected _lastInBucket = 0;\n protected _bucketCount = 0;\n protected readonly _bucketSize: number;\n\n /**\n * The constructor initializes a data structure with a specified bucket size and populates it with\n * elements from an iterable.\n * @param elements - The `elements` parameter is an iterable object (such as an array or a Set) that\n * contains the initial elements to be stored in the data structure. It can also be an object with a\n * `length` property or a `size` property, which represents the number of elements in the iterable.\n * @param bucketSize - The `bucketSize` parameter is the maximum number of elements that can be\n * stored in each bucket. It determines the size of each bucket in the data structure.\n */\n constructor(elements: IterableWithSizeOrLength<E> = [], bucketSize = (1 << 12)) {\n super();\n let _size: number;\n if ('length' in elements) {\n if (elements.length instanceof Function) _size = elements.length(); else _size = elements.length;\n } else {\n if (elements.size instanceof Function) _size = elements.size(); else _size = elements.size;\n }\n\n this._bucketSize = bucketSize;\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 element of elements) {\n this.push(element);\n }\n }\n\n protected _buckets: E[][] = [];\n\n get buckets() {\n return this._buckets;\n }\n\n protected _size = 0;\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 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\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 (\n this._bucketLast === this._bucketFirst &&\n this._lastInBucket === this._firstInBucket\n ) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketLast][this._lastInBucket] = element;\n return true;\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 `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\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 (\n this._bucketFirst === this._bucketLast &&\n this._firstInBucket === this._lastInBucket\n ) this._reallocate();\n }\n this._size += 1;\n this._buckets[this._bucketFirst][this._firstInBucket] = element;\n return true;\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 `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) - Removes the last element.\n * Space Complexity: O(1) - Operates in-place.\n */\n\n isEmpty(): boolean {\n return this.size === 0;\n }\n\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.getAt(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.getAt(index);\n index--;\n }\n }\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 `getAt` 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 getAt(pos: number): E {\n rangeCheck(pos, 0, this.size - 1);\n const {\n bucketIndex,\n indexInBucket\n } = this._getBucketAndPosition(pos);\n return this._buckets[bucketIndex][indexInBucket]!;\n }\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 `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 {\n bucketIndex,\n indexInBucket\n } = 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\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.getAt(i));\n }\n this.cut(pos - 1);\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\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 * @returns The method is returning the updated size of the data structure.\n */\n cut(pos: number): number {\n if (pos < 0) {\n this.clear();\n return 0;\n }\n const {\n bucketIndex,\n indexInBucket\n } = this._getBucketAndPosition(pos);\n this._bucketLast = bucketIndex;\n this._lastInBucket = indexInBucket;\n this._size = pos + 1;\n return this.size;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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 {\n bucketIndex: curBucket,\n indexInBucket: curPointer\n } = this._getBucketAndPosition(pos);\n for (let i = pos; i < length; ++i) {\n const {\n bucketIndex: nextBucket,\n indexInBucket: nextPointer\n } = 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\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.getAt(i);\n if (oldElement !== element) {\n this.setAt(index, oldElement!);\n index += 1;\n }\n i += 1;\n }\n this.cut(index - 1);\n return true;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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\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.getAt(0);\n for (let i = 1; i < this.size; ++i) {\n const cur = this.getAt(i);\n if (cur !== prev) {\n prev = cur;\n this.setAt(index++, cur);\n }\n }\n this.cut(index - 1);\n return this;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\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.getAt(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\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\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The `find` function iterates over the elements in a deque and returns the first element for which\n * the callback function returns true, or undefined if no such element is found.\n * @param callback - A function that takes three parameters: element, index, and deque. It should\n * return a boolean value indicating whether the element satisfies a certain condition.\n * @returns The method `find` returns the first element in the deque that satisfies the condition\n * specified by the callback function. If no element satisfies the condition, it returns `undefined`.\n */\n find(callback: (element: E, index: number, deque: Deque<E>) => boolean): E | undefined {\n for (let i = 0; i < this.size; ++i) {\n const element = this.getAt(i);\n if (callback(element, i, this)) {\n return element;\n }\n }\n return;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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.getAt(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\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 /**\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, boolean>, thisArg?: any): Deque<E> {\n const newDeque = new Deque<E>([], this._bucketSize);\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 /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new Deque by applying a callback function to each element of the\n * original Deque.\n * @param callback - The `callback` parameter is a function that will be called for each element in\n * the deque. It takes three arguments:\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 a new Deque object with the mapped values.\n */\n map<T>(callback: ElementCallback<E, T>, thisArg?: any): Deque<T> {\n const newDeque = new Deque<T>([], this._bucketSize);\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: Amortized O(1) - Similar to push, resizing leads to O(n).\n * Space Complexity: O(n) - Due to potential resizing.\n */\n\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(n) - In worst case, resizing doubles the array size.\n *\n * The addLast function adds an element to the end of an array.\n * @param {E} element - The element parameter represents the element that you want to add to the end of the\n * data structure.\n */\n addLast(element: E): boolean {\n return this.push(element);\n }\n\n /**\n * Time Complexity: O(1) - Removes the first element.\n * Space Complexity: O(1) - In-place operation.\n */\n\n /**\n * Time Complexity: O(1) - Removes the last element.\n * Space Complexity: O(1) - Operates in-place.\n *\n * The function \"pollLast\" removes and returns the last element of an array.\n * @returns The last element of the array is being returned.\n */\n pollLast(): E | undefined {\n return this.pop();\n }\n\n /**\n * Time Complexity: O(1).\n * Space Complexity: O(n) - Due to potential resizing.\n *\n * The \"addFirst\" function adds an element to the beginning of an array.\n * @param {E} element - The parameter \"element\" represents the element that you want to add to the\n * beginning of the data structure.\n */\n addFirst(element: E): boolean {\n return this.unshift(element);\n }\n\n /**\n * Time Complexity: O(1) - Removes the first element.\n * Space Complexity: O(1) - In-place operation.\n *\n * The function \"pollFirst\" removes and returns the first element of an array.\n * @returns The method `pollFirst()` is returning the first element of the array after removing it\n * from the beginning. If the array is empty, it will return `undefined`.\n */\n pollFirst(): E | undefined {\n return this.shift();\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.getAt(i);\n }\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 `_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\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 * 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 Prim's minimum spanning tree algorithm, which use heaps to improve performance.\n */\nexport class Heap<E = any> extends IterableElementBase<E> {\n options: HeapOptions<E>;\n\n constructor(elements?: Iterable<E>, options?: HeapOptions<E>) {\n super();\n const defaultComparator = (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return a - b;\n }\n }\n if (options) {\n this.options = options\n } else {\n this.options = {\n comparator: defaultComparator\n }\n }\n\n if (elements) {\n for (const el of elements) {\n this.add(el);\n }\n // this.fix();\n }\n }\n\n protected _elements: E[] = [];\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>(elements: Iterable<E>, options: { comparator: Comparator<E> }): Heap<E> {\n return new Heap<E>(elements, options);\n }\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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 * 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), where n is the number of elements in the elements array.\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the elements array.\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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the heap.\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 has(element: E): boolean {\n return this.elements.includes(element);\n }\n\n /**\n * Time Complexity: O(n). The worst-case O(n), where n is the number of elements in the heap. This is because, in the worst case, the element to be deleted is located at the end of the heap (not the root), and after deletion, we may need to reorganize the elements by performing a sinkDown operation.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n). The worst-case O(n), where n is the number of elements in the heap. This is because, in the worst case, the element to be deleted is located at the end of the heap (not the root), and after deletion, we may need to reorganize the elements by performing a sinkDown operation.\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), where n is the number of elements in the heap.\n * Space Complexity: O(h), where h is the height of the heap.\n */\n\n /**\n * Time Complexity: O(n), where n is the number of elements in the heap.\n * Space Complexity: O(h), where h is the height of the heap.\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, 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\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\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> {\n const clonedHeap = new Heap<E>([], this.options);\n clonedHeap._elements = [...this.elements];\n return clonedHeap;\n }\n\n /**\n * Time Complexity: O(n log n)\n * Space Complexity: O(n)\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 = this.clone();\n while (cloned.size !== 0) {\n const top = cloned.poll();\n if (top) visitedNode.push(top);\n }\n return visitedNode;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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\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, boolean>, thisArg?: any): Heap<E> {\n const filteredList = new Heap<E>();\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)\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(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 the\n * original heap. It takes three arguments: the current element, the index of the current element,\n * and the original heap itself. The callback function should return a value of type T, which will be\n * added to the mapped heap.\n * @param comparator - The `comparator` parameter is a function that is used to compare elements in\n * the heap. It takes two arguments, `a` and `b`, and returns a negative number if `a` is less than\n * `b`, a positive number if `a` is greater than `b`, or\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 when you want to bind a\n * specific object as the context for the callback function. If `thisArg` is not provided,\n * `undefined` is used as\n * @returns a new instance of the Heap class, which is created using the mapped elements from the\n * original Heap.\n */\n map<T>(callback: ElementCallback<E, T>, comparator: Comparator<T>, thisArg?: any): Heap<T> {\n\n const mappedHeap: Heap<T> = new Heap<T>([], { comparator: comparator });\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* _getIterator(): IterableIterator<E> {\n for (const element of this.elements) {\n yield element;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\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.options.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 (\n right < this.elements.length &&\n this.options.comparator(minItem, this.elements[right]) > 0\n ) {\n left = right;\n minItem = this.elements[right];\n }\n if (this.options.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 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 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 get root(): FibonacciHeapNode<E> | undefined {\n return this._root;\n }\n\n protected _size = 0;\n\n get size(): number {\n return this._size;\n }\n\n protected _min?: FibonacciHeapNode<E>;\n\n get min(): FibonacciHeapNode<E> | undefined {\n return this._min;\n }\n\n protected _comparator: Comparator<E>;\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\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\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\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\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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n), where n is the number of elements in the heap.\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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\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\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *.\n * Remove and return the top element (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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * Remove and return the top element (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), where n is the number of elements in the heap.\n * Space Complexity: O(n)\n */\n\n /**\n * Time Complexity: O(n log n), where n is the number of elements in the heap.\n * Space Complexity: O(n)\n *\n * Remove and return the top element (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 { 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> extends Heap<E> {\n constructor(\n elements?: Iterable<E>,\n options: HeapOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return b - a;\n }\n }\n }) {\n super(elements, options);\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 { 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 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 Prim's minimum spanning tree algorithm, which use heaps to improve performance.\n */\nexport class MinHeap<E = any> extends Heap<E> {\n constructor(\n elements?: Iterable<E>,\n options: HeapOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return a - b;\n }\n }\n }) {\n super(elements, options);\n }\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 { 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> extends IterableEntryBase<VertexKey, V | undefined> implements IGraph<V, E, VO, EO> {\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 /**\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\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\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\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\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\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\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\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\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\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 * Dijkstra algorithm time: O(VE) space: O(VO + EO)\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\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 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 genPaths && getPaths(minDest);\n\n return { distMap, preMap, seen, paths, minDist, minPath };\n }\n\n /**\n * Dijkstra algorithm time: O(logVE) space: O(VO + EO)\n *\n * Dijkstra's algorithm only solves the single-source shortest path problem, while the Bellman-Ford algorithm and Floyd-Warshall algorithm can address shortest paths between all pairs of nodes.\n * Dijkstra's algorithm is suitable for graphs with non-negative edge weights, whereas the Bellman-Ford algorithm and Floyd-Warshall algorithm can handle negative-weight edgeMap.\n * The time complexity of Dijkstra's algorithm and the Bellman-Ford algorithm depends on the size of the graph, while the time complexity of the Floyd-Warshall algorithm is O(VO^3), where VO is the number of nodes. For dense graphs, Floyd-Warshall might become slower.\n *\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\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\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 * one to rest pairs\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 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 * 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 * /\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 * Time Complexity: O(V + E) - Linear time (Tarjan's algorithm).\n * Space Complexity: O(V) - Linear space (Tarjan's algorithm).\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * Tarjan can find cycles in directed or undirected graph\n * Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time,\n * Tarjan solve the bi-connected components of undirected graphs;\n * Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.\n * /\n\n /**\n * Time Complexity: O(V + E) - Linear time (Tarjan's algorithm).\n * Space Complexity: O(V) - Linear space (Tarjan's algorithm).\n *\n * Tarjan is an algorithm based on dfs,which is used to solve the connectivity problem of graphs.\n * Tarjan can find cycles in directed or undirected graph\n * Tarjan can find the articulation points and bridges(critical edgeMap) of undirected graphs in linear time,\n * Tarjan solve the bi-connected components of undirected graphs;\n * Tarjan can find the SSC(strongly connected components), articulation points, and bridges of directed graphs.\n * The `tarjan` function is used to perform various graph analysis tasks such as finding articulation points, bridges,\n * strongly connected components (SCCs), and cycles in a graph.\n * @param {boolean} [needCutVertexes] - A boolean value indicating whether or not to calculate and return the\n * articulation points in the graph. Articulation points are the vertexMap in a graph whose removal would increase the\n * number of connected components in the graph.\n * @param {boolean} [needBridges] - A boolean flag indicating whether the algorithm should find and return the bridges\n * (edgeMap whose removal would increase the number of connected components in the graph).\n * @param {boolean} [needSCCs] - A boolean value indicating whether the Strongly Connected Components (SCCs) of the\n * graph are needed. If set to true, the function will calculate and return the SCCs of the graph. If set to false, the\n * SCCs will not be calculated or returned.\n * @param {boolean} [needCycles] - A boolean flag indicating whether the algorithm should find cycles in the graph. If\n * set to true, the algorithm will return a map of cycles, where the keys are the low values of the SCCs and the values\n * are arrays of vertexMap that form cycles within the SCCs.\n * @returns The function `tarjan` returns an object with the following properties:\n */\n tarjan(\n needCutVertexes: boolean = false,\n needBridges: boolean = false,\n needSCCs: boolean = true,\n needCycles: boolean = false\n ) {\n // !! in undirected graph we will not let child visit parent when dfs\n // !! articulation point(in dfs search tree not in graph): (cur !== root && cur.has(child)) && (low(child) >= dfn(cur)) || (cur === root && cur.children() >= 2)\n // !! bridge: low(child) > dfn(cur)\n\n const defaultConfig = false;\n if (needCutVertexes === undefined) needCutVertexes = defaultConfig;\n if (needBridges === undefined) needBridges = defaultConfig;\n if (needSCCs === undefined) needSCCs = defaultConfig;\n if (needCycles === undefined) needCycles = defaultConfig;\n\n const dfnMap: Map<VO, number> = new Map();\n const lowMap: Map<VO, number> = new Map();\n const vertexMap = this._vertexMap;\n vertexMap.forEach(v => {\n dfnMap.set(v, -1);\n lowMap.set(v, Infinity);\n });\n\n const [root] = vertexMap.values();\n\n const cutVertexes: VO[] = [];\n const bridges: EO[] = [];\n let dfn = 0;\n const dfs = (cur: VO, parent: VO | undefined) => {\n dfn++;\n dfnMap.set(cur, dfn);\n lowMap.set(cur, dfn);\n\n const neighbors = this.getNeighbors(cur);\n let childCount = 0; // child in dfs tree not child in graph\n for (const neighbor of neighbors) {\n if (neighbor !== parent) {\n if (dfnMap.get(neighbor) === -1) {\n childCount++;\n dfs(neighbor, cur);\n }\n const childLow = lowMap.get(neighbor);\n const curLow = lowMap.get(cur);\n // TODO after no-non-undefined-assertion not ensure the logic\n if (curLow !== undefined && childLow !== undefined) {\n lowMap.set(cur, Math.min(curLow, childLow));\n }\n const curFromMap = dfnMap.get(cur);\n if (childLow !== undefined && curFromMap !== undefined) {\n if (needCutVertexes) {\n if ((cur === root && childCount >= 2) || (cur !== root && childLow >= curFromMap)) {\n // todo not ensure the logic if (cur === root && childCount >= 2 || ((cur !== root) && (childLow >= curFromMap))) {\n cutVertexes.push(cur);\n }\n }\n\n if (needBridges) {\n if (childLow > curFromMap) {\n const edgeCurToNeighbor = this.getEdge(cur, neighbor);\n if (edgeCurToNeighbor) {\n bridges.push(edgeCurToNeighbor);\n }\n }\n }\n }\n }\n }\n };\n\n dfs(root, undefined);\n\n let SCCs: Map<number, VO[]> = new Map();\n\n const getSCCs = () => {\n const SCCs: Map<number, VO[]> = new Map();\n lowMap.forEach((low, vertex) => {\n if (!SCCs.has(low)) {\n SCCs.set(low, [vertex]);\n } else {\n SCCs.get(low)?.push(vertex);\n }\n });\n return SCCs;\n };\n\n if (needSCCs) {\n SCCs = getSCCs();\n }\n\n const cycles: Map<number, VO[]> = new Map();\n\n if (needCycles) {\n const visitedMap: Map<VO, boolean> = new Map();\n const stack: VO[] = [];\n const findCyclesDFS = (cur: VO, parent: VO | undefined) => {\n visitedMap.set(cur, true);\n stack.push(cur);\n\n const neighbors = this.getNeighbors(cur);\n\n for (const neighbor of neighbors) {\n if (!visitedMap.get(neighbor)) {\n findCyclesDFS(neighbor, cur);\n } else if (stack.includes(neighbor) && neighbor !== parent) {\n const cycleStartIndex = stack.indexOf(neighbor);\n const cycle = stack.slice(cycleStartIndex);\n const cycleLow = Math.min(...cycle.map(v => dfnMap.get(v) || Infinity));\n cycles.set(cycleLow, cycle);\n }\n }\n\n stack.pop();\n };\n\n vertexMap.forEach(v => {\n if (!visitedMap.get(v)) {\n findCyclesDFS(v, undefined);\n }\n });\n }\n\n return { dfnMap, lowMap, bridges, cutVertexes, SCCs, cycles };\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\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(false, false, false, false).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(false, false, false, false).lowMap;\n }\n\n /**\n * The function \"getCutVertexes\" returns an array of cut vertexes using the Tarjan algorithm.\n * @returns an array of VO objects, specifically the cut vertexes.\n */\n getCutVertexes(): VO[] {\n return this.tarjan(true, false, false, false).cutVertexes;\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(false, false, true, false).SCCs;\n }\n\n /**\n * The function \"getBridges\" returns an array of bridges using the Tarjan algorithm.\n * @returns the bridges found using the Tarjan algorithm.\n */\n getBridges() {\n return this.tarjan(false, true, false, false).bridges;\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 ((!isInclude2Cycle && currentPath.length > 2 || isInclude2Cycle && currentPath.length >= 2) && currentPath[0] === vertex.key) {\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 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 =>\n cycleString[1]\n );\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 `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\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler 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 * 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 protected _inEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();\n\n get inEdgeMap(): Map<VO, EO[]> {\n return this._inEdgeMap;\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 /**\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 * 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 /**\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\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\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\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\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 }\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\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 v1ToV2 && removed.push(v1ToV2);\n v2ToV1 && removed.push(v2ToV1);\n }\n\n return removed;\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 `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\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\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\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\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\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\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\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\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\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\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\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\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 /**\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 `_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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler 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 vertexMap: [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.vertexMap = [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 * 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 /**\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\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 vertexMap, 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.vertexMap.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\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 vertexMap (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.vertexMap.includes(vertex2.key))[0] || undefined;\n }\n const v2Edges = this._edgeMap.get(vertex2);\n if (v2Edges) {\n arrayRemove<EO>(v2Edges, (e: EO) => e.vertexMap.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\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 vertexMap 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.vertexMap[0]);\n otherSide = this._getVertex(edgeOrOneSideVertexKey.vertexMap[1]);\n }\n\n if (oneSide && otherSide) {\n return this.deleteEdgeBetween(oneSide, otherSide);\n\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\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.vertexMap.includes(vertexKey);\n });\n this._edgeMap.set(neighbor, restEdges);\n }\n })\n this._edgeMap.delete(vertex);\n\n }\n\n return this._vertexMap.delete(vertexKey);\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 `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\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\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\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 vertexMap 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.vertexMap.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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function \"getEndsOfEdge\" returns the vertexMap 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 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.vertexMap[0], edge.vertexMap[1])) {\n return undefined;\n }\n const v1 = this._getVertex(edge.vertexMap[0]);\n const v2 = this._getVertex(edge.vertexMap[1]);\n if (v1 && v2) {\n return [v1, v2];\n } else {\n return undefined;\n }\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 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.vertexMap) {\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(key: VertexKey, value?: V, lat: number = this.originCoord[0], long: number = this.originCoord[1]): 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","import { RedBlackTree, RedBlackTreeNode } from '../../../data-structures';\nimport type { BSTOptions } from \"./bst\";\n\nexport enum RBTNColor { RED = 1, BLACK = 0}\n\nexport type RedBlackTreeNodeNested<K, V> = RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, RedBlackTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\nexport type RedBlackTreeNested<K, V, N extends RedBlackTreeNode<K, V, N>> = RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, RedBlackTree<K, V, N, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\nexport type RBTreeOptions<K> = BSTOptions<K> & {};\n","export enum BSTVariant {\n MIN = 'MIN',\n MAX = 'MAX',\n}\n\nexport enum CP {\n lt = 'lt',\n eq = 'eq',\n gt = 'gt'\n}\n\n/**\n * Enum representing different loop types.\n *\n * - `iterative`: Indicates the iterative loop type (with loops that use iterations).\n * - `recursive`: Indicates the recursive loop type (with loops that call themselves).\n */\nexport enum IterationType {\n ITERATIVE = 'ITERATIVE',\n RECURSIVE = 'RECURSIVE'\n}\n\nexport enum FamilyPosition {\n ROOT = 'ROOT',\n LEFT = 'LEFT',\n RIGHT = 'RIGHT',\n ROOT_LEFT = 'ROOT_LEFT',\n ROOT_RIGHT = 'ROOT_RIGHT',\n ISOLATED = 'ISOLATED',\n MAL_NODE = 'MAL_NODE'\n}\n\nexport type Comparator<K> = (a: K, b: K) => number;\n\nexport type DFSOrderPattern = 'pre' | 'in' | 'post';\n\nexport type NodeDisplayLayout = [string[], number, number, number];\n\nexport type BTNCallback<N, D = any> = (node: N) => D;\n\nexport interface IterableWithSize<T> extends Iterable<T> {\n size: number | ((...args: any[]) => number);\n}\n\nexport interface IterableWithLength<T> extends Iterable<T> {\n length: number | ((...args: any[]) => number);\n}\n\nexport type IterableWithSizeOrLength<T> = IterableWithSize<T> | IterableWithLength<T>\n\nexport type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean }\n\nexport type BTNEntry<K, V> = [K | null | undefined, V | undefined];\n\nexport type BTNKeyOrNode<K, N> = K | null | undefined | N;\n\nexport type BTNExemplar<K, V, N> = BTNEntry<K, V> | BTNKeyOrNode<K, N>\n\nexport type BTNodePureKeyOrNode<K, N> = K | N;\n\nexport type BTNodePureExemplar<K, V, N> = [K, V | undefined] | BTNodePureKeyOrNode<K, N>;\n\nexport type BSTNKeyOrNode<K, N> = K | undefined | N;\n\nexport type BinaryTreeDeleteResult<N> = { deleted: N | null | undefined; needBalanced: N | null | undefined };\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 */\n\nimport type {\n BinaryTreeDeleteResult,\n BinaryTreeNested,\n BinaryTreeNodeNested,\n BinaryTreeOptions,\n BinaryTreePrintOptions,\n BTNCallback,\n BTNEntry,\n BTNExemplar,\n BTNKeyOrNode,\n DFSOrderPattern,\n EntryCallback,\n NodeDisplayLayout\n} from '../../types';\nimport { FamilyPosition, IterationType } from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { trampoline } from '../../utils';\nimport { Queue } from '../queue';\nimport { IterableEntryBase } from \"../base\";\n\n/**\n * Represents a node in a binary tree.\n * @template V - The type of data stored in the node.\n * @template N - The type of the family relationship in the binary tree.\n */\nexport class BinaryTreeNode<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>> {\n key: K;\n\n value?: V;\n\n parent?: N;\n\n constructor(key: K, value?: V) {\n this.key = key;\n this.value = value;\n }\n\n protected _left?: N | null;\n\n get left(): N | null | undefined {\n return this._left;\n }\n\n set left(v: N | null | undefined) {\n if (v) {\n v.parent = this as unknown as N;\n }\n this._left = v;\n }\n\n protected _right?: N | null;\n\n get right(): N | null | undefined {\n return this._right;\n }\n\n set right(v: N | null | undefined) {\n if (v) {\n v.parent = this as unknown as N;\n }\n this._right = v;\n }\n\n /**\n * Get the position of the node within its family.\n * @returns {FamilyPosition} - The family position of the node.\n */\n get familyPosition(): FamilyPosition {\n const that = this as unknown as N;\n if (!this.parent) {\n return this.left || this.right ? FamilyPosition.ROOT : FamilyPosition.ISOLATED;\n }\n\n if (this.parent.left === that) {\n return this.left || this.right ? FamilyPosition.ROOT_LEFT : FamilyPosition.LEFT;\n } else if (this.parent.right === that) {\n return this.left || this.right ? FamilyPosition.ROOT_RIGHT : FamilyPosition.RIGHT;\n }\n\n return FamilyPosition.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 */\n\nexport class BinaryTree<K = any, V = any, N extends BinaryTreeNode<K, V, N> = BinaryTreeNode<K, V, BinaryTreeNodeNested<K, V>>, TREE extends BinaryTree<K, V, N, TREE> = BinaryTree<K, V, N, BinaryTreeNested<K, V, N>>> extends IterableEntryBase<K, V | undefined>\n\n implements IBinaryTree<K, V, N, TREE> {\n iterationType = IterationType.ITERATIVE\n\n /**\n * The constructor function initializes a binary tree object with optional elements and options.\n * @param [elements] - An optional iterable of BTNExemplar objects. These objects represent the\n * elements to be added to the binary tree.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the binary tree. In this case, it is of type\n * `Partial<BinaryTreeOptions>`, which means that not all properties of `BinaryTreeOptions` are\n * required.\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<BinaryTreeOptions<K>>) {\n super();\n if (options) {\n const { iterationType, extractor } = options;\n if (iterationType) {\n this.iterationType = iterationType;\n }\n if (extractor) {\n this._extractor = extractor;\n }\n }\n\n this._size = 0;\n\n if (elements) this.addMany(elements);\n }\n\n protected _extractor = (key: K) => Number(key)\n\n get extractor() {\n return this._extractor;\n }\n\n protected _root?: N | null;\n\n get root(): N | null | undefined {\n return this._root;\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n /**\n * Creates a new instance of BinaryTreeNode with the given key and value.\n * @param {K} key - The key for the new node.\n * @param {V} value - The value for the new node.\n * @returns {N} - The newly created BinaryTreeNode.\n */\n createNode(key: K, value?: V): N {\n return new BinaryTreeNode<K, V, N>(key, value) as N;\n }\n\n /**\n * The function creates a binary tree with the given options.\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the `BinaryTree` class. It is of type `Partial<BinaryTreeOptions>`, which means that\n * you can provide only a subset of the properties defined in the `BinaryTreeOptions` interface.\n * @returns a new instance of a binary tree.\n */\n createTree(options?: Partial<BinaryTreeOptions<K>>): TREE {\n return new BinaryTree<K, V, N, TREE>([], { iterationType: this.iterationType, ...options }) as TREE;\n }\n\n /**\n * The function \"isNode\" checks if an exemplar is an instance of the BinaryTreeNode class.\n * @param exemplar - The `exemplar` parameter is a variable of type `BTNExemplar<K, V,N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the class N.\n */\n isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof BinaryTreeNode;\n }\n\n /**\n * The function `exemplarToNode` converts an exemplar object into a node object.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `exemplarToNode` function. It represents the value associated with the exemplar node. If no value\n * is provided, it will be `undefined`.\n * @returns a value of type N (node), or null, or undefined.\n */\n exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V): N | null | undefined {\n if (exemplar === undefined) return;\n\n let node: N | null | undefined;\n if (exemplar === null) {\n node = null;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined) {\n return;\n } else if (key === null) {\n node = null;\n } else {\n node = this.createNode(key, value);\n }\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * The function checks if a given value is an entry in a binary tree node.\n * @param kne - BTNExemplar<K, V,N> - A generic type representing a node in a binary tree. It has\n * two type parameters V and N, representing the value and node type respectively.\n * @returns a boolean value.\n */\n isEntry(kne: BTNExemplar<K, V, N>): kne is BTNEntry<K, V> {\n return Array.isArray(kne) && kne.length === 2;\n }\n\n /**\n * Time Complexity O(log n) - O(n)\n * Space Complexity O(1)\n */\n\n /**\n * Time Complexity O(log n) - O(n)\n * Space Complexity O(1)\n *\n * The `add` function adds a new node to a binary tree, either by creating a new node or replacing an\n * existing node with the same key.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be one of the following:\n * @param {V} [value] - The value to be inserted into the binary tree.\n * @returns The function `add` returns either a node (`N`), `null`, or `undefined`.\n */\n add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | null | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);\n if (newNode === undefined) return;\n\n // If the tree is empty, directly set the new node as the root node\n if (!this.root) {\n this._root = newNode;\n this._size = 1;\n return newNode;\n }\n\n const queue = new Queue<N>([this.root]);\n let potentialParent: N | 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 newNode; // 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 cur.left && queue.push(cur.left);\n }\n if (cur.right !== null) {\n 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 newNode;\n }\n\n return undefined; // If the insertion position cannot be found, return undefined\n }\n\n\n /**\n * Time Complexity: O(k log n) - O(k * n)\n * Space Complexity: O(1)\n * Comments: The time complexity for adding a node depends on the depth of the tree. In the best case (when the tree is empty), it's O(1). In the worst case (when the tree is a degenerate tree), it's O(n). The space complexity is constant.\n */\n\n /**\n * Time Complexity: O(k log n) - O(k * n)\n * Space Complexity: O(1)\n *\n * The `addMany` function takes in a collection of nodes and an optional collection of values, and\n * adds each node with its corresponding value to the data structure.\n * @param nodes - An iterable collection of BTNExemplar objects.\n * @param [values] - An optional iterable of values that will be assigned to each node being added.\n * @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.\n */\n addMany(nodes: Iterable<BTNExemplar<K, V, N>>, values?: Iterable<V | undefined>): (N | null | undefined)[] {\n // TODO not sure addMany not be run multi times\n const inserted: (N | null | undefined)[] = [];\n\n let valuesIterator: Iterator<V | undefined> | undefined;\n if (values) {\n valuesIterator = values[Symbol.iterator]();\n }\n\n for (const kne of nodes) {\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(kne, value));\n }\n\n return inserted;\n }\n\n\n /**\n * Time Complexity: O(k * n) \"n\" is the number of nodes in the tree, and \"k\" is the number of keys to be inserted.\n * Space Complexity: O(1)\n */\n\n refill(nodesOrKeysOrEntries: Iterable<BTNExemplar<K, V, N>>, values?: Iterable<V | undefined>): void {\n this.clear();\n this.addMany(nodesOrKeysOrEntries, values);\n }\n\n /**\n * Time Complexity: O(k * n) \"n\" is the number of nodes in the tree, and \"k\" is the number of keys to be inserted.\n * Space Complexity: O(1)\n */\n\n delete<C extends BTNCallback<N, K>>(identifier: K, callback?: C): BinaryTreeDeleteResult<N>[];\n\n delete<C extends BTNCallback<N, N>>(identifier: N | null | undefined, callback?: C): BinaryTreeDeleteResult<N>[];\n\n delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BinaryTreeDeleteResult<N>[];\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function deletes a node from a binary tree and returns an array of the deleted nodes along\n * with the nodes that need to be balanced.\n * @param {ReturnType<C> | null | undefined} identifier - The identifier parameter is the value or\n * object that you want to delete from the binary tree. It can be of any type that is compatible with\n * the callback function's return type. It can also be null or undefined if you want to delete a\n * specific node based on its value or object.\n * @param {C} callback - The `callback` parameter is a function that is used to determine the\n * identifier of the node to be deleted. It is optional and has a default value of\n * `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.\n * @returns an array of `BinaryTreeDeleteResult<N>`.\n */\n delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C\n ): BinaryTreeDeleteResult<N>[] {\n const deletedResult: BinaryTreeDeleteResult<N>[] = [];\n if (!this.root) return deletedResult;\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n const curr = this.getNode(identifier, callback);\n if (!curr) return deletedResult;\n\n const parent: N | null | undefined = curr?.parent ? curr.parent : null;\n let needBalanced: N | null | undefined = undefined;\n let orgCurrent: N | undefined = curr;\n\n if (!curr.left) {\n if (!parent) {\n // Handle the case when there's only one root node\n this._setRoot(null);\n } else {\n const { familyPosition: fp } = curr;\n if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {\n parent.left = curr.right;\n } else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {\n parent.right = curr.right;\n }\n needBalanced = parent;\n }\n } else {\n if (curr.left) {\n const leftSubTreeRightMost = this.getRightMost(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 }\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(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function calculates the depth of a given node in a binary tree.\n * @param {K | N | null | undefined} distNode - The `distNode` parameter represents the node in\n * the binary tree whose depth we want to find. It can be of type `K`, `N`, `null`, or\n * `undefined`.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node\n * from which we want to calculate the depth. It can be either a `K` (binary tree node key) or\n * `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot\n * @returns the depth of the `distNode` relative to the `beginRoot`.\n */\n getDepth(distNode: BTNKeyOrNode<K, N>, beginRoot: BTNKeyOrNode<K, N> = this.root): number {\n distNode = this.ensureNode(distNode);\n beginRoot = this.ensureNode(beginRoot);\n let depth = 0;\n while (distNode?.parent) {\n if (distNode === beginRoot) {\n return depth;\n }\n depth++;\n distNode = distNode.parent;\n }\n return depth;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getHeight` calculates the maximum height of a binary tree using either recursive or\n * iterative traversal.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node of the binary tree from which we want to calculate the height. It can be of type\n * `K`, `N`, `null`, or `undefined`. If not provided, it defaults to `this.root`.\n * @param iterationType - The `iterationType` parameter is used to determine whether to calculate the\n * height of the tree using a recursive approach or an iterative approach. It can have two possible\n * values:\n * @returns the height of the binary tree.\n */\n getHeight(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return -1;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _getMaxHeight = (cur: N | null | undefined): number => {\n if (!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: N; 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 (node.left) stack.push({ node: node.left, depth: depth + 1 });\n if (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 * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)\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.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node of the binary tree from which we want to calculate the minimum height. It can be of\n * type `K`, `N`, `null`, or `undefined`. If no value is provided, it defaults to `this.root`.\n * @param iterationType - The `iterationType` parameter is used to determine the method of iteration\n * to calculate the minimum height of a binary tree. It can have two possible values:\n * @returns The function `getMinHeight` returns the minimum height of a binary tree.\n */\n getMinHeight(beginRoot: BTNKeyOrNode<K, N> = this.root, iterationType = this.iterationType): number {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return -1;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _getMinHeight = (cur: N | null | undefined): number => {\n if (!cur) return 0;\n if (!cur.left && !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: N[] = [];\n let node: N | null | undefined = beginRoot,\n last: N | null | undefined = null;\n const depths: Map<N, 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 leftMinHeight = node.left ? depths.get(node.left) ?? -1 : -1;\n const rightMinHeight = node.right ? depths.get(node.right) ?? -1 : -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) ?? -1;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n * Best Case - O(log n) (when using recursive iterationType), Worst Case - O(n) (when using iterative iterationType)\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 the minimum height and the\n * height of the tree.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for calculating the height and minimum height of a binary tree. It can be either a `K` (a key\n * value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If\n * @returns a boolean value.\n */\n isPerfectlyBalanced(beginRoot: BTNKeyOrNode<K, N> = this.root): boolean {\n return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n getNodes<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n onlyOne?: boolean,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N[];\n\n getNodes<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n onlyOne?: boolean,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N[];\n\n getNodes<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n onlyOne?: boolean,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N[];\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n).\n *\n * The function `getNodes` retrieves nodes from a binary tree based on a given identifier and\n * callback function.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * that you want to search for in the binary tree. It can be of any type that is returned by the\n * callback function `C`. It can also be `null` or `undefined` if you don't want to search for a\n * specific value.\n * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` as\n * input and returns a value of type `C`. It is used to determine if a node matches the given\n * identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the\n * default\n * @param [onlyOne=false] - A boolean value indicating whether to only return the first node that\n * matches the identifier. If set to true, the function will stop iterating once it finds a matching\n * node and return that node. If set to false (default), the function will continue iterating and\n * return all nodes that match the identifier.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node for the traversal. It can be either a key, a node object, or `null`/`undefined`. If\n * it is `null` or `undefined`, an empty array will be returned.\n * @param iterationType - The `iterationType` parameter determines the type of iteration used to\n * traverse the binary tree. It can have two possible values:\n * @returns an array of nodes of type `N`.\n */\n getNodes<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n onlyOne = false,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N[] {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n\n const ans: N[] = [];\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N) => {\n if (callback(cur) === identifier) {\n ans.push(cur);\n if (onlyOne) return;\n }\n if (!cur.left && !cur.right) return;\n cur.left && _traverse(cur.left);\n cur.right && _traverse(cur.right);\n };\n\n _traverse(beginRoot);\n } else {\n const queue = new Queue<N>([beginRoot]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n if (callback(cur) === identifier) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n cur.left && queue.push(cur.left);\n cur.right && queue.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\n has<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): boolean;\n\n has<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): boolean;\n\n has<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): boolean;\n\n /**\n * Time Complexity: O(n)\n *\n * The function checks if a Binary Tree Node with a specific identifier exists in the tree.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * that you want to search for in the binary tree. It can be of any type that is returned by the\n * callback function `C`. It can also be `null` or `undefined` if you don't want to specify a\n * specific identifier.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the binary tree. It is used to filter the nodes based on certain conditions. The `callback`\n * function should return a boolean value indicating whether the node should be included in the\n * result or not.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a\n * node in the binary tree), a node object (`N`), or `null`/`undefined` to start the search from\n * @param iterationType - The `iterationType` parameter is a variable that determines the type of\n * iteration to be performed on the binary tree. It is used to specify whether the iteration should\n * be performed in a pre-order, in-order, or post-order manner.\n * @returns a boolean value.\n */\n has<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): boolean {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n).\n */\n\n getNode<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N | null | undefined;\n\n getNode<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N | null | undefined;\n\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): N | null | undefined;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getNode` returns the first node that matches the given identifier and callback\n * function.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * used to identify the node you want to retrieve. It can be of any type that is returned by the\n * callback function `C`. It can also be `null` or `undefined` if you don't have a specific\n * identifier.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the binary tree. It is used to determine if a node matches the given identifier. The `callback`\n * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for searching the binary tree. It can be either a key value, a node object, or `null`/`undefined`.\n * If `null` or `undefined` is passed, the search will start from the root of the binary tree.\n * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to\n * be performed when searching for nodes in the binary tree. It determines the order in which the\n * nodes are visited during the search.\n * @returns a value of type `N | null | undefined`.\n */\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `getNodeByKey` searches for a node in a binary tree by its key, using either\n * recursive or iterative iteration.\n * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.\n * It is used to find the node with the matching key value.\n * @param iterationType - The `iterationType` parameter is used to determine whether the search for\n * the node with the given key should be performed iteratively or recursively. It has two possible\n * values:\n * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is\n * found in the binary tree. If no node is found, it returns `undefined`.\n */\n getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {\n if (!this.root) return undefined;\n if (iterationType === IterationType.RECURSIVE) {\n const _dfs = (cur: N): N | undefined => {\n if (cur.key === key) return cur;\n\n if (!cur.left && !cur.right) return;\n if (cur.left) return _dfs(cur.left);\n if (cur.right) return _dfs(cur.right);\n };\n\n return _dfs(this.root);\n } else {\n const queue = new Queue<N>([this.root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n if (cur.key === key) return cur;\n cur.left && queue.push(cur.left);\n cur.right && queue.push(cur.right);\n }\n }\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n /**\n * The function `ensureNode` returns the node corresponding to the given key if it is a valid node\n * key, otherwise it returns the key itself.\n * @param {K | N | null | undefined} key - The `key` parameter can be of type `K`, `N`,\n * `null`, or `undefined`. It represents a key used to identify a node in a binary tree.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to be used when searching for a node by key. It has a default value of\n * `IterationType.ITERATIVE`.\n * @returns either the node corresponding to the given key if it is a valid node key, or the key\n * itself if it is not a valid node key.\n */\n ensureNode(key: BTNKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | null | undefined {\n return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;\n }\n\n get<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): V | undefined;\n\n get<C extends BTNCallback<N, N>>(\n identifier: N | null | undefined,\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): V | undefined;\n\n get<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType\n ): V | undefined;\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n *\n * The function `get` retrieves the value of a node in a binary tree based on the provided identifier\n * and callback function.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * used to identify the node in the binary tree. It can be of any type that is the return type of the\n * callback function `C`. It can also be `null` or `undefined` if no identifier is provided.\n * @param {C} callback - The `callback` parameter is a function that will be called with each node in\n * the binary tree. It is used to determine whether a node matches the given identifier. The callback\n * function should return a value that can be compared to the identifier to determine if it is a\n * match.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for the search in the binary tree. It can be specified as a `K` (a unique identifier for a\n * node), a node object of type `N`, or `null`/`undefined` to start the search from the root of\n * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to\n * be performed when searching for a node in the binary tree. It is an optional parameter with a\n * default value specified by `this.iterationType`.\n * @returns The value of the node with the given identifier is being returned. If the node is not\n * found, `undefined` is returned.\n */\n get<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): V | undefined {\n if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)\n callback = (node => node) as C;\n\n return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(log n)\n */\n\n /**\n * Clear the binary tree, removing all nodes.\n */\n clear() {\n this._setRoot(undefined);\n this._size = 0;\n }\n\n /**\n * Check if the binary tree is empty.\n * @returns {boolean} - True if the binary tree is empty, false otherwise.\n */\n isEmpty(): boolean {\n return this.size === 0;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n *\n * The function `getPathToRoot` returns an array of nodes from a given node to the root of a tree\n * structure, with the option to reverse the order of the nodes.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node from which you want to find the path to the root. It can be of type `K`, `N`,\n * `null`, or `undefined`.\n * @param [isReverse=true] - The `isReverse` parameter is a boolean flag that determines whether the\n * resulting path should be reversed or not. If `isReverse` is set to `true`, the path will be\n * reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is\n * @returns The function `getPathToRoot` returns an array of nodes (`N[]`).\n */\n getPathToRoot(beginRoot: BTNKeyOrNode<K, N>, isReverse = true): N[] {\n // TODO to support get path through passing key\n const result: N[] = [];\n beginRoot = this.ensureNode(beginRoot);\n\n if (!beginRoot) return result;\n\n while (beginRoot.parent) {\n // Array.push + Array.reverse is more efficient than Array.unshift\n // TODO may consider using Deque, so far this is not the performance bottleneck\n result.push(beginRoot);\n beginRoot = beginRoot.parent;\n }\n result.push(beginRoot);\n return isReverse ? result.reverse() : result;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(log n)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getLeftMost` returns the leftmost node in a binary tree, either recursively or\n * iteratively.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting point\n * for finding the leftmost node in a binary tree. It can be either a `K` (a key value), `N` (a\n * node), `null`, or `undefined`. If not provided, it defaults to `this.root`,\n * @param iterationType - The `iterationType` parameter is used to determine the type of iteration to\n * be performed when finding the leftmost node in a binary tree. It can have two possible values:\n * @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there\n * is no leftmost node, it returns `null` or `undefined` depending on the input.\n */\n getLeftMost(\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n beginRoot = this.ensureNode(beginRoot);\n\n if (!beginRoot) return beginRoot;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N): N => {\n if (!this.isRealNode(cur.left)) return cur;\n return _traverse(cur.left);\n };\n\n return _traverse(beginRoot);\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const _traverse = trampoline((cur: N) => {\n if (!this.isRealNode(cur.left)) return cur;\n return _traverse.cont(cur.left);\n });\n\n return _traverse(beginRoot);\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function `getRightMost` returns the rightmost node in a binary tree, either recursively or\n * iteratively.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node from which we want to find the rightmost node. It can be of type `K`, `N`,\n * `null`, or `undefined`. If not provided, it defaults to `this.root`, which is a property of the\n * current object.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when finding the rightmost node. It can have one of two values:\n * @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there\n * is no rightmost node, it returns `null` or `undefined`, depending on the input.\n */\n getRightMost(\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n // TODO support get right most by passing key in\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return beginRoot;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N): N => {\n if (!this.isRealNode(cur.right)) return cur;\n return _traverse(cur.right);\n };\n\n return _traverse(beginRoot);\n } else {\n // Indirect implementation of iteration using tail recursion optimization\n const _traverse = trampoline((cur: N) => {\n if (!this.isRealNode(cur.right)) return cur;\n return _traverse.cont(cur.right);\n });\n\n return _traverse(beginRoot);\n }\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function `isSubtreeBST` checks if a given binary tree is a valid binary search tree.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the root\n * node of the binary search tree (BST) that you want to check if it is a subtree of another BST.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when checking if a subtree is a binary search tree (BST). It can have two\n * possible values:\n * @returns a boolean value.\n */\n isSubtreeBST(beginRoot: BTNKeyOrNode<K, N>, iterationType = this.iterationType): boolean {\n // TODO there is a bug\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return true;\n\n if (iterationType === IterationType.RECURSIVE) {\n const dfs = (cur: N | null | undefined, min: number, max: number): boolean => {\n if (!cur) return true;\n const numKey = this.extractor(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 return dfs(beginRoot, Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);\n } else {\n const stack = [];\n let prev = Number.MIN_SAFE_INTEGER,\n curr: N | null | undefined = beginRoot;\n while (curr || stack.length > 0) {\n while (curr) {\n stack.push(curr);\n curr = curr.left;\n }\n curr = stack.pop()!;\n const numKey = this.extractor(curr.key);\n if (!curr || prev >= numKey) return false;\n prev = numKey;\n curr = curr.right;\n }\n return true;\n }\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n *\n * The function checks if a binary tree is a binary search tree.\n * @param iterationType - The parameter \"iterationType\" is used to specify the type of iteration to\n * be used when checking if the binary tree is a binary search tree (BST). It is an optional\n * parameter with a default value of \"this.iterationType\". The value of \"this.iterationType\" is\n * expected to be\n * @returns a boolean value.\n */\n isBST(iterationType = this.iterationType): boolean {\n if (this.root === null) return true;\n return this.isSubtreeBST(this.root, iterationType);\n }\n\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(1)\n */\n\n subTreeTraverse<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n subTreeTraverse<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[];\n\n subTreeTraverse<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: true\n ): ReturnType<C>[];\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(log n)\n *\n * The function `subTreeTraverse` traverses a binary tree and applies a callback function to each\n * node, either recursively or iteratively.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the subtree traversal. It takes a single parameter, which is the current node being traversed, and\n * returns a value of any type.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node or key from which the subtree traversal should begin. It can be of type `K`,\n * `N`, `null`, or `undefined`. If not provided, the `root` property of the current object is used as\n * the default value.\n * @param iterationType - The `iterationType` parameter determines the type of traversal to be\n * performed on the subtree. It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines\n * whether to include null values in the traversal. If `includeNull` is set to `true`, the\n * traversal will include null values, otherwise it will skip them.\n * @returns The function `subTreeTraverse` returns an array of values that are the result of invoking\n * the `callback` function on each node in the subtree. The type of the array elements is determined\n * by the return type of the `callback` function.\n */\n subTreeTraverse<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n\n const ans: (ReturnType<BTNCallback<N>> | null | undefined)[] = [];\n if (!beginRoot) return ans;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N | null | undefined) => {\n if (cur !== undefined) {\n ans.push(callback(cur));\n if (includeNull) {\n cur && this.isNodeOrNull(cur.left) && _traverse(cur.left);\n cur && this.isNodeOrNull(cur.right) && _traverse(cur.right);\n } else {\n cur && cur.left && _traverse(cur.left);\n cur && cur.right && _traverse(cur.right);\n }\n }\n };\n\n _traverse(beginRoot);\n } else {\n const stack: (N | null | undefined)[] = [beginRoot];\n\n while (stack.length > 0) {\n const cur = stack.pop();\n if (cur !== undefined) {\n ans.push(callback(cur));\n if (includeNull) {\n cur && this.isNodeOrNull(cur.right) && stack.push(cur.right);\n cur && this.isNodeOrNull(cur.left) && stack.push(cur.left);\n } else {\n cur && cur.right && stack.push(cur.right);\n cur && cur.left && stack.push(cur.left);\n }\n }\n }\n }\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(log n)\n */\n\n /**\n * The function checks if a given node is a real node by verifying if it is an instance of\n * BinaryTreeNode and its key is not NaN.\n * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.\n * @returns a boolean value.\n */\n isRealNode(node: BTNExemplar<K, V, N>): node is N {\n return node instanceof BinaryTreeNode && String(node.key) !== 'NaN';\n }\n\n /**\n * The function checks if a given node is a BinaryTreeNode instance and has a key value of NaN.\n * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.\n * @returns a boolean value.\n */\n isNIL(node: BTNExemplar<K, V, N>) {\n return node instanceof BinaryTreeNode && String(node.key) === 'NaN';\n }\n\n /**\n * The function checks if a given node is a real node or null.\n * @param {any} node - The parameter `node` is of type `any`, which means it can be any data type.\n * @returns a boolean value.\n */\n isNodeOrNull(node: BTNExemplar<K, V, N>): node is N | null {\n return this.isRealNode(node) || node === null;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof BinaryTreeNode)\n }\n\n dfs<C extends BTNCallback<N>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n dfs<C extends BTNCallback<N>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[];\n\n dfs<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n pattern?: DFSOrderPattern,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: true\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 or graph, based on the\n * specified pattern and iteration type, and returns an array of values obtained from applying a\n * callback function to each visited node.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the tree during the depth-first search. It takes a single parameter, which can be of type `N`,\n * `null`, or `undefined`, and returns a value of any type. The default value for this parameter is\n * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter determines the order in which the\n * nodes are traversed during the depth-first search. It can have one of the following values:\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node\n * for the depth-first search traversal. It can be specified as a key, a node object, or\n * `null`/`undefined`. If not provided, the `beginRoot` will default to the root node of the tree.\n * @param {IterationType} iterationType - The `iterationType` parameter determines the type of\n * iteration to use when traversing the tree. It can have one of the following values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines\n * whether null or undefined nodes should be included in the traversal. If `includeNull` is set to\n * `true`, null or undefined nodes will be included in the traversal. If `includeNull` is set to\n * `false`, null or undefined\n * @returns an array of values that are the return values of the callback function.\n */\n dfs<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n pattern: DFSOrderPattern = 'in',\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType: IterationType = IterationType.ITERATIVE,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: ReturnType<C>[] = [];\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (node: N | null | undefined) => {\n switch (pattern) {\n case 'in':\n if (includeNull) {\n if (node && this.isNodeOrNull(node.left)) _traverse(node.left);\n this.isNodeOrNull(node) && ans.push(callback(node));\n if (node && this.isNodeOrNull(node.right)) _traverse(node.right);\n } else {\n if (node && node.left) _traverse(node.left);\n this.isRealNode(node) && ans.push(callback(node));\n if (node && node.right) _traverse(node.right);\n }\n break;\n case 'pre':\n if (includeNull) {\n this.isNodeOrNull(node) && ans.push(callback(node));\n if (node && this.isNodeOrNull(node.left)) _traverse(node.left);\n if (node && this.isNodeOrNull(node.right)) _traverse(node.right);\n } else {\n this.isRealNode(node) && ans.push(callback(node));\n if (node && node.left) _traverse(node.left);\n if (node && node.right) _traverse(node.right);\n }\n break;\n case 'post':\n if (includeNull) {\n if (node && this.isNodeOrNull(node.left)) _traverse(node.left);\n if (node && this.isNodeOrNull(node.right)) _traverse(node.right);\n this.isNodeOrNull(node) && ans.push(callback(node));\n } else {\n if (node && node.left) _traverse(node.left);\n if (node && node.right) _traverse(node.right);\n this.isRealNode(node) && ans.push(callback(node));\n }\n\n break;\n }\n };\n\n _traverse(beginRoot);\n } else {\n // 0: visit, 1: print\n const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{ opt: 0, node: beginRoot }];\n\n while (stack.length > 0) {\n const cur = stack.pop();\n if (cur === undefined || this.isNIL(cur.node)) continue;\n if (includeNull) {\n if (cur.node === undefined) continue;\n } else {\n if (cur.node === null || cur.node === undefined) continue;\n }\n if (cur.opt === 1) {\n ans.push(callback(cur.node));\n } else {\n switch (pattern) {\n case 'in':\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n stack.push({ opt: 1, node: cur.node });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n break;\n case 'pre':\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n stack.push({ opt: 1, node: cur.node });\n break;\n case 'post':\n stack.push({ opt: 1, node: cur.node });\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n break;\n default:\n cur.node && stack.push({ opt: 0, node: cur.node.right });\n stack.push({ opt: 1, node: cur.node });\n cur.node && stack.push({ opt: 0, node: cur.node.left });\n break;\n }\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n */\n\n bfs<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[];\n\n bfs<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[];\n\n bfs<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\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, executing a\n * callback function on each node.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the breadth-first search traversal. It takes a single parameter, which is the current node being\n * visited, and returns a value of any type.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node for the breadth-first search traversal. It can be specified as a key, a node object,\n * or `null`/`undefined` to indicate the root of the tree. If not provided, the `root` property of\n * the class is used as\n * @param iterationType - The `iterationType` parameter determines the type of iteration to be\n * performed during the breadth-first search (BFS). It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean flag that determines whether\n * to include null values in the breadth-first search traversal. If `includeNull` is set to\n * `true`, null values will be included in the traversal, otherwise they will be skipped.\n * @returns an array of values that are the result of invoking the callback function on each node in\n * the breadth-first traversal of a binary tree.\n */\n bfs<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType,\n includeNull = false\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n\n const ans: ReturnType<BTNCallback<N>>[] = [];\n\n if (iterationType === IterationType.RECURSIVE) {\n const queue: Queue<N | null | undefined> = new Queue<N | null | undefined>([beginRoot]);\n\n const traverse = (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.isNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (current.left) queue.push(current.left);\n if (current.right) queue.push(current.right);\n }\n\n traverse(level + 1);\n };\n\n traverse(0);\n } else {\n const queue = new Queue<N | null | undefined>([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.isNodeOrNull(current.left)) queue.push(current.left);\n if (current && this.isNodeOrNull(current.right)) queue.push(current.right);\n } else {\n if (current.left) queue.push(current.left);\n if (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\n listLevels<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: false\n ): ReturnType<C>[][];\n\n listLevels<C extends BTNCallback<N>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\n iterationType?: IterationType,\n includeNull?: undefined\n ): ReturnType<C>[][];\n\n listLevels<C extends BTNCallback<N | null | undefined>>(\n callback?: C,\n beginRoot?: BTNKeyOrNode<K, N>,\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 returns an array of arrays, where each inner array represents a level in\n * a binary tree and contains the values returned by a callback function applied to the nodes at that\n * level.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the tree. It takes a single parameter, which can be of type `N`, `null`, or `undefined`, and\n * returns a value of any type.\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter represents the\n * starting node for traversing the tree. It can be either a node object (`N`), a key value\n * (`K`), `null`, or `undefined`. If not provided, it defaults to the root node of the tree.\n * @param iterationType - The `iterationType` parameter determines the type of iteration to be\n * performed on the tree. It can have two possible values:\n * @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines\n * whether to include null values in the resulting levels. If `includeNull` is set to `true`,\n * null values will be included in the levels. If `includeNull` is set to `false`, null values will\n * be excluded\n * @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.\n */\n listLevels<C extends BTNCallback<N | null | undefined>>(\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BTNKeyOrNode<K, N> = this.root,\n 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 === IterationType.RECURSIVE) {\n const _recursive = (node: N | null | undefined, level: number) => {\n if (!levelsNodes[level]) levelsNodes[level] = [];\n levelsNodes[level].push(callback(node));\n if (includeNull) {\n if (node && this.isNodeOrNull(node.left)) _recursive(node.left, level + 1);\n if (node && this.isNodeOrNull(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: [N | null | undefined, 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.isNodeOrNull(node.right)) stack.push([node.right, level + 1]);\n if (node && this.isNodeOrNull(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(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function returns the predecessor of a given node in a tree.\n * @param {N} node - The parameter `node` is of type `RedBlackTreeNode`, which represents a node in a\n * tree.\n * @returns the predecessor of the given 'node'.\n */\n getPredecessor(node: N): N {\n if (this.isRealNode(node.left)) {\n let predecessor: N | null | undefined = 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 * The function `getSuccessor` returns the next node in a binary tree given a current node.\n * @param {K | N | null} [x] - The parameter `x` can be of type `K`, `N`, or `null`.\n * @returns the successor of the given node or key. The successor is the node that comes immediately\n * after the given node in the inorder traversal of the binary tree.\n */\n getSuccessor(x?: K | N | null): N | null | undefined {\n\n x = this.ensureNode(x);\n if (!this.isRealNode(x)) return undefined;\n\n if (this.isRealNode(x.right)) {\n return this.getLeftMost(x.right);\n }\n\n let y: N | null | undefined = x.parent;\n while (this.isRealNode(y) && x === y.right) {\n x = y;\n y = y.parent;\n }\n return y;\n }\n\n /**\n * Time complexity: O(n)\n * Space complexity: O(1)\n * The `morris` function performs a depth-first traversal on a binary tree using the Morris traversal\n * algorithm.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the tree. It takes a single parameter of type `N` (the type of the nodes in the tree) and returns\n * a value of any type.\n * @param {DFSOrderPattern} [pattern=in] - The `pattern` parameter in the `morris` function\n * determines the order in which the nodes of a binary tree are traversed. It can have one of the\n * following values:\n * @param {K | N | null | undefined} beginRoot - The `beginRoot` parameter is the starting node\n * for the traversal. It can be specified as a key, a node object, or `null`/`undefined` to indicate\n * the root of the tree. If no value is provided, the default value is the root of the tree.\n * @returns The function `morris` returns an array of values that are the result of invoking the\n * `callback` function on each node in the binary tree. The type of the array elements is determined\n * by the return type of the `callback` function.\n */\n morris<C extends BTNCallback<N>>(\n callback: C = this._defaultOneParamCallback as C,\n pattern: DFSOrderPattern = 'in',\n beginRoot: BTNKeyOrNode<K, N> = this.root\n ): ReturnType<C>[] {\n beginRoot = this.ensureNode(beginRoot);\n if (beginRoot === null) return [];\n const ans: ReturnType<BTNCallback<N>>[] = [];\n\n let cur: N | null | undefined = beginRoot;\n const _reverseEdge = (node: N | null | undefined) => {\n let pre: N | null | undefined = null;\n let next: N | null | undefined = 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: N | null | undefined) => {\n const tail: N | null | undefined = _reverseEdge(node);\n let cur: N | null | undefined = 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\n /**\n * Time complexity: O(n)\n * Space complexity: O(n)\n *\n * The `clone` function creates a new tree object and copies all the nodes from the original tree to\n * the new tree.\n * @returns The `clone()` method is returning a cloned instance of the `TREE` object.\n */\n clone(): TREE {\n const cloned = this.createTree();\n this.bfs(node => cloned.add([node.key, node.value]));\n return cloned;\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 `filter` function creates a new tree by iterating over the elements of the current tree and\n * adding only the elements that satisfy the given predicate function.\n * @param predicate - The `predicate` parameter is a function that takes three arguments: `value`,\n * `key`, and `index`. It should return a boolean value indicating whether the pair should be\n * included in the filtered tree or not.\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 The `filter` method is returning a new tree object that contains the key-value pairs that\n * pass the given 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\n /**\n * Time Complexity: O(n)\n * Space Complexity: O(n)\n *\n * The `map` function creates a new tree by applying a callback function to each key-value pair in\n * the original tree.\n * @param callback - The callback parameter is a function that will be called for each key-value pair\n * in the tree. It takes four arguments: the value of the current pair, the key of the current pair,\n * the index of the current pair, and a reference to the tree itself. The callback function should\n * return a new\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 you pass a value for `thisArg`, it\n * will be used as the `this` value when the callback function is called. If you don't pass a value\n * @returns The `map` method is returning a new tree object.\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 * The `print` function is used to display a binary tree structure in a visually appealing way.\n * @param {K | N | null | undefined} [beginRoot=this.root] - The `root` parameter is of type `K | N | null |\n * undefined`. It represents the root node of a binary tree. The root node can have one of the\n * following types:\n * @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.\n */\n print(beginRoot: BTNKeyOrNode<K, N> = this.root, options?: BinaryTreePrintOptions): void {\n const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return;\n\n if (opts.isShowUndefined) console.log(`U for undefined\n `);\n if (opts.isShowNull) console.log(`N for null\n `);\n if (opts.isShowRedBlackNIL) console.log(`S for Sentinel Node\n `);\n\n const display = (root: N | null | undefined): void => {\n const [lines, , ,] = this._displayAux(root, opts);\n for (const line of lines) {\n console.log(line);\n }\n };\n\n display(beginRoot);\n }\n\n protected* _getIterator(node = this.root): IterableIterator<[K, V | undefined]> {\n if (!node) return;\n\n if (this.iterationType === IterationType.ITERATIVE) {\n const stack: (N | null | undefined)[] = [];\n let current: N | null | undefined = node;\n\n while (current || stack.length > 0) {\n while (current && !isNaN(this.extractor(current.key))) {\n stack.push(current);\n current = current.left;\n }\n\n current = stack.pop();\n\n if (current && !isNaN(this.extractor(current.key))) {\n yield [current.key, current.value];\n current = current.right;\n }\n }\n } else {\n if (node.left && !isNaN(this.extractor(node.key))) {\n yield* this[Symbol.iterator](node.left);\n }\n yield [node.key, node.value];\n if (node.right && !isNaN(this.extractor(node.key))) {\n yield* this[Symbol.iterator](node.right);\n }\n }\n }\n\n protected _displayAux(node: N | null | undefined, 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 (node !== null && node !== undefined && isNaN(this.extractor(node.key)) && !isShowRedBlackNIL) {\n return emptyDisplayLayout;\n } else if (node !== null && node !== undefined) {\n // Display logic of normal nodes\n\n const key = node.key, line = isNaN(this.extractor(key)) ? 'S' : this.extractor(key).toString(),\n width = line.length;\n\n return _buildNodeDisplay(line, width, this._displayAux(node.left, options), 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', 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 = ' '.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 = (leftHeight > 0 ? ' '.repeat(leftMiddle) + '/' + ' '.repeat(leftWidth - leftMiddle - 1) : ' '.repeat(leftWidth))\n + ' '.repeat(width)\n + (rightHeight > 0 ? ' '.repeat(rightMiddle) + '\\\\' + ' '.repeat(rightWidth - rightMiddle - 1) : ' '.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>[mergedLines, leftWidth + width + rightWidth, Math.max(leftHeight, rightHeight) + 2, leftWidth + Math.floor(width / 2)];\n }\n }\n\n protected _defaultOneParamCallback = (node: N | null | undefined) => node ? node.key : undefined;\n\n /**\n * Swap the data of two nodes in the binary tree.\n * @param {N} srcNode - The source node to swap.\n * @param {N} destNode - The destination node to swap.\n * @returns {N} - The destination node after the swap.\n */\n protected _swapProperties(srcNode: BTNKeyOrNode<K, N>, destNode: BTNKeyOrNode<K, N>): N | 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 * The function replaces an old node with a new node in a binary tree.\n * @param {N} oldNode - The oldNode parameter represents the node that needs to be replaced in the\n * tree.\n * @param {N} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the\n * tree.\n * @returns The method is returning the newNode.\n */\n protected _replaceNode(oldNode: N, newNode: N): N {\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._root = newNode;\n }\n\n return newNode;\n }\n\n /**\n * The function `_addTo` adds a new node to a binary tree if there is an available position.\n * @param {N | null | undefined} newNode - The `newNode` parameter represents the node that you want to add to\n * the binary tree. It can be either a node object or `null`.\n * @param {N} parent - The `parent` parameter represents the parent node to which the new node will\n * be added as a child.\n * @returns either the left or right child node of the parent node, depending on which child is\n * available for adding the new node. If a new node is added, the function also updates the size of\n * the binary tree. If neither the left nor right child is available, the function returns undefined.\n * If the parent node is null, the function also returns undefined.\n */\n protected _addTo(newNode: N | null | undefined, parent: BTNKeyOrNode<K, N>): N | null | undefined {\n if (this.isNotNodeInstance(parent)) parent = this.getNode(parent);\n\n if (parent) {\n // When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.\n // In this scenario, null nodes serve as \"sentinel nodes,\" \"virtual nodes,\" or \"placeholder nodes.\"\n if (parent.left === undefined) {\n parent.left = newNode;\n if (newNode) {\n this._size = this.size + 1;\n }\n return parent.left;\n } else if (parent.right === undefined) {\n parent.right = newNode;\n if (newNode) {\n this._size = this.size + 1;\n }\n return parent.right;\n } else {\n return;\n }\n } else {\n return;\n }\n }\n\n /**\n * The function sets the root property of an object to a given value, and if the value is not null,\n * it also sets the parent property of the value to undefined.\n * @param {N | null | undefined} v - The parameter `v` is of type `N | null | undefined`, which means it can either be of\n * type `N` or `null`.\n */\n protected _setRoot(v: N | null | undefined) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\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 {\n BSTNested,\n BSTNKeyOrNode,\n BSTNodeNested,\n BSTOptions,\n BTNCallback,\n BTNExemplar,\n BTNKeyOrNode,\n BTNodePureExemplar\n} from '../../types';\nimport { BSTVariant, CP, IterationType } from '../../types';\nimport { BinaryTree, BinaryTreeNode } from './binary-tree';\nimport { IBinaryTree } from '../../interfaces';\nimport { Queue } from '../queue';\n\nexport class BSTNode<K = any, V = any, N extends BSTNode<K, V, N> = BSTNodeNested<K, V>> extends BinaryTreeNode<K, V, N> {\n override parent?: N;\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?: N;\n\n /**\n * Get the left child node.\n */\n override get left(): N | undefined {\n return this._left;\n }\n\n /**\n * Set the left child node.\n * @param {N | undefined} v - The left child node.\n */\n override set left(v: N | undefined) {\n if (v) {\n v.parent = this as unknown as N;\n }\n this._left = v;\n }\n\n protected override _right?: N;\n\n /**\n * Get the right child node.\n */\n override get right(): N | undefined {\n return this._right;\n }\n\n /**\n * Set the right child node.\n * @param {N | undefined} v - The right child node.\n */\n override set right(v: N | undefined) {\n if (v) {\n v.parent = this as unknown as N;\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<K = any, V = any, N extends BSTNode<K, V, N> = BSTNode<K, V, BSTNodeNested<K, V>>, TREE extends BST<K, V, N, TREE> = BST<K, V, N, BSTNested<K, V, N>>>\n extends BinaryTree<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n\n\n /**\n * This is the constructor function for a binary search tree class in TypeScript, which initializes\n * the tree with optional elements and options.\n * @param [elements] - An optional iterable of BTNExemplar objects that will be added to the\n * binary search tree.\n * @param [options] - The `options` parameter is an optional object that can contain additional\n * configuration options for the binary search tree. It can have the following properties:\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<BSTOptions<K>>) {\n super([], options);\n\n if (options) {\n const { variant } = options;\n if (variant) {\n this._variant = variant;\n }\n }\n\n this._root = undefined;\n\n if (elements) this.addMany(elements);\n }\n\n protected override _root?: N;\n\n override get root(): N | undefined {\n return this._root;\n }\n\n protected _variant = BSTVariant.MIN\n\n get variant() {\n return this._variant;\n }\n\n /**\n * The function creates a new binary search tree node with the given key and value.\n * @param {K} key - The key parameter is the key value that will be associated with\n * the new node. It is used to determine the position of the node in the binary search tree.\n * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It\n * represents the value associated with the node in a binary search tree.\n * @returns a new instance of the BSTNode class with the specified key and value.\n */\n override createNode(key: K, value?: V): N {\n return new BSTNode<K, V, N>(key, value) as N;\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 is a type\n * that defines various options for creating a binary search tree.\n * @returns a new instance of the BST class with the specified options.\n */\n override createTree(options?: Partial<BSTOptions<K>>): TREE {\n return new BST<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of BSTNode.\n * @param exemplar - The `exemplar` parameter is a variable of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the BSTNode class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof BSTNode;\n }\n\n\n /**\n * The function `exemplarToNode` takes an exemplar and returns a node if the exemplar is valid,\n * otherwise it returns undefined.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`, where:\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `exemplarToNode` function. It represents the value associated with the exemplar node.\n * @returns a node of type N or undefined.\n */\n override exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V): N | undefined {\n let node: N | undefined;\n if (exemplar === null || exemplar === undefined) {\n return;\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined || key === null) {\n return;\n } else {\n node = this.createNode(key, value);\n }\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).\n * Space Complexity: O(1) - Constant space is used.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. In the worst case (unbalanced tree), it can be O(n).\n * Space Complexity: O(1) - Constant space is used.\n *\n * The `add` function adds a new node to a binary tree, updating the value if the key already exists\n * or inserting a new node if the key is unique.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can accept three types of values:\n * @param {V} [value] - The `value` parameter represents the value associated with the key that is\n * being added to the binary tree.\n * @returns The method `add` returns either the newly added node (`newNode`) or `undefined` if the\n * node was not added.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);\n if (newNode === undefined) return;\n\n if (this.root === undefined) {\n this._setRoot(newNode);\n this._size++;\n return this.root;\n }\n\n let current = this.root;\n while (current !== undefined) {\n if (this._compare(current.key, newNode.key) === CP.eq) {\n // if (current !== newNode) {\n // The key value is the same but the reference is different, update the value of the existing node\n this._replaceNode(current, newNode);\n return newNode;\n\n // } else {\n // The key value is the same and the reference is the same, replace the entire node\n // this._replaceNode(current, newNode);\n\n // return;\n // }\n } else if (this._compare(current.key, newNode.key) === CP.gt) {\n if (current.left === undefined) {\n current.left = newNode;\n newNode.parent = current;\n this._size++;\n return newNode;\n }\n current = current.left;\n } else {\n if (current.right === undefined) {\n current.right = newNode;\n newNode.parent = current;\n this._size++;\n return newNode;\n }\n current = current.right;\n }\n }\n\n return undefined;\n }\n\n /**\n * Time Complexity: O(k log n) - Adding each element individually in a balanced tree.\n * Space Complexity: O(k) - Additional space is required for the sorted array.\n */\n\n /**\n * Time Complexity: O(k log n) - Adding each element individually in a balanced tree.\n * Space Complexity: O(k) - Additional space is required for the sorted array.\n *\n * The `addMany` function in TypeScript adds multiple keys or nodes to a binary tree, optionally\n * balancing the tree after each addition.\n * @param keysOrNodesOrEntries - An iterable containing the keys, nodes, or entries to be added to\n * the binary tree.\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 add operation should be\n * balanced or not. If set to true, the add operation will be balanced using a binary search tree\n * algorithm. If set to false, the add operation will not be balanced and the elements will be added\n * in the order they appear in the input.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when adding multiple keys or nodes. It has a default value of\n * `this.iterationType`, which suggests that it is a property of the current object.\n * @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.\n */\n override addMany(\n keysOrNodesOrEntries: Iterable<BTNExemplar<K, V, N>>,\n values?: Iterable<V | undefined>,\n isBalanceAdd = true,\n iterationType = this.iterationType\n ): (N | undefined)[] {\n const inserted: (N | undefined)[] = [];\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 keysOrNodesOrEntries) {\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: BTNodePureExemplar<K, V, N>[] = [];\n\n const isRealBTNExemplar = (kve: BTNExemplar<K, V, N>): kve is BTNodePureExemplar<K, V, N> => {\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 keysOrNodesOrEntries) {\n isRealBTNExemplar(kve) && realBTNExemplars.push(kve);\n }\n\n let sorted: BTNodePureExemplar<K, V, N>[] = [];\n\n sorted = realBTNExemplars.sort((a, b) => {\n let aR: number, bR: number;\n if (this.isEntry(a)) aR = this.extractor(a[0]);\n else if (this.isRealNode(a)) aR = this.extractor(a.key);\n else aR = this.extractor(a);\n\n if (this.isEntry(b)) bR = this.extractor(b[0]);\n else if (this.isRealNode(b)) bR = this.extractor(b.key);\n else bR = this.extractor(b);\n\n return aR - bR;\n });\n\n const _dfs = (arr: BTNodePureExemplar<K, V, N>[]) => {\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 === IterationType.RECURSIVE) {\n _dfs(sorted);\n } else {\n _iterate();\n }\n\n return inserted;\n }\n\n\n /**\n * Time Complexity: O(n log n) - Adding each element individually in a balanced tree.\n * Space Complexity: O(n) - Additional space is required for the sorted array.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(1) - Constant space is used.\n *\n * The `lastKey` function returns the key of the rightmost node in a binary tree, or the key of the\n * leftmost node if the comparison result is greater than.\n * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is optional and can be of\n * type `K`, `N`, or `undefined`. It represents the starting point for finding the last key in\n * the binary tree. If not provided, it defaults to the root of the binary tree (`this.root`).\n * @param iterationType - The `iterationType` parameter is used to specify the type of iteration to\n * be performed. It can have one of the following values:\n * @returns the key of the rightmost node in the binary tree if the comparison result is less than,\n * the key of the leftmost node if the comparison result is greater than, and the key of the\n * rightmost node otherwise. If no node is found, it returns 0.\n */\n lastKey(beginRoot: BSTNKeyOrNode<K, N> = this.root): K | undefined {\n let current = this.ensureNode(beginRoot);\n if (!current) return undefined;\n\n if (this._variant === BSTVariant.MIN) {\n // For BSTVariant.MIN, find the rightmost node\n while (current.right !== undefined) {\n current = current.right;\n }\n } else {\n // For BSTVariant.MAX, find the leftmost node\n while (current.left !== undefined) {\n current = current.left;\n }\n }\n return current.key;\n }\n\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(1) - Constant space is used.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The function `getNodeByKey` searches for a node in a binary tree based on a given key, using\n * either recursive or iterative methods.\n * @param {K} key - The `key` parameter is the key value that we are searching for in the tree.\n * It is used to identify the node that we want to retrieve.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when searching for a node in the binary tree. It can have two possible\n * values:\n * @returns The function `getNodeByKey` returns a node (`N`) if a node with the specified key is\n * found in the binary tree. If no node is found, it returns `undefined`.\n */\n override getNodeByKey(key: K, iterationType = IterationType.ITERATIVE): N | undefined {\n if (!this.root) return undefined;\n if (iterationType === IterationType.RECURSIVE) {\n const _dfs = (cur: N): N | undefined => {\n if (cur.key === key) return cur;\n if (!cur.left && !cur.right) return;\n\n if (this._compare(cur.key, key) === CP.gt && cur.left) return _dfs(cur.left);\n if (this._compare(cur.key, key) === CP.lt && cur.right) return _dfs(cur.right);\n };\n\n return _dfs(this.root);\n } else {\n const queue = new Queue<N>([this.root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n if (this._compare(cur.key, key) === CP.eq) return cur;\n if (this._compare(cur.key, key) === CP.gt) cur.left && queue.push(cur.left);\n if (this._compare(cur.key, key) === CP.lt) cur.right && queue.push(cur.right);\n }\n }\n }\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof BSTNode)\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n */\n\n /**\n * The function `ensureNode` returns the node corresponding to the given key if it is a node key,\n * otherwise it returns the key itself.\n * @param {K | N | undefined} key - The `key` parameter can be of type `K`, `N`, or\n * `undefined`.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.\n * @returns either a node object (N) or undefined.\n */\n override ensureNode(key: BSTNKeyOrNode<K, N>, iterationType = IterationType.ITERATIVE): N | undefined {\n return this.isNotNodeInstance(key) ? this.getNodeByKey(key, iterationType) : key;\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The function `getNodes` returns an array of nodes that match a given identifier, using either a\n * recursive or iterative approach.\n * @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you\n * want to search for in the nodes of the binary tree. It can be of any type that is returned by the\n * callback function `C`.\n * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` as its\n * argument and returns a value of type `ReturnType<C>`. The `C` type parameter represents a callback\n * function type that extends the `BTNCallback<N>` type. The `BTNCallback<N>` type is\n * @param [onlyOne=false] - A boolean flag indicating whether to stop searching after finding the\n * first node that matches the identifier. If set to true, the function will return an array\n * containing only the first matching node. If set to false (default), the function will continue\n * searching for all nodes that match the identifier and return an array containing\n * @param {K | N | undefined} beginRoot - The `beginRoot` parameter represents the starting node\n * for the traversal. It can be either a key value or a node object. If it is undefined, the\n * traversal will start from the root of the tree.\n * @param iterationType - The `iterationType` parameter determines the type of iteration to be\n * performed on the binary tree. It can have two possible values:\n * @returns The method returns an array of nodes (`N[]`).\n */\n override getNodes<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | undefined,\n callback: C = this._defaultOneParamCallback as C,\n onlyOne = false,\n beginRoot: BSTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N[] {\n beginRoot = this.ensureNode(beginRoot);\n if (!beginRoot) return [];\n const ans: N[] = [];\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N) => {\n const callbackResult = callback(cur);\n if (callbackResult === identifier) {\n ans.push(cur);\n if (onlyOne) return;\n }\n\n if (!cur.left && !cur.right) return;\n // TODO potential bug\n if (callback === this._defaultOneParamCallback) {\n if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && _traverse(cur.left);\n if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && _traverse(cur.right);\n } else {\n cur.left && _traverse(cur.left);\n cur.right && _traverse(cur.right);\n }\n };\n\n _traverse(beginRoot);\n } else {\n const queue = new Queue<N>([beginRoot]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n const callbackResult = callback(cur);\n if (callbackResult === identifier) {\n ans.push(cur);\n if (onlyOne) return ans;\n }\n // TODO potential bug\n if (callback === this._defaultOneParamCallback) {\n if (this._compare(cur.key, identifier as K) === CP.gt) cur.left && queue.push(cur.left);\n if (this._compare(cur.key, identifier as K) === CP.lt) cur.right && queue.push(cur.right);\n } else {\n cur.left && queue.push(cur.left);\n cur.right && queue.push(cur.right);\n }\n }\n }\n }\n\n return ans;\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n */\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The `lesserOrGreaterTraverse` function traverses a binary tree and returns an array of nodes that\n * are either lesser or greater than a target node, depending on the specified comparison type.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * that satisfies the condition specified by the `lesserOrGreater` parameter. It takes a single\n * parameter of type `N` (the node type) 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 than, greater than, or equal to the `targetNode`. It is of type\n * `CP`, which is a custom type representing the comparison operator. The possible values for\n * `lesserOrGreater` are\n * @param {K | N | undefined} targetNode - The `targetNode` parameter represents the node in the\n * binary tree that you want to traverse from. It can be specified either by its key, by the node\n * object itself, or it can be left undefined to start the traversal from the root of the tree.\n * @param iterationType - The `iterationType` parameter determines the type of traversal to be\n * 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<N>>(\n callback: C = this._defaultOneParamCallback as C,\n lesserOrGreater: CP = CP.lt,\n targetNode: BSTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): ReturnType<C>[] {\n targetNode = this.ensureNode(targetNode);\n const ans: ReturnType<BTNCallback<N>>[] = [];\n if (!targetNode) return ans;\n if (!this.root) return ans;\n\n const targetKey = targetNode.key;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _traverse = (cur: N) => {\n const compared = this._compare(cur.key, targetKey);\n if (compared === lesserOrGreater) ans.push(callback(cur));\n\n if (!cur.left && !cur.right) return;\n if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) _traverse(cur.left);\n if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) _traverse(cur.right);\n };\n\n _traverse(this.root);\n return ans;\n } else {\n const queue = new Queue<N>([this.root]);\n while (queue.size > 0) {\n const cur = queue.shift();\n if (cur) {\n const compared = this._compare(cur.key, targetKey);\n if (compared === lesserOrGreater) ans.push(callback(cur));\n\n if (cur.left && this._compare(cur.left.key, targetKey) === lesserOrGreater) queue.push(cur.left);\n if (cur.right && this._compare(cur.right.key, targetKey) === lesserOrGreater) queue.push(cur.right);\n }\n }\n return ans;\n }\n }\n\n /**\n * Time Complexity: O(log n) - Average case for a balanced tree. O(n) - Visiting each node once when identifier is not node's key.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n */\n\n /**\n * Time Complexity: O(n) - Building a balanced tree from a sorted array.\n * Space Complexity: O(n) - Additional space is required for the sorted array.\n *\n * The `perfectlyBalance` function balances a binary search tree by adding nodes in a way that\n * ensures the tree is perfectly balanced.\n * @param iterationType - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when building a balanced binary search tree. It can have two possible\n * values:\n * @returns The function `perfectlyBalance` returns a boolean value.\n */\n perfectlyBalance(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 === 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 * Balancing Adjustment:\n * Perfectly Balanced Binary Tree: Since the balance of a perfectly balanced binary tree is already fixed, no additional balancing adjustment is needed. Any insertion or deletion operation will disrupt the perfect balance, often requiring a complete reconstruction of the tree.\n * AVL Tree: After insertion or deletion operations, an AVL tree performs rotation adjustments based on the balance factor of nodes to restore the tree's balance. These rotations can be left rotations, right rotations, left-right rotations, or right-left rotations, performed as needed.\n *\n * Use Cases and Efficiency:\n * Perfectly Balanced Binary Tree: Perfectly balanced binary trees are typically used in specific scenarios such as complete binary heaps in heap sort or certain types of Huffman trees. However, they are not suitable for dynamic operations requiring frequent insertions and deletions, as these operations often necessitate full tree reconstruction.\n * AVL Tree: AVL trees are well-suited for scenarios involving frequent searching, insertion, and deletion operations. Through rotation adjustments, AVL trees maintain their balance, ensuring average and worst-case time complexity of O(log n).\n */\n\n /**\n * Time Complexity: O(n) - Building a balanced tree from a sorted array.\n * Space Complexity: O(n) - Additional space is required for the sorted array.\n */\n\n /**\n * Time Complexity: O(n) - Visiting each node once.\n * Space Complexity: O(log n) - Space for the recursive call stack in the worst case.\n *\n * The function checks if a binary tree is AVL balanced using either recursive or iterative approach.\n * @param iterationType - The `iterationType` parameter is used to determine the method of iteration\n * to check if the AVL tree is balanced. It can have two possible values:\n * @returns a boolean value.\n */\n isAVLBalanced(iterationType = this.iterationType): boolean {\n if (!this.root) return true;\n\n let balanced = true;\n\n if (iterationType === IterationType.RECURSIVE) {\n const _height = (cur: N | undefined): 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: N[] = [];\n let node: N | undefined = this.root,\n last: N | undefined = undefined;\n const depths: Map<N, 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 : -1;\n const right = node.right ? depths.get(node.right) ?? -1 : -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\n protected _setRoot(v: N | undefined) {\n if (v) {\n v.parent = undefined;\n }\n this._root = v;\n }\n\n /**\n * The function compares two values using a comparator function and returns whether the first value\n * is greater than, less than, or equal to the second value.\n * @param {K} a - The parameter \"a\" is of type K.\n * @param {K} b - The parameter \"b\" in the above code represents a K.\n * @returns a value of type CP (ComparisonResult). The possible return values are CP.gt (greater\n * than), CP.lt (less than), or CP.eq (equal).\n */\n protected _compare(a: K, b: K): CP {\n const extractedA = this.extractor(a);\n const extractedB = this.extractor(b);\n const compared = this.variant === BSTVariant.MIN ? extractedA - extractedB : extractedB - extractedA;\n\n return compared > 0 ? CP.gt : compared < 0 ? CP.lt : CP.eq;\n }\n\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 { 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 get freqMap(): Record<number, number> {\n return this._freqMap;\n }\n\n protected _msb: number;\n\n get msb(): number {\n return this._msb;\n }\n\n protected _negativeCount: number;\n\n get negativeCount(): number {\n return this._negativeCount;\n }\n\n get freq(): number {\n return this._freq;\n }\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>\n * @license MIT License\n */\n\nimport type { SegmentTreeNodeVal } from '../../types';\n\nexport class SegmentTreeNode {\n start = 0;\n end = 0;\n value: SegmentTreeNodeVal | undefined = undefined;\n sum = 0;\n left: SegmentTreeNode | undefined = undefined;\n right: SegmentTreeNode | undefined = undefined;\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\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 get values(): number[] {\n return this._values;\n }\n\n protected _start = 0;\n\n get start(): number {\n return this._start;\n }\n\n protected _end: number;\n\n get end(): number {\n return this._end;\n }\n\n protected _root: SegmentTreeNode | undefined;\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 Tyler Zeng\n * @copyright Copyright (c) 2022 Tyler 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 BTNCallback,\n BTNExemplar,\n BTNKeyOrNode\n} from '../../types';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class AVLTreeNode<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNodeNested<K, V>> extends BSTNode<K, V, N> {\n height: number;\n\n constructor(key: K, value?: V) {\n super(key, value);\n this.height = 0;\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<K = any, V = any, N extends AVLTreeNode<K, V, N> = AVLTreeNode<K, V, AVLTreeNodeNested<K, V>>, TREE extends AVLTree<K, V, N, TREE> = AVLTree<K, V, N, AVLTreeNested<K, V, N>>>\n extends BST<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n\n /**\n * The constructor function initializes an AVLTree object with optional elements and options.\n * @param [elements] - The `elements` parameter is an optional iterable of `BTNExemplar<K, V, N>`\n * objects. It represents a collection of elements that will be added to the AVL tree during\n * initialization.\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the AVL tree. It is of type `Partial<AVLTreeOptions>`, which means that you can\n * provide only a subset of the properties defined in the `AVLTreeOptions` interface.\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<AVLTreeOptions<K>>) {\n super([], options);\n if (elements) super.addMany(elements);\n }\n\n /**\n * The function creates a new AVL tree node with the specified key and value.\n * @param {K} key - The key parameter is the key value that will be associated with\n * the new node. It is used to determine the position of the node in the binary search tree.\n * @param [value] - The parameter `value` is an optional value that can be assigned to the node. It is of\n * type `V`, which means it can be any value that is assignable to the `value` property of the\n * node type `N`.\n * @returns a new AVLTreeNode object with the specified key and value.\n */\n override createNode(key: K, value?: V): N {\n return new AVLTreeNode<K, V, N>(key, value) as N;\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>): TREE {\n return new AVLTree<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of AVLTreeNode.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the AVLTreeNode class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof AVLTreeNode;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof AVLTreeNode)\n }\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the add method of a binary tree node and balances the tree after inserting\n * a new node.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an\n * entry.\n * @param {V} [value] - The `value` parameter represents the value associated with the key that is\n * being added to the binary tree.\n * @returns The method is returning either the inserted node or undefined.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | undefined {\n if (keyOrNodeOrEntry === null) return undefined;\n const inserted = super.add(keyOrNodeOrEntry, value);\n if (inserted) this._balancePath(inserted);\n return inserted;\n }\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The delete method of the superclass (BST) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the delete method of a binary tree, performs the deletion, and then\n * balances the tree if necessary.\n * @param identifier - The `identifier` parameter is the value or condition used to identify the\n * node(s) to be deleted from the binary tree. It can be of any type and is the return type of the\n * `callback` function.\n * @param {C} callback - The `callback` parameter is a function that will be called for each node\n * that is deleted from the binary tree. It is an optional parameter and if not provided, it will\n * default to the `_defaultOneParamCallback` function. The `callback` function should have a single\n * parameter of type `N\n * @returns The method is returning an array of `BinaryTreeDeleteResult<N>`.\n */\n override delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C = this._defaultOneParamCallback as C\n ): BinaryTreeDeleteResult<N>[] {\n if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;\n const deletedResults = super.delete(identifier, callback);\n for (const { needBalanced } of deletedResults) {\n if (needBalanced) {\n this._balancePath(needBalanced);\n }\n }\n return deletedResults;\n }\n\n\n /**\n * The `_swapProperties` function swaps the key, value, and height properties between two nodes in a binary\n * tree.\n * @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node that\n * needs to be swapped with the destination node. It can be of type `K`, `N`, or `undefined`.\n * @param {K | N | undefined} destNode - The `destNode` parameter represents the destination\n * node where the values from the source node will be swapped to.\n * @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`\n * if either `srcNode` or `destNode` is undefined.\n */\n protected override _swapProperties(srcNode: BSTNKeyOrNode<K, N>, destNode: BSTNKeyOrNode<K, N>): N | undefined {\n srcNode = this.ensureNode(srcNode);\n destNode = this.ensureNode(destNode);\n\n if (srcNode && destNode) {\n const { key, value, height } = destNode;\n const tempNode = this.createNode(key, value);\n\n if (tempNode) {\n tempNode.height = height;\n\n destNode.key = srcNode.key;\n destNode.value = srcNode.value;\n destNode.height = srcNode.height;\n\n srcNode.key = tempNode.key;\n srcNode.value = tempNode.value;\n srcNode.height = tempNode.height;\n }\n\n return destNode;\n }\n return undefined;\n }\n\n /**\n * Time Complexity: O(1) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n *\n * The function calculates the balance factor of a node in a binary tree.\n * @param {N} node - The parameter \"node\" represents a node in a 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: N): 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) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as it performs a fixed number of operations.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\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 {N} node - The parameter \"node\" represents a node in a binary tree data structure.\n */\n protected _updateHeight(node: N): 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(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The method traverses the path from the inserted node to the root.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The method traverses the path from the inserted node to the root.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\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 {N} node - The `node` parameter in the `_balancePath` function represents the node in the\n * AVL tree that needs to be balanced.\n */\n protected _balancePath(node: N): void {\n const path = this.getPathToRoot(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 // 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 * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The function `_balanceLL` performs a left-left rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceLL(A: N): 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) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The `_balanceLR` function performs a left-right rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceLR(A: N): 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 B && this._updateHeight(B);\n C && this._updateHeight(C);\n }\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The function `_balanceRR` performs a right-right rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceRR(A: N): 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 B && this._updateHeight(B);\n }\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(1) - constant time, as these methods perform a fixed number of operations.\n * Space Complexity: O(1) - constant space, as they only use a constant amount of memory.\n *\n * The function `_balanceRL` performs a right-left rotation to balance a binary tree.\n * @param {N} A - A is a node in a binary tree.\n */\n protected _balanceRL(A: N): 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 B && this._updateHeight(B);\n C && this._updateHeight(C);\n }\n\n protected _replaceNode(oldNode: N, newNode: N): N {\n newNode.height = oldNode.height;\n\n return super._replaceNode(oldNode, newNode)\n }\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 */\n\nimport {\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNCallback,\n BTNExemplar,\n BTNKeyOrNode,\n IterationType,\n RBTNColor,\n RBTreeOptions,\n RedBlackTreeNested,\n RedBlackTreeNodeNested\n} from '../../types';\nimport { BST, BSTNode } from './bst';\nimport { IBinaryTree } from '../../interfaces';\n\nexport class RedBlackTreeNode<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNodeNested<K, V>> extends BSTNode<\n K, V,\n N\n> {\n color: RBTNColor;\n\n constructor(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK) {\n super(key, value);\n this.color = color;\n }\n}\n\n/**\n * 1. Each node is either red or black.\n * 2. The root node is always black.\n * 3. Leaf nodes are typically Sentinel nodes and are considered black.\n * 4. Red nodes must have black children.\n * 5. Black balance: Every path from any node to each of its leaf nodes contains the same number of black nodes.\n */\nexport class RedBlackTree<K = any, V = any, N extends RedBlackTreeNode<K, V, N> = RedBlackTreeNode<K, V, RedBlackTreeNodeNested<K, V>>, TREE extends RedBlackTree<K, V, N, TREE> = RedBlackTree<K, V, N, RedBlackTreeNested<K, V, N>>>\n extends BST<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n Sentinel: N = new RedBlackTreeNode<K, V>(NaN as K) as unknown as N;\n\n /**\n * This is the constructor function for a Red-Black Tree data structure in TypeScript, which\n * initializes the tree with optional elements and options.\n * @param [elements] - The `elements` parameter is an optional iterable of `BTNExemplar<K, V, N>`\n * objects. It represents the initial elements that will be added to the RBTree during its\n * construction. If this parameter is provided, the `addMany` method is called to add all the\n * elements to the\n * @param [options] - The `options` parameter is an optional object that allows you to customize the\n * behavior of the RBTree. It is of type `Partial<RBTreeOptions>`, which means that you can provide\n * only a subset of the properties defined in the `RBTreeOptions` interface.\n */\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<RBTreeOptions<K>>) {\n super([], options);\n\n this._root = this.Sentinel;\n if (elements) super.addMany(elements);\n }\n\n protected _root: N;\n\n get root(): N {\n return this._root;\n }\n\n protected _size: number = 0;\n\n get size(): number {\n return this._size;\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 is the key value associated with the node. It is used to\n * identify and compare nodes in the Red-Black Tree.\n * @param {V} [value] - The `value` parameter is an optional parameter that represents the value\n * associated with the node. It is of type `V`, which is a generic type that can be replaced with any\n * specific type when using the `createNode` method.\n * @param {RBTNColor} color - The \"color\" parameter is used to specify the color of the node in a\n * Red-Black Tree. It can be either \"RED\" or \"BLACK\". By default, the color is set to \"BLACK\".\n * @returns The method is returning a new instance of a RedBlackTreeNode with the specified key,\n * value, and color.\n */\n override createNode(key: K, value?: V, color: RBTNColor = RBTNColor.BLACK): N {\n return new RedBlackTreeNode<K, V, N>(key, value, color) as N;\n }\n\n /**\n * The function creates a Red-Black Tree with the specified options and returns it.\n * @param {RBTreeOptions} [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 `RedBlackTree`\n * class.\n * @returns a new instance of a RedBlackTree object.\n */\n override createTree(options?: RBTreeOptions<K>): TREE {\n return new RedBlackTree<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of the RedBlackTreeNode class.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the RedBlackTreeNode\n * class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof RedBlackTreeNode;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof RedBlackTreeNode)\n }\n\n /**\n * The function `exemplarToNode` takes an exemplar and converts it into a node object if possible.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`, where:\n * @param {V} [value] - The `value` parameter is an optional value that can be passed to the\n * `exemplarToNode` function. It represents the value associated with the exemplar node. If a value\n * is provided, it will be used when creating the new node. If no value is provided, the new node\n * @returns a node of type N or undefined.\n */\n override exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V): N | undefined {\n let node: N | undefined;\n\n if (exemplar === null || exemplar === undefined) {\n return;\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined || key === null) {\n return;\n } else {\n node = this.createNode(key, value, RBTNColor.RED);\n }\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value, RBTNColor.RED);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The `add` function adds a new node to a binary search tree and performs necessary rotations and\n * color changes to maintain the red-black tree properties.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an\n * entry.\n * @param {V} [value] - The `value` parameter represents the value associated with the key that is\n * being added to the binary search tree.\n * @returns The method `add` returns either the newly added node (`N`) or `undefined`.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V): N | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value);\n if (newNode === undefined) return;\n\n newNode.left = this.Sentinel;\n newNode.right = this.Sentinel;\n\n let y: N | undefined = undefined;\n let x: N | undefined = this.root;\n\n while (x !== this.Sentinel) {\n y = x;\n if (x) {\n if (newNode.key < x.key) {\n x = x.left;\n } else if (newNode.key > x.key) {\n x = x?.right;\n } else {\n if (newNode !== x) {\n this._replaceNode(x, newNode)\n }\n return;\n }\n }\n\n }\n\n newNode.parent = y;\n if (y === undefined) {\n this._setRoot(newNode);\n } else if (newNode.key < y.key) {\n y.left = newNode;\n } else {\n y.right = newNode;\n }\n\n if (newNode.parent === undefined) {\n newNode.color = RBTNColor.BLACK;\n this._size++;\n return;\n }\n\n if (newNode.parent.parent === undefined) {\n this._size++;\n return;\n }\n\n this._fixInsert(newNode);\n this._size++;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The `delete` function removes a node from a binary tree based on a given identifier and updates\n * the tree accordingly.\n * @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value\n * that you want to use to identify the node that you want to delete from the binary tree. It can be\n * of any type that is returned by the callback function `C`. It can also be `null` or `undefined` if\n * you don't want to\n * @param {C} callback - The `callback` parameter is a function that takes a node of type `N` and\n * returns a value of type `ReturnType<C>`. It is used to determine if a node should be deleted based\n * on its identifier. The `callback` function is optional and defaults to `this._defaultOneParam\n * @returns an array of `BinaryTreeDeleteResult<N>`.\n */\n delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | null | undefined,\n callback: C = this._defaultOneParamCallback as C\n ): BinaryTreeDeleteResult<N>[] {\n const ans: BinaryTreeDeleteResult<N>[] = [];\n if (identifier === null) return ans;\n const helper = (node: N | undefined): void => {\n let z: N = this.Sentinel;\n let x: N | undefined, y: N;\n while (node !== this.Sentinel) {\n if (node && callback(node) === identifier) {\n z = node;\n }\n\n if (node && identifier && callback(node) <= identifier) {\n node = node.right;\n } else {\n node = node?.left;\n }\n }\n\n if (z === this.Sentinel) {\n this._size--;\n return;\n }\n\n y = z;\n let yOriginalColor: number = y.color;\n if (z.left === this.Sentinel) {\n x = z.right;\n this._rbTransplant(z, z.right!);\n } else if (z.right === this.Sentinel) {\n x = z.left;\n this._rbTransplant(z, z.left!);\n } else {\n y = this.getLeftMost(z.right)!;\n yOriginalColor = y.color;\n x = y.right;\n if (y.parent === z) {\n x!.parent = y;\n } else {\n this._rbTransplant(y, y.right!);\n y.right = z.right;\n y.right!.parent = y;\n }\n\n this._rbTransplant(z, y);\n y.left = z.left;\n y.left!.parent = y;\n y.color = z.color;\n }\n if (yOriginalColor === RBTNColor.BLACK) {\n this._fixDelete(x!);\n }\n this._size--;\n };\n helper(this.root);\n // TODO\n return ans;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n override isRealNode(node: N | undefined): node is N {\n if (node === this.Sentinel || node === undefined) return false;\n return node instanceof RedBlackTreeNode;\n }\n\n getNode<C extends BTNCallback<N, K>>(\n identifier: K,\n callback?: C,\n beginRoot?: N | undefined,\n iterationType?: IterationType\n ): N | undefined;\n\n getNode<C extends BTNCallback<N, N>>(\n identifier: N | undefined,\n callback?: C,\n beginRoot?: N | undefined,\n iterationType?: IterationType\n ): N | undefined;\n\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C,\n beginRoot?: N | undefined,\n iterationType?: IterationType\n ): N | undefined;\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The function `getNode` retrieves a single node from a binary tree based on a given identifier and\n * callback function.\n * @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value used to\n * identify the node you want to retrieve. It can be of any type that is the return type of the `C`\n * callback function. If the `identifier` is `undefined`, it means you want to retrieve the first\n * node that matches the other criteria\n * @param {C} callback - The `callback` parameter is a function that will be called for each node in\n * the binary tree. It is used to determine if a node matches the given identifier. The `callback`\n * function should take a single parameter of type `N` (the type of the nodes in the binary tree) and\n * @param {K | N | undefined} beginRoot - The `beginRoot` parameter is the starting point for\n * searching for a node in a binary tree. It can be either a key value or a node object. If it is not\n * provided, the search will start from the root of the binary tree.\n * @param iterationType - The `iterationType` parameter is a variable that determines the type of\n * iteration to be performed when searching for nodes in the binary tree. It is used in the\n * `getNodes` method, which is called within the `getNode` method.\n * @returns a value of type `N`, `null`, or `undefined`.\n */\n getNode<C extends BTNCallback<N>>(\n identifier: ReturnType<C> | undefined,\n callback: C = this._defaultOneParamCallback as C,\n beginRoot: BSTNKeyOrNode<K, N> = this.root,\n iterationType = this.iterationType\n ): N | null | undefined {\n if ((identifier as any) instanceof RedBlackTreeNode) callback = (node => node) as C;\n beginRoot = this.ensureNode(beginRoot);\n return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;\n }\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n)\n * Space Complexity: O(1)\n *\n * The function returns the predecessor of a given node in a red-black tree.\n * @param {RedBlackTreeNode} x - The parameter `x` is of type `RedBlackTreeNode`, which represents a node in a\n * Red-Black Tree.\n * @returns the predecessor of the given RedBlackTreeNode 'x'.\n */\n override getPredecessor(x: N): N {\n if (this.isRealNode(x.left)) {\n return this.getRightMost(x.left)!;\n }\n\n let y: N | undefined = x.parent;\n while (this.isRealNode(y) && x === y.left) {\n x = y!;\n y = y!.parent;\n }\n\n return y!;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n override clear() {\n this._root = this.Sentinel;\n this._size = 0;\n }\n\n protected override _setRoot(v: N) {\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\n /**\n * Time Complexity: O(1)\n * Space Complexity: O(1)\n *\n * The function performs a left rotation on a binary tree node.\n * @param {RedBlackTreeNode} x - The parameter `x` is of type `N`, which likely represents a node in a binary tree.\n */\n protected _leftRotate(x: N): void {\n if (x.right) {\n const y: N = x.right;\n x.right = y.left;\n if (y.left !== this.Sentinel) {\n if (y.left) y.left.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === undefined) {\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 y.left = x;\n x.parent = y;\n }\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 performs a right rotation on a red-black tree node.\n * @param {RedBlackTreeNode} x - x is a RedBlackTreeNode, which represents the node that needs to be right\n * rotated.\n */\n protected _rightRotate(x: N): void {\n if (x.left) {\n const y: N = x.left;\n x.left = y.right;\n if (y.right !== this.Sentinel) {\n if (y.right) y.right.parent = x;\n }\n y.parent = x.parent;\n if (x.parent === undefined) {\n this._setRoot(y);\n } else if (x === x.parent.right) {\n x.parent.right = y;\n } else {\n x.parent.left = y;\n }\n y.right = x;\n x.parent = y;\n }\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The function `_fixDelete` is used to fix the red-black tree after a node deletion.\n * @param {RedBlackTreeNode} x - The parameter `x` represents a node in a Red-Black Tree (RBT).\n */\n protected _fixDelete(x: N): void {\n let s: N | undefined;\n while (x !== this.root && x.color === RBTNColor.BLACK) {\n if (x.parent && x === x.parent.left) {\n s = x.parent.right!;\n if (s.color === 1) {\n s.color = RBTNColor.BLACK;\n x.parent.color = RBTNColor.RED;\n this._leftRotate(x.parent);\n s = x.parent.right!;\n }\n\n if (s.left !== undefined && s.left.color === RBTNColor.BLACK && s.right && s.right.color === RBTNColor.BLACK) {\n s.color = RBTNColor.RED;\n x = x.parent;\n } else {\n if (s.right && s.right.color === RBTNColor.BLACK) {\n if (s.left) s.left.color = RBTNColor.BLACK;\n s.color = RBTNColor.RED;\n this._rightRotate(s);\n s = x.parent.right;\n }\n\n if (s) s.color = x.parent.color;\n x.parent.color = RBTNColor.BLACK;\n if (s && s.right) s.right.color = RBTNColor.BLACK;\n this._leftRotate(x.parent);\n x = this.root;\n }\n } else {\n s = x.parent!.left!;\n if (s.color === 1) {\n s.color = RBTNColor.BLACK;\n x.parent!.color = RBTNColor.RED;\n this._rightRotate(x.parent!);\n s = x.parent!.left;\n }\n\n if (s && s.right && s.right.color === RBTNColor.BLACK && s.right.color === RBTNColor.BLACK) {\n s.color = RBTNColor.RED;\n x = x.parent!;\n } else {\n if (s && s.left && s.left.color === RBTNColor.BLACK) {\n if (s.right) s.right.color = RBTNColor.BLACK;\n s.color = RBTNColor.RED;\n this._leftRotate(s);\n s = x.parent!.left;\n }\n\n if (s) s.color = x.parent!.color;\n x.parent!.color = RBTNColor.BLACK;\n if (s && s.left) s.left.color = RBTNColor.BLACK;\n this._rightRotate(x.parent!);\n x = this.root;\n }\n }\n }\n x.color = RBTNColor.BLACK;\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 `_rbTransplant` replaces one node in a red-black tree with another node.\n * @param {RedBlackTreeNode} u - The parameter \"u\" represents a RedBlackTreeNode object.\n * @param {RedBlackTreeNode} v - The parameter \"v\" is a RedBlackTreeNode object.\n */\n protected _rbTransplant(u: N, v: N): void {\n if (u.parent === undefined) {\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 v.parent = u.parent;\n }\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n */\n\n /**\n * Time Complexity: O(log n) on average (where n is the number of nodes in the tree)\n * Space Complexity: O(1)\n *\n * The `_fixInsert` function is used to fix the red-black tree after an insertion operation.\n * @param {RedBlackTreeNode} k - The parameter `k` is a RedBlackTreeNode object, which represents a node in a\n * red-black tree.\n */\n protected _fixInsert(k: N): void {\n let u: N | undefined;\n while (k.parent && k.parent.color === 1) {\n if (k.parent.parent && k.parent === k.parent.parent.right) {\n u = k.parent.parent.left;\n if (u && u.color === 1) {\n u.color = RBTNColor.BLACK;\n k.parent.color = RBTNColor.BLACK;\n k.parent.parent.color = RBTNColor.RED;\n k = k.parent.parent;\n } else {\n if (k === k.parent.left) {\n k = k.parent;\n this._rightRotate(k);\n }\n\n k.parent!.color = RBTNColor.BLACK;\n k.parent!.parent!.color = RBTNColor.RED;\n this._leftRotate(k.parent!.parent!);\n }\n } else {\n u = k.parent.parent!.right;\n\n if (u && u.color === 1) {\n u.color = RBTNColor.BLACK;\n k.parent.color = RBTNColor.BLACK;\n k.parent.parent!.color = RBTNColor.RED;\n k = k.parent.parent!;\n } else {\n if (k === k.parent.right) {\n k = k.parent;\n this._leftRotate(k);\n }\n\n k.parent!.color = RBTNColor.BLACK;\n k.parent!.parent!.color = RBTNColor.RED;\n this._rightRotate(k.parent!.parent!);\n }\n }\n if (k === this.root) {\n break;\n }\n }\n this.root.color = RBTNColor.BLACK;\n }\n\n /**\n * The function replaces an old node with a new node while preserving the color of the old node.\n * @param {N} oldNode - The `oldNode` parameter represents the node that needs to be replaced in a\n * data structure. It is of type `N`, which is the type of the nodes in the data structure.\n * @param {N} newNode - The `newNode` parameter is the node that will replace the `oldNode` in the\n * data structure.\n * @returns The method is returning the result of calling the `_replaceNode` method from the\n * superclass, passing in the `oldNode` and `newNode` as arguments.\n */\n protected _replaceNode(oldNode: N, newNode: N): N {\n newNode.color = oldNode.color;\n\n return super._replaceNode(oldNode, newNode)\n }\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 {\n BinaryTreeDeleteResult,\n BSTNKeyOrNode,\n BTNCallback,\n BTNExemplar,\n BTNKeyOrNode,\n TreeMultimapNested,\n TreeMultimapNodeNested,\n TreeMultimapOptions\n} from '../../types';\nimport { FamilyPosition, IterationType } from '../../types';\nimport { IBinaryTree } from '../../interfaces';\nimport { AVLTree, AVLTreeNode } from './avl-tree';\n\nexport class TreeMultimapNode<\n K = any,\n V = any,\n N extends TreeMultimapNode<K, V, N> = TreeMultimapNodeNested<K, V>\n> extends AVLTreeNode<K, V, N> {\n count: number;\n\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\n/**\n * The only distinction between a TreeMultimap and a AVLTree lies in the ability of the former to store duplicate nodes through the utilization of counters.\n */\nexport class TreeMultimap<K = any, V = any, N extends TreeMultimapNode<K, V, N> = TreeMultimapNode<K, V, TreeMultimapNodeNested<K, V>>,\n TREE extends TreeMultimap<K, V, N, TREE> = TreeMultimap<K, V, N, TreeMultimapNested<K, V, N>>>\n extends AVLTree<K, V, N, TREE>\n implements IBinaryTree<K, V, N, TREE> {\n\n constructor(elements?: Iterable<BTNExemplar<K, V, N>>, options?: Partial<TreeMultimapOptions<K>>) {\n super([], options);\n if (elements) this.addMany(elements);\n }\n\n private _count = 0;\n\n // TODO the _count is not accurate after nodes count modified\n get count(): number {\n let sum = 0;\n this.subTreeTraverse(node => sum += node.count);\n return sum;\n }\n\n /**\n * The function creates a new BSTNode with the given key, value, and count.\n * @param {K} key - The key parameter is the unique identifier for the binary tree node. It is used to\n * distinguish one node from another in the tree.\n * @param {N} value - The `value` parameter represents the value that will be stored in the binary search tree node.\n * @param {number} [count] - The \"count\" parameter is an optional parameter of type number. It represents the number of\n * occurrences of the value in the binary search tree node. If not provided, the count will default to 1.\n * @returns A new instance of the BSTNode class with the specified key, value, and count (if provided).\n */\n override createNode(key: K, value?: V, count?: number): N {\n return new TreeMultimapNode(key, value, count) as N;\n }\n\n override createTree(options?: TreeMultimapOptions<K>): TREE {\n return new TreeMultimap<K, V, N, TREE>([], {\n iterationType: this.iterationType,\n variant: this.variant, ...options\n }) as TREE;\n }\n\n /**\n * The function checks if an exemplar is an instance of the TreeMultimapNode class.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`.\n * @returns a boolean value indicating whether the exemplar is an instance of the TreeMultimapNode\n * class.\n */\n override isNode(exemplar: BTNExemplar<K, V, N>): exemplar is N {\n return exemplar instanceof TreeMultimapNode;\n }\n\n /**\n * The function \"isNotNodeInstance\" checks if a potential key is a K.\n * @param {any} potentialKey - The potentialKey parameter is of type any, which means it can be any\n * data type.\n * @returns a boolean value indicating whether the potentialKey is of type number or not.\n */\n override isNotNodeInstance(potentialKey: BTNKeyOrNode<K, N>): potentialKey is K {\n return !(potentialKey instanceof TreeMultimapNode)\n }\n\n /**\n * The function `exemplarToNode` converts an exemplar object into a node object.\n * @param exemplar - The `exemplar` parameter is of type `BTNExemplar<K, V, N>`, which means it\n * can be one of the following:\n * @param {V} [value] - The `value` parameter is an optional argument that represents the value\n * associated with the node. It is of type `V`, which can be any data type. If no value is provided,\n * it defaults to `undefined`.\n * @param [count=1] - The `count` parameter is an optional parameter that specifies the number of\n * times the value should be added to the node. If not provided, it defaults to 1.\n * @returns a node of type `N` or `undefined`.\n */\n override exemplarToNode(exemplar: BTNExemplar<K, V, N>, value?: V, count = 1): N | undefined {\n let node: N | undefined;\n if (exemplar === undefined || exemplar === null) {\n return;\n } else if (this.isNode(exemplar)) {\n node = exemplar;\n } else if (this.isEntry(exemplar)) {\n const [key, value] = exemplar;\n if (key === undefined || key === null) {\n return;\n } else {\n node = this.createNode(key, value, count);\n }\n } else if (this.isNotNodeInstance(exemplar)) {\n node = this.createNode(exemplar, value, count);\n } else {\n return;\n }\n return node;\n }\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the add method of a binary tree node and adds a new node to the tree.\n * @param keyOrNodeOrEntry - The `keyOrNodeOrEntry` parameter can be either a key, a node, or an\n * entry. It represents the key, node, or entry that you want to add to the binary tree.\n * @param {V} [value] - The `value` parameter represents the value associated with the key in the\n * binary tree node. It is an optional parameter, meaning it can be omitted when calling the `add`\n * method.\n * @param [count=1] - The `count` parameter represents the number of times the key-value pair should\n * be added to the binary tree. By default, it is set to 1, meaning that the key-value pair will be\n * added once. However, you can specify a different value for `count` if you want to add\n * @returns The method is returning either the newly inserted node or `undefined` if the insertion\n * was not successful.\n */\n override add(keyOrNodeOrEntry: BTNExemplar<K, V, N>, value?: V, count = 1): N | undefined {\n const newNode = this.exemplarToNode(keyOrNodeOrEntry, value, count);\n if (newNode === undefined) return;\n\n const orgNodeCount = newNode?.count || 0;\n const inserted = super.add(newNode);\n if (inserted) {\n this._count += orgNodeCount;\n }\n return inserted;\n }\n\n /**\n * Time Complexity: O(k log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(k log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The add method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The function overrides the addMany method to add multiple keys, nodes, or entries to a data\n * structure.\n * @param keysOrNodesOrEntries - The parameter `keysOrNodesOrEntries` is an iterable that can contain\n * either keys, nodes, or entries.\n * @returns The method is returning an array of type `N | undefined`.\n */\n override addMany(keysOrNodesOrEntries: Iterable<BTNExemplar<K, V, N>>): (N | undefined)[] {\n return super.addMany(keysOrNodesOrEntries);\n }\n\n /**\n * Time Complexity: O(1) - constant time, as it performs basic pointer assignments.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n */\n\n /**\n * Time Complexity: O(n log n) - logarithmic time for each insertion, where \"n\" is the number of nodes in the tree. This is because the method calls the add method for each node.\n * Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes.\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 - The `iterationType` parameter is an optional parameter that specifies the\n * type of iteration to use when building the balanced binary search tree. It can have two possible\n * values:\n * @returns a boolean value.\n */\n override perfectlyBalance(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 === 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(k log n) - logarithmic time for each insertion, where \"n\" is the number of nodes in the tree, and \"k\" is the number of keys to be inserted. This is because the method iterates through the keys and calls the add method for each.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n */\n\n /**\n * Time Complexity: O(log n) - logarithmic time, where \"n\" is the number of nodes in the tree. The delete method of the superclass (AVLTree) has logarithmic time complexity.\n * Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.\n *\n * The `delete` function in TypeScript is used to remove a node from a binary tree, taking into\n * account the count of the node and balancing the tree if necessary.\n * @param identifier - The identifier is the value or key that is used to identify the node that\n * needs to be deleted from the binary tree. It can be of any type that is returned by the callback\n * function.\n * @param {C} callback - The `callback` parameter is a function that is used to determine if a node\n * should be deleted. It is optional and defaults to a default callback function. The `callback`\n * function takes one parameter, which is the identifier of the node, and returns a value that is\n * used to identify the node to\n * @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node\n * being deleted. If set to true, the count of the node will not be considered and the node will be\n * deleted regardless of its count. If set to false (default), the count of the node will be\n * decremented by 1 and\n * @returns an array of `BinaryTreeDeleteResult<N>`.\n */\n override delete<C extends BTNCallback<N>>(\n identifier: ReturnType<C>,\n callback: C = this._defaultOneParamCallback as C,\n ignoreCount = false\n ): BinaryTreeDeleteResult<N>[] {\n const deletedResult: BinaryTreeDeleteResult<N>[] = [];\n if (!this.root) return deletedResult;\n\n const curr: N | undefined = this.getNode(identifier, callback) ?? undefined;\n if (!curr) return deletedResult;\n\n const parent: N | undefined = curr?.parent ? curr.parent : undefined;\n let needBalanced: N | undefined = undefined,\n orgCurrent: N | 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 === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {\n parent.left = curr.right;\n } else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {\n parent.right = curr.right;\n }\n needBalanced = parent;\n }\n } else {\n const leftSubTreeRightMost = curr.left ? this.getRightMost(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(n log n) - logarithmic time for each insertion, where \"n\" is the number of nodes in the tree. This is because the method calls the add method for each node.\n * Space Complexity: O(n) - linear space, as it creates an array to store the sorted nodes.\n */\n\n /**\n * The clear() function clears the contents of a data structure and sets the count to zero.\n */\n override clear() {\n super.clear();\n this._count = 0;\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 `clone` function creates 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) - constant time, as it performs basic pointer assignments.\n * Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.\n *\n * The function adds a new node to a binary tree, either as the left child or the right child of a\n * given parent node.\n * @param {N | undefined} newNode - The `newNode` parameter represents the node that needs to be\n * added to the binary tree. It can be of type `N` (which represents a node in the binary tree) or\n * `undefined` if there is no node to add.\n * @param {K | N | undefined} parent - The `parent` parameter represents the parent node to\n * which the new node will be added as a child. It can be either a node object (`N`) or a key value\n * (`K`).\n * @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was\n * added, or `undefined` if no node was added.\n */\n protected override _addTo(newNode: N | undefined, parent: BSTNKeyOrNode<K, N>): N | undefined {\n parent = this.ensureNode(parent);\n if (parent) {\n if (parent.left === undefined) {\n parent.left = newNode;\n if (newNode !== undefined) {\n this._size = this.size + 1;\n this._count += newNode.count;\n }\n\n return parent.left;\n } else if (parent.right === undefined) {\n parent.right = newNode;\n if (newNode !== undefined) {\n this._size = this.size + 1;\n this._count += newNode.count;\n }\n return parent.right;\n } else {\n return;\n }\n } else {\n return;\n }\n }\n\n /**\n * The `_swapProperties` function swaps the key, value, count, and height properties between two nodes.\n * @param {K | N | undefined} srcNode - The `srcNode` parameter represents the source node from\n * which the values will be swapped. It can be of type `K`, `N`, or `undefined`.\n * @param {K | N | undefined} destNode - The `destNode` parameter represents the destination\n * node where the values from the source node will be swapped to.\n * @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`\n * if either `srcNode` or `destNode` is undefined.\n */\n protected override _swapProperties(srcNode: BSTNKeyOrNode<K, N>, destNode: BSTNKeyOrNode<K, N>): N | 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 protected _replaceNode(oldNode: N, newNode: N): N {\n newNode.count = oldNode.count + newNode.count\n return super._replaceNode(oldNode, newNode);\n }\n}\n","export class TreeNode<V = any> {\n key: string;\n value?: V | undefined;\n children?: TreeNode<V>[] | undefined;\n\n constructor(key: string, value?: V, children?: TreeNode<V>[]) {\n this.key = key;\n this.value = value || undefined;\n this.children = children || [];\n }\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 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","/**\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 { 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> extends Heap<E> {\n constructor(elements?: Iterable<E>, options?: PriorityQueueOptions<E>) {\n super(elements, options);\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 { PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MinPriorityQueue<E = any> extends PriorityQueue<E> {\n constructor(elements?: Iterable<E>,\n options: PriorityQueueOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return a - b;\n }\n }\n }\n ) {\n super(elements, options);\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 { PriorityQueueOptions } from '../../types';\nimport { PriorityQueue } from './priority-queue';\n\nexport class MaxPriorityQueue<E = any> extends PriorityQueue<E> {\n constructor(\n elements?: Iterable<E>,\n options: PriorityQueueOptions<E> = {\n comparator: (a: E, b: E) => {\n if (!(typeof a === 'number' && typeof b === 'number')) {\n throw new Error('The a, b params of compare function must be number');\n } else {\n return b - a;\n }\n }\n }\n ) {\n super(elements, options);\n }\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 */\n// todo need to be improved\nexport class MatrixNTI2D<V = any> {\n protected readonly _matrix: Array<Array<V>>;\n\n /**\n * The constructor creates a matrix with the specified number of rows and columns, and initializes all elements to a\n * given initial value or 0 if not provided.\n * @param options - An object containing the following properties:\n */\n constructor(options: { row: number; col: number; initialVal?: V }) {\n const { row, col, initialVal } = options;\n this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));\n }\n\n /* The `toArray` method returns the matrix as a two-dimensional array. It converts the internal representation of the\n matrix, which is an array of arrays, into a format that is more commonly used in JavaScript. */\n toArray(): Array<Array<V>> {\n return this._matrix;\n }\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 */\nexport class Vector2D {\n constructor(\n public x: number = 0,\n public y: number = 0,\n public w: number = 1 // needed for matrix multiplication\n ) {\n }\n\n /**\n * The function checks if the x and y values of a point are both zero.\n * @returns A boolean value indicating whether both the x and y properties of the object are equal to 0.\n */\n get isZero(): boolean {\n return this.x === 0 && this.y === 0;\n }\n\n /**\n * The above function calculates the length of a vector using the Pythagorean theorem.\n * @returns The length of a vector, calculated using the Pythagorean theorem.\n */\n get length(): number {\n return Math.sqrt(this.x * this.x + this.y * this.y);\n }\n\n /**\n * The function calculates the square of the length of a vector.\n * @returns The method is returning the sum of the squares of the x and y values.\n */\n get lengthSq(): number {\n return this.x * this.x + this.y * this.y;\n }\n\n /**\n * The \"rounded\" function returns a new Vector2D object with the x and y values rounded to the nearest whole number.\n * @returns The method is returning a new instance of the Vector2D class with the x and y values rounded to the nearest\n * whole number.\n */\n get rounded(): Vector2D {\n return new Vector2D(Math.round(this.x), Math.round(this.y));\n }\n\n /**\n * The function \"add\" takes two Vector2D objects as parameters and returns a new Vector2D object with the sum of their\n * x and y components.\n * @param {Vector2D} vector1 - The parameter `vector1` is an instance of the `Vector2D` class. It represents a\n * 2-dimensional vector with an `x` and `y` component.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is of type Vector2D. It represents a 2-dimensional vector with\n * an x and y component.\n * @returns The method is returning a new instance of the Vector2D class with the x and y components of the two input\n * vectors added together.\n */\n static add(vector1: Vector2D, vector2: Vector2D): Vector2D {\n return new Vector2D(vector1.x + vector2.x, vector1.y + vector2.y);\n }\n\n /**\n * The subtract function takes two Vector2D objects as parameters and returns a new Vector2D object with the x and y\n * components subtracted.\n * @param {Vector2D} vector1 - The parameter `vector1` is an instance of the `Vector2D` class, representing a\n * 2-dimensional vector. It has properties `x` and `y` which represent the x and y components of the vector\n * respectively.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is a Vector2D object. It represents the second vector that you\n * want to subtract from the first vector.\n * @returns The method is returning a new Vector2D object with the x and y components subtracted from vector1 and\n * vector2.\n */\n static subtract(vector1: Vector2D, vector2: Vector2D): Vector2D {\n return new Vector2D(vector1.x - vector2.x, vector1.y - vector2.y);\n }\n\n /**\n * The function subtracts a given value from the x and y components of a Vector2D object and returns a new Vector2D\n * object.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector with\n * x and y components.\n * @param {number} value - The \"value\" parameter is a number that will be subtracted from both the x and y components\n * of the \"vector\" parameter.\n * @returns A new Vector2D object with the x and y values subtracted by the given value.\n */\n static subtractValue(vector: Vector2D, value: number): Vector2D {\n return new Vector2D(vector.x - value, vector.y - value);\n }\n\n /**\n * The function multiplies a Vector2D object by a given value.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector with\n * x and y components.\n * @param {number} value - The \"value\" parameter is a number that represents the value by which the x and y components\n * of the vector will be multiplied.\n * @returns A new Vector2D object with the x and y values multiplied by the given value.\n */\n static multiply(vector: Vector2D, value: number): Vector2D {\n return new Vector2D(vector.x * value, vector.y * value);\n }\n\n /**\n * The function divides the x and y components of a Vector2D by a given value and returns a new Vector2D.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector with\n * x and y components.\n * @param {number} value - The value parameter is a number that will be used to divide the x and y components of the\n * vector.\n * @returns A new instance of the Vector2D class with the x and y values divided by the given value.\n */\n static divide(vector: Vector2D, value: number): Vector2D {\n return new Vector2D(vector.x / value, vector.y / value);\n }\n\n /**\n * The function checks if two Vector2D objects are equal by comparing their x and y values.\n * @param {Vector2D} vector1 - The parameter `vector1` is of type `Vector2D`, which represents a 2-dimensional vector.\n * It has two properties: `x` and `y`, which represent the x and y components of the vector, respectively.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is of type Vector2D.\n * @returns a boolean value, which indicates whether the two input vectors are equal or not.\n */\n static equals(vector1: Vector2D, vector2: Vector2D): boolean {\n return vector1.x === vector2.x && vector1.y === vector2.y;\n }\n\n /**\n * The function checks if two Vector2D objects are equal within a specified rounding factor.\n * @param {Vector2D} vector1 - The first vector to compare.\n * @param {Vector2D} vector2 - The parameter \"vector2\" is a Vector2D object, which represents a 2-dimensional vector.\n * It is used as one of the inputs for the \"equalsRounded\" function.\n * @param [roundingFactor=12] - The roundingFactor parameter is used to determine the threshold for considering two\n * vectors as equal. If the absolute difference in the x and y components of the vectors is less than the\n * roundingFactor, the vectors are considered equal.\n * @returns a boolean value.\n */\n static equalsRounded(vector1: Vector2D, vector2: Vector2D, roundingFactor = 12): boolean {\n const vector = Vector2D.abs(Vector2D.subtract(vector1, vector2));\n if (vector.x < roundingFactor && vector.y < roundingFactor) {\n return true;\n }\n\n return false;\n }\n\n /**\n * The normalize function takes a vector as input and returns a normalized version of the vector.Normalizes the vector if it matches a certain condition\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D.\n * @returns the normalized vector if its length is greater than a very small value (epsilon), otherwise it returns the\n * original vector.\n */\n static normalize(vector: Vector2D): Vector2D {\n const length = vector.length;\n if (length > 2.220446049250313e-16) {\n // Epsilon\n return Vector2D.divide(vector, length);\n }\n\n return vector;\n }\n\n /**\n * The function truncates a vector to a maximum length if it exceeds that length.Adjusts x and y so that the length of the vector does not exceed max\n * @param {Vector2D} vector - A 2D vector represented by the Vector2D class.\n * @param {number} max - The `max` parameter is a number that represents the maximum length that the `vector` should\n * have.\n * @returns either the original vector or a truncated version of the vector, depending on whether the length of the\n * vector is greater than the maximum value specified.\n */\n static truncate(vector: Vector2D, max: number): Vector2D {\n if (vector.length > max) {\n return Vector2D.multiply(Vector2D.normalize(vector), max);\n }\n\n return vector;\n }\n\n /**\n * The function returns a new Vector2D object that is perpendicular to the input vector.The vector that is perpendicular to this one\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D.\n * @returns A new Vector2D object is being returned.\n */\n static perp(vector: Vector2D): Vector2D {\n return new Vector2D(-vector.y, vector.x);\n }\n\n /**\n * The reverse function takes a Vector2D object and returns a new Vector2D object with the negated x and y values.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector. It\n * has two properties: \"x\" and \"y\", which represent the x and y components of the vector, respectively.\n * @returns A new Vector2D object with the negated x and y values of the input vector. Returns the vector that is the reverse of this vector\n */\n static reverse(vector: Vector2D): Vector2D {\n return new Vector2D(-vector.x, -vector.y);\n }\n\n /**\n * The function takes a Vector2D object as input and returns a new Vector2D object with the absolute values of its x\n * and y components.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D, which represents a 2-dimensional vector. It\n * has two properties: \"x\" and \"y\", which represent the x and y components of the vector, respectively.\n * @returns The method is returning a new Vector2D object with the absolute values of the x and y components of the\n * input vector.\n */\n static abs(vector: Vector2D): Vector2D {\n return new Vector2D(Math.abs(vector.x), Math.abs(vector.y));\n }\n\n /**\n * The dot function calculates the dot product of two 2D vectors.The dot product of v1 and v2\n * @param {Vector2D} vector1 - The parameter `vector1` represents a 2D vector with its x and y components.\n * @param {Vector2D} vector2 - The \"vector2\" parameter is a Vector2D object. It represents a two-dimensional vector\n * with an x and y component.\n * @returns The dot product of the two input vectors.\n */\n static dot(vector1: Vector2D, vector2: Vector2D): number {\n return vector1.x * vector2.x + vector1.y * vector2.y;\n }\n\n // /**\n // * Transform vectors based on the current tranformation matrices: translation, rotation and scale\n // * @param vectors The vectors to transform\n // */\n // static transform(vector: Vector2D, transformation: Matrix2D): Vector2D {\n // return Matrix2D.multiplyByVector(transformation, vector)\n // }\n\n // /**\n // * Transform vectors based on the current tranformation matrices: translation, rotation and scale\n // * @param vectors The vectors to transform\n // */\n // static transformList(vectors: Vector2D[], transformation: Matrix2D): Vector2D[] {\n // return vectors.map(vector => Matrix2D.multiplyByVector(transformation, vector))\n // }\n\n /**\n * The function calculates the distance between two points in a two-dimensional space.\n * @param {Vector2D} vector1 - The parameter `vector1` represents the first vector in 2D space, while `vector2`\n * represents the second vector. Each vector has an `x` and `y` component, which represent their respective coordinates\n * in the 2D space.\n * @param {Vector2D} vector2 - The `vector2` parameter represents the second vector in the calculation of distance. It\n * is an instance of the `Vector2D` class, which typically has properties `x` and `y` representing the coordinates of\n * the vector in a 2D space.\n * @returns The distance between vector1 and vector2.\n */\n static distance(vector1: Vector2D, vector2: Vector2D): number {\n const ySeparation = vector2.y - vector1.y;\n const xSeparation = vector2.x - vector1.x;\n return Math.sqrt(ySeparation * ySeparation + xSeparation * xSeparation);\n }\n\n /**\n * The function calculates the squared distance between two 2D vectors.\n * @param {Vector2D} vector1 - The parameter `vector1` represents the first vector, which is an instance of the\n * `Vector2D` class. It contains the x and y coordinates of the vector.\n * @param {Vector2D} vector2 - The `vector2` parameter represents the second vector in a two-dimensional space. It has\n * properties `x` and `y` which represent the coordinates of the vector.\n * @returns the square of the distance between the two input vectors.\n */\n static distanceSq(vector1: Vector2D, vector2: Vector2D): number {\n const ySeparation = vector2.y - vector1.y;\n const xSeparation = vector2.x - vector1.x;\n return ySeparation * ySeparation + xSeparation * xSeparation;\n }\n\n /**\n * The sign function determines the sign of the cross product between two 2D vectors.\n * (assuming the Y axis is pointing down, X axis to right like a Window app)\n * @param {Vector2D} vector1 - The parameter `vector1` is of type `Vector2D`, which represents a 2-dimensional vector.\n * It likely has properties `x` and `y` representing the x and y components of the vector, respectively.\n * @param {Vector2D} vector2 - The above code defines a function called \"sign\" that takes two parameters: vector1 and\n * vector2. Both vector1 and vector2 are of type Vector2D.\n * @returns either -1 or 1. Returns positive if v2 is clockwise of this vector, negative if counterclockwise\n */\n static sign(vector1: Vector2D, vector2: Vector2D): number {\n if (vector1.y * vector2.x > vector1.x * vector2.y) {\n return -1;\n }\n\n return 1;\n }\n\n /**\n * The function calculates the angle between a given vector and the negative y-axis.\n * @param {Vector2D} vector - The \"vector\" parameter is an instance of the Vector2D class, which represents a\n * 2-dimensional vector. It has two properties: \"x\" and \"y\", which represent the x and y components of the vector,\n * respectively.\n * @returns the angle between the given vector and the vector (0, -1) in radians.Returns the angle between origin and the given vector in radians\n */\n static angle(vector: Vector2D): number {\n const origin = new Vector2D(0, -1);\n const radian = Math.acos(Vector2D.dot(vector, origin) / (vector.length * origin.length));\n return Vector2D.sign(vector, origin) === 1 ? Math.PI * 2 - radian : radian;\n }\n\n /**\n * The function \"random\" generates a random Vector2D object with x and y values within the specified range.\n * @param {number} maxX - The maxX parameter represents the maximum value for the x-coordinate of the random vector.\n * @param {number} maxY - The `maxY` parameter represents the maximum value for the y-coordinate of the generated\n * random vector.\n * @returns a new instance of the Vector2D class with random x and y values.\n */\n static random(maxX: number, maxY: number): Vector2D {\n const randX = Math.floor(Math.random() * maxX - maxX / 2);\n const randY = Math.floor(Math.random() * maxY - maxY / 2);\n return new Vector2D(randX, randY);\n }\n\n /**\n * The function sets the values of x and y to zero.\n */\n zero(): void {\n this.x = 0;\n this.y = 0;\n }\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 { Vector2D } from './vector2d';\n\nexport class Matrix2D {\n protected readonly _matrix: number[][];\n\n /**\n * The constructor function initializes a Matrix2D object with either a default identity matrix, or a provided matrix\n * or Vector2D object.\n * @param {number[][] | Vector2D} [value] - The `value` parameter can be either a 2D array of numbers (`number[][]`) or\n * an instance of the `Vector2D` class.\n */\n constructor(value?: number[][] | Vector2D) {\n if (typeof value === 'undefined') {\n this._matrix = Matrix2D.identity;\n } else if (value instanceof Vector2D) {\n this._matrix = Matrix2D.identity;\n this._matrix[0][0] = value.x;\n this._matrix[1][0] = value.y;\n this._matrix[2][0] = value.w;\n } else {\n this._matrix = value;\n }\n }\n\n /**\n * The function returns a 2D array with three empty arrays.\n * @returns An empty 2-dimensional array with 3 empty arrays inside.\n */\n static get empty(): number[][] {\n return [[], [], []];\n }\n\n /**\n * The above function returns a 3x3 identity matrix.\n * @returns The method is returning a 2-dimensional array of numbers representing the identity matrix.\n */\n static get identity(): number[][] {\n return [\n [1, 0, 0],\n [0, 1, 0],\n [0, 0, 1]\n ];\n }\n\n /**\n * The function returns a two-dimensional array of numbers.\n * @returns The getter method is returning the value of the private variable `_matrix`, which is a two-dimensional\n * array of numbers.\n */\n get m(): number[][] {\n return this._matrix;\n }\n\n /**\n * The function takes two 2D matrices as input and returns their sum as a new 2D matrix.\n * @param {Matrix2D} matrix1 - Matrix2D - The first matrix to be added.\n * @param {Matrix2D} matrix2 - The parameter `matrix2` is a Matrix2D object.\n * @returns a new instance of the Matrix2D class, which is created using the result array.\n */\n static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = matrix1.m[i][j] + matrix2.m[i][j];\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function subtracts two 2D matrices and returns the result as a new Matrix2D object.\n * @param {Matrix2D} matrix1 - Matrix2D - The first matrix to subtract from.\n * @param {Matrix2D} matrix2 - Matrix2D is a class representing a 2D matrix. It has a property `m` which is a 2D array\n * representing the matrix elements.\n * @returns a new instance of the Matrix2D class, which is created using the result array.\n */\n static subtract(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = matrix1.m[i][j] - matrix2.m[i][j];\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function multiplies two 2D matrices and returns the result as a new Matrix2D object.\n * @param {Matrix2D} matrix1 - A 2D matrix represented by the Matrix2D class.\n * @param {Matrix2D} matrix2 - The parameter `matrix2` is a 2D matrix of size 3x3.\n * @returns a new instance of the Matrix2D class, created using the result array.\n */\n static multiply(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = 0;\n for (let k = 0; k < 3; k++) {\n result[i][j] += matrix1.m[i][k] * matrix2.m[k][j];\n }\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function multiplies each element of a 2D matrix by a given value and returns the resulting matrix.\n * @param {Matrix2D} matrix - The `matrix` parameter is an instance of the `Matrix2D` class, which represents a 2D\n * matrix. It contains a property `m` that is a 2D array representing the matrix elements.\n * @param {number} value - The `value` parameter is a number that you want to multiply each element of the `matrix` by.\n * @returns a new instance of the Matrix2D class, which is created using the result array.\n */\n static multiplyByValue(matrix: Matrix2D, value: number): Matrix2D {\n const result = Matrix2D.empty;\n for (let i = 0; i < 3; i++) {\n for (let j = 0; j < 3; j++) {\n result[i][j] = matrix.m[i][j] * value;\n }\n }\n return new Matrix2D(result);\n }\n\n /**\n * The function multiplies a 2D matrix by a 2D vector and returns the result as a 2D vector.\n * @param {Matrix2D} matrix - The parameter \"matrix\" is of type Matrix2D. It represents a 2-dimensional matrix.\n * @param {Vector2D} vector - The \"vector\" parameter is a 2D vector, represented by an object of type Vector2D.\n * @returns a Vector2D.\n */\n static multiplyByVector(matrix: Matrix2D, vector: Vector2D): Vector2D {\n const resultMatrix = Matrix2D.multiply(matrix, new Matrix2D(vector));\n return resultMatrix.toVector();\n }\n\n /**\n * The function returns a 2D matrix that scales and flips a vector around the center of a given width and height.\n * @param {number} width - The width parameter represents the width of the view or the canvas. It is a number that\n * specifies the width in pixels or any other unit of measurement.\n * @param {number} height - The height parameter represents the height of the view or the canvas. It is used to\n * calculate the centerY value, which is the vertical center of the view.\n * @returns a Matrix2D object.\n */\n static view(width: number, height: number): Matrix2D {\n const scaleStep = 1; // Scale every vector * scaleStep\n const centerX = width / 2;\n const centerY = height / 2;\n const flipX = Math.cos(Math.PI); // rotate 180deg / 3.14radian around X-axis\n\n return new Matrix2D([\n [scaleStep, 0, centerX],\n [0, flipX * scaleStep, centerY],\n [0, 0, 1]\n ]);\n }\n\n /**\n * The function scales a matrix by a given factor.\n * @param {number} factor - The factor parameter is a number that represents the scaling factor by which the matrix\n * should be scaled.\n * @returns the result of multiplying a new instance of Matrix2D by the given factor.\n */\n static scale(factor: number) {\n return Matrix2D.multiplyByValue(new Matrix2D(), factor);\n }\n\n /**\n * The function \"rotate\" takes an angle in radians and returns a 2D transformation matrix for rotating objects.\n * @param {number} radians - The \"radians\" parameter is the angle in radians by which you want to rotate an object.\n * @returns The code is returning a new instance of a Matrix2D object.\n */\n static rotate(radians: number) {\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n\n return new Matrix2D([\n [cos, -sin, 0],\n [sin, cos, 0],\n [0, 0, 1]\n ]);\n }\n\n /**\n * The translate function takes a 2D vector and returns a 2D matrix that represents a translation transformation.\n * @param {Vector2D} vector - The parameter \"vector\" is of type Vector2D. It represents a 2D vector with components x\n * and y, and an optional w component.\n * @returns The method is returning a new instance of the Matrix2D class.\n */\n static translate(vector: Vector2D): Matrix2D {\n return new Matrix2D([\n [1, 0, vector.x],\n [0, 1, vector.y],\n [0, 0, vector.w]\n ]);\n }\n\n /**\n * The function \"toVector\" returns a new Vector2D object with the values from the first and second elements of the\n * _matrix array.\n * @returns A new instance of the Vector2D class is being returned. The values of the returned vector are taken from\n * the first column of the matrix.\n */\n toVector(): Vector2D {\n return new Vector2D(this._matrix[0][0], this._matrix[1][0]);\n }\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 { 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 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 this.onMove && this.onMove(this._cur);\n }\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 { ElementCallback } 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 key: string;\n children: Map<string, TrieNode>;\n isEnd: boolean;\n\n constructor(key: string) {\n this.key = key;\n this.isEnd = false;\n this.children = new Map<string, TrieNode>();\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 extends IterableElementBase<string> {\n constructor(words?: string[], caseSensitive = true) {\n super();\n this._root = new TrieNode('');\n this._caseSensitive = caseSensitive;\n this._size = 0;\n if (words) {\n for (const word of words) {\n this.add(word);\n }\n }\n }\n\n protected _size: number;\n\n get size(): number {\n return this._size;\n }\n\n protected _caseSensitive: boolean;\n\n get caseSensitive(): boolean {\n return this._caseSensitive;\n }\n\n protected _root: TrieNode;\n\n get root() {\n return this._root;\n }\n\n /**\n * Time Complexity: O(M), where M is the length of the word being added.\n * Space Complexity: O(M) - Each character in the word adds a TrieNode.\n */\n\n /**\n * Time Complexity: O(M), where M is the length of the word being added.\n * Space Complexity: O(M) - 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(M), where M is the length of the input word.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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 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(M), where M is the length of the word being deleted.\n * Space Complexity: O(M) - Due to the recursive DFS approach.\n */\n\n /**\n * Time Complexity: O(M), where M is the length of the word being deleted.\n * Space Complexity: O(M) - 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 /**\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(M), where M is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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(M), where M is the length of the input prefix.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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(M), where M is the length of the input prefix.\n */\n\n /**\n * Time Complexity: O(N), where N is the total number of nodes in the trie.\n * Space Complexity: O(M), where M 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(M), where M is the length of the longest common prefix.\n */\n\n /**\n * Time Complexity: O(N), where N is the total number of nodes in the trie.\n * Space Complexity: O(M), where M 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(K * L), where K is the number of words retrieved, and L is the average length of the words.\n * Space Complexity: O(K * L) - The space required for the output array.\n */\n\n /**\n * Time Complexity: O(K * L), where K is the number of words retrieved, and L is the average length of the words.\n * Space Complexity: O(K * 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) startNode = nodeC;\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\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, boolean>, thisArg?: any): Trie {\n const results: Trie = new Trie();\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\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 Trie.\n * @param callback - The callback parameter is a function that will be called for each element in the\n * Trie. It takes three arguments: the current element in the Trie, the index of the current element,\n * and the Trie itself. The callback function should return a new value for the element.\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 `map` function is returning a new Trie object.\n */\n map(callback: ElementCallback<string, string>, thisArg?: any): Trie {\n const newTrie = new Trie();\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 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(M), where M is the length of the input string.\n * Space Complexity: O(1) - Constant space.\n */\n\n /**\n * Time Complexity: O(M), where M 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"],"mappings":"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","names":["src_exports","__export","AVLTree","AVLTreeNode","AbstractEdge","AbstractGraph","AbstractVertex","BST","BSTNode","BSTVariant","BinaryIndexedTree","BinaryTree","BinaryTreeNode","CP","Character","Deque","DirectedEdge","DirectedGraph","DirectedVertex","DoublyLinkedList","DoublyLinkedListNode","FamilyPosition","FibonacciHeap","FibonacciHeapNode","HashMap","HashTable","HashTableNode","Heap","IterableElementBase","IterableEntryBase","IterationType","LinkedHashMap","LinkedListQueue","MapEdge","MapGraph","MapVertex","Matrix2D","MatrixNTI2D","MaxHeap","MaxPriorityQueue","MinHeap","MinPriorityQueue","Navigator","PriorityQueue","Queue","RBTNColor","RedBlackTree","RedBlackTreeNode","SegmentTree","SegmentTreeNode","SinglyLinkedList","SinglyLinkedListNode","SkipList","SkipListNode","Stack","THUNK_SYMBOL","TreeMultimap","TreeMultimapNode","TreeNode","Trie","TrieNode","UndirectedEdge","UndirectedGraph","UndirectedVertex","Vector2D","arrayRemove","calcMinUnitsRequired","getMSB","isThunk","isWeakKey","rangeCheck","throwRangeError","toThunk","trampoline","trampolineAsync","uuidV4","HashTableNode","key","value","__publicField","_HashTable","capacity","hashFn","index","newNode","currentNode","prevNode","bucket","callback","entry","predicate","newTable","initialValue","accumulator","keyString","hash","i","charCode","A","M","char","newCapacity","newBuckets","newIndex","currentNewNode","HashTable","IterableEntryBase","args","__yieldStar","item","predicate","thisArg","index","callbackfn","key","value","initialValue","accumulator","elementValue","IterableElementBase","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","HashMap","_HashMap","IterableEntryBase","elements","options","__publicField","key","hashFn","value","strKey","results","_a","callbackfn","thisArg","resultMap","index","predicate","filteredMap","node","keyType","LinkedHashMap","_LinkedHashMap","objHashFn","el","isNewKey","isWeakKey","hash","entries","entry","rangeCheck","cloned","callback","mappedMap","newValue","prev","next","SinglyLinkedListNode","value","__publicField","SinglyLinkedList","_SinglyLinkedList","IterableElementBase","elements","el","data","singlyLinkedList","item","newNode","current","removedNode","index","i","prevNode","valueOrNode","prev","array","next","callback","existingValueOrNode","newValue","existingValue","existingNode","count","thisArg","filteredList","mappedList","DoublyLinkedListNode","value","__publicField","DoublyLinkedList","_DoublyLinkedList","IterableElementBase","elements","el","_a","data","doublyLinkedList","item","newNode","removedNode","index","current","i","prevNode","nextNode","existingValueOrNode","newValue","existingNode","valOrNode","node","callback","next","array","thisArg","filteredList","mappedList","SkipListNode","key","value","level","__publicField","SkipList","maxLevel","probability","firstNode","current","i","newNode","update","nextNode","lastLess","Stack","_Stack","IterableElementBase","elements","__publicField","el","element","predicate","thisArg","newStack","index","callback","i","Queue","_Queue","IterableElementBase","elements","__publicField","element","first","value","index","predicate","thisArg","newDeque","el","callback","item","LinkedListQueue","SinglyLinkedList","_a","Deque","_Deque","IterableElementBase","elements","bucketSize","__publicField","_size","calcMinUnitsRequired","i","needBucketNum","element","index","pos","rangeCheck","bucketIndex","indexInBucket","num","length","arr","curBucket","curPointer","nextBucket","nextPointer","size","oldElement","bucket","_bucketFirst","_bucketLast","_firstInBucket","_lastInBucket","prev","cur","comparator","newBuckets","callback","predicate","thisArg","newDeque","el","addBucketNum","overallIndex","Heap","_Heap","IterableElementBase","elements","options","__publicField","defaultComparator","a","b","el","_a","element","value","last","index","order","result","_dfs","left","right","clonedHeap","visitedNode","cloned","top","results","i","callback","thisArg","filteredList","current","comparator","mappedHeap","parent","parentItem","halfLength","minItem","FibonacciHeapNode","degree","FibonacciHeap","node","head","flag","z","heapToMerge","thisRoot","otherRoot","thisRootRight","otherRootLeft","y","x","A","d","t","MaxHeap","Heap","elements","options","a","b","MinHeap","Heap","elements","options","a","b","AbstractVertex","key","value","__publicField","AbstractEdge","weight","uuidV4","AbstractGraph","IterableEntryBase","vertexKey","vertexOrKey","keyOrVertex","newVertex","potentialKey","potentialKeyType","vertexMap","removed","v","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","curHeapNode","dist","distSrcToNeighbor","scanNegativeCycle","getMin","genPath","hasNegativeCycle","numOfVertices","edgeMap","numOfEdges","j","ends","s","sWeight","dWeight","idAndVertices","n","costs","predecessor","k","needCutVertexes","needBridges","needSCCs","needCycles","dfnMap","lowMap","root","cutVertexes","bridges","dfn","childCount","childLow","curLow","edgeCurToNeighbor","SCCs","low","cycles","visitedMap","findCyclesDFS","cycleStartIndex","cycle","cycleLow","isInclude2Cycle","currentPath","uniqueCycles","sorted","cycleString","predicate","thisArg","filtered","callback","mapped","DirectedVertex","AbstractVertex","key","value","DirectedEdge","AbstractEdge","src","dest","weight","__publicField","DirectedGraph","AbstractGraph","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","srcVertex","destVertex","UndirectedVertex","AbstractVertex","key","value","UndirectedEdge","AbstractEdge","v1","v2","weight","__publicField","UndirectedGraph","AbstractGraph","_a","edgeMap","vertex1","vertex2","e","v1Edges","removed","arrayRemove","v2Edges","edgeOrOneSideVertexKey","otherSideVertexKey","oneSide","otherSide","vertexOrKey","vertexKey","vertex","neighbors","neighbor","neighborEdges","restEdges","edge","edgeSet","end","endVertex","MapVertex","DirectedVertex","key","value","lat","long","__publicField","MapEdge","DirectedEdge","src","dest","weight","MapGraph","DirectedGraph","originCoord","bottomRight","RBTNColor","BSTVariant","CP","IterationType","FamilyPosition","BinaryTreeNode","key","value","__publicField","v","that","BinaryTree","_BinaryTree","IterableEntryBase","elements","options","node","iterationType","extractor","__spreadValues","exemplar","kne","keyOrNodeOrEntry","newNode","queue","Queue","potentialParent","cur","nodes","values","inserted","valuesIterator","valueResult","nodesOrKeysOrEntries","identifier","callback","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","distNode","beginRoot","depth","_getMaxHeight","leftHeight","rightHeight","stack","maxHeight","_a","_b","_c","_getMinHeight","leftMinHeight","rightMinHeight","last","depths","onlyOne","ans","_traverse","_dfs","isReverse","result","trampoline","dfs","min","max","numKey","prev","includeNull","potentialKey","pattern","traverse","level","current","levelSize","i","levelsNodes","_recursive","head","predecessor","x","y","_reverseEdge","pre","next","_printEdge","tail","cloned","predicate","thisArg","newTree","index","opts","root","lines","line","__yieldStar","isShowNull","isShowUndefined","isShowRedBlackNIL","emptyDisplayLayout","width","_buildNodeDisplay","left","right","leftLines","leftWidth","leftMiddle","rightLines","rightWidth","rightMiddle","firstLine","secondLine","mergedLines","leftLine","rightLine","srcNode","destNode","tempNode","oldNode","BSTNode","BinaryTreeNode","key","value","__publicField","v","BST","_BST","BinaryTree","elements","options","variant","__spreadValues","exemplar","node","keyOrNodeOrEntry","newNode","current","keysOrNodesOrEntries","values","isBalanceAdd","iterationType","inserted","valuesIterator","kve","nn","realBTNExemplars","isRealBTNExemplar","sorted","a","b","aR","bR","_dfs","arr","mid","_iterate","stack","popped","l","r","m","beginRoot","cur","queue","Queue","potentialKey","identifier","callback","onlyOne","ans","_traverse","lesserOrGreater","targetNode","targetKey","n","buildBalanceBST","midNode","_a","_b","balanced","_height","leftHeight","rightHeight","last","depths","left","right","extractedA","extractedB","compared","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","elements","options","__spreadValues","exemplar","potentialKey","keyOrNodeOrEntry","inserted","identifier","callback","node","deletedResults","needBalanced","srcNode","destNode","height","tempNode","rightHeight","path","i","A","parentOfA","B","C","oldNode","newNode","RedBlackTreeNode","BSTNode","key","value","color","__publicField","RedBlackTree","_RedBlackTree","BST","elements","options","__spreadValues","exemplar","potentialKey","node","keyOrNodeOrEntry","newNode","y","x","identifier","callback","ans","z","yOriginalColor","beginRoot","iterationType","_a","v","s","u","k","oldNode","TreeMultimapNode","AVLTreeNode","key","value","count","__publicField","TreeMultimap","_TreeMultimap","AVLTree","elements","options","sum","node","__spreadValues","exemplar","potentialKey","keyOrNodeOrEntry","newNode","orgNodeCount","inserted","keysOrNodesOrEntries","iterationType","sorted","n","buildBalanceBST","l","r","m","midNode","stack","popped","identifier","callback","ignoreCount","_a","deletedResult","curr","parent","needBalanced","orgCurrent","leftSubTreeRightMost","parentOfLeftSubTreeMax","fp","cloned","srcNode","destNode","height","tempNode","oldNode","TreeNode","_TreeNode","key","value","children","__publicField","maxDepth","bfs","node","level","i","len","PriorityQueue","Heap","elements","options","MinPriorityQueue","PriorityQueue","elements","options","a","b","MaxPriorityQueue","PriorityQueue","elements","options","a","b","MatrixNTI2D","options","__publicField","row","col","initialVal","Vector2D","_Vector2D","x","y","w","vector1","vector2","vector","value","roundingFactor","length","max","ySeparation","xSeparation","origin","radian","maxX","maxY","randX","randY","Matrix2D","_Matrix2D","value","__publicField","Vector2D","matrix1","matrix2","result","i","j","k","matrix","vector","width","height","centerX","centerY","flipX","factor","radians","cos","sin","Character","_Character","direction","turning","__publicField","Navigator","matrix","onMove","cur","charDir","VISITED","forward","row","j","i","TrieNode","key","__publicField","Trie","_Trie","IterableElementBase","words","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","newTrie","_dfs","path","childNode","__yieldStar","str"]}
|