bst-typed 2.0.5 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/data-structures/base/iterable-element-base.d.ts +186 -83
  2. package/dist/data-structures/base/iterable-element-base.js +149 -107
  3. package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
  4. package/dist/data-structures/base/iterable-entry-base.js +59 -116
  5. package/dist/data-structures/base/linear-base.d.ts +250 -192
  6. package/dist/data-structures/base/linear-base.js +137 -274
  7. package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
  8. package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
  9. package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
  10. package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
  11. package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
  12. package/dist/data-structures/binary-tree/avl-tree.js +208 -195
  13. package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
  14. package/dist/data-structures/binary-tree/binary-tree.js +598 -869
  15. package/dist/data-structures/binary-tree/bst.d.ts +258 -306
  16. package/dist/data-structures/binary-tree/bst.js +505 -481
  17. package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
  18. package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
  19. package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
  20. package/dist/data-structures/binary-tree/tree-counter.js +172 -203
  21. package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
  22. package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
  23. package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
  24. package/dist/data-structures/graph/abstract-graph.js +267 -237
  25. package/dist/data-structures/graph/directed-graph.d.ts +108 -224
  26. package/dist/data-structures/graph/directed-graph.js +146 -233
  27. package/dist/data-structures/graph/map-graph.d.ts +49 -55
  28. package/dist/data-structures/graph/map-graph.js +56 -59
  29. package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
  30. package/dist/data-structures/graph/undirected-graph.js +129 -149
  31. package/dist/data-structures/hash/hash-map.d.ts +164 -338
  32. package/dist/data-structures/hash/hash-map.js +270 -457
  33. package/dist/data-structures/heap/heap.d.ts +214 -289
  34. package/dist/data-structures/heap/heap.js +340 -349
  35. package/dist/data-structures/heap/max-heap.d.ts +11 -47
  36. package/dist/data-structures/heap/max-heap.js +11 -66
  37. package/dist/data-structures/heap/min-heap.d.ts +12 -47
  38. package/dist/data-structures/heap/min-heap.js +11 -66
  39. package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
  40. package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
  41. package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
  42. package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
  43. package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
  44. package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
  45. package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
  46. package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
  47. package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
  48. package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
  49. package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
  50. package/dist/data-structures/priority-queue/priority-queue.js +8 -83
  51. package/dist/data-structures/queue/deque.d.ts +227 -254
  52. package/dist/data-structures/queue/deque.js +309 -348
  53. package/dist/data-structures/queue/queue.d.ts +180 -201
  54. package/dist/data-structures/queue/queue.js +265 -248
  55. package/dist/data-structures/stack/stack.d.ts +124 -102
  56. package/dist/data-structures/stack/stack.js +181 -125
  57. package/dist/data-structures/trie/trie.d.ts +164 -165
  58. package/dist/data-structures/trie/trie.js +189 -172
  59. package/dist/interfaces/binary-tree.d.ts +56 -6
  60. package/dist/interfaces/graph.d.ts +16 -0
  61. package/dist/types/data-structures/base/base.d.ts +1 -1
  62. package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
  63. package/dist/types/utils/utils.d.ts +1 -0
  64. package/dist/utils/utils.d.ts +1 -1
  65. package/dist/utils/utils.js +2 -1
  66. package/package.json +2 -2
  67. package/src/data-structures/base/iterable-element-base.ts +238 -115
  68. package/src/data-structures/base/iterable-entry-base.ts +96 -120
  69. package/src/data-structures/base/linear-base.ts +271 -277
  70. package/src/data-structures/binary-tree/avl-tree-counter.ts +198 -216
  71. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +192 -101
  72. package/src/data-structures/binary-tree/avl-tree.ts +239 -206
  73. package/src/data-structures/binary-tree/binary-tree.ts +664 -893
  74. package/src/data-structures/binary-tree/bst.ts +568 -570
  75. package/src/data-structures/binary-tree/red-black-tree.ts +161 -222
  76. package/src/data-structures/binary-tree/tree-counter.ts +199 -218
  77. package/src/data-structures/binary-tree/tree-multi-map.ts +131 -97
  78. package/src/data-structures/graph/abstract-graph.ts +339 -264
  79. package/src/data-structures/graph/directed-graph.ts +146 -236
  80. package/src/data-structures/graph/map-graph.ts +63 -60
  81. package/src/data-structures/graph/undirected-graph.ts +129 -152
  82. package/src/data-structures/hash/hash-map.ts +274 -496
  83. package/src/data-structures/heap/heap.ts +389 -402
  84. package/src/data-structures/heap/max-heap.ts +12 -76
  85. package/src/data-structures/heap/min-heap.ts +13 -76
  86. package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
  87. package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
  88. package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
  89. package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
  90. package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
  91. package/src/data-structures/priority-queue/priority-queue.ts +3 -92
  92. package/src/data-structures/queue/deque.ts +381 -357
  93. package/src/data-structures/queue/queue.ts +310 -264
  94. package/src/data-structures/stack/stack.ts +217 -131
  95. package/src/data-structures/trie/trie.ts +240 -175
  96. package/src/interfaces/binary-tree.ts +240 -6
  97. package/src/interfaces/graph.ts +37 -0
  98. package/src/types/data-structures/base/base.ts +5 -5
  99. package/src/types/data-structures/graph/abstract-graph.ts +5 -0
  100. package/src/types/utils/utils.ts +2 -0
  101. package/src/utils/utils.ts +9 -14
@@ -1,57 +1,76 @@
1
1
  "use strict";
2
+ /**
3
+ * data-structure-typed
4
+ *
5
+ * @author Pablo Zeng
6
+ * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
7
+ * @license MIT License
8
+ */
2
9
  Object.defineProperty(exports, "__esModule", { value: true });
3
10
  exports.Trie = exports.TrieNode = void 0;
4
11
  const base_1 = require("../base");
12
+ /**
13
+ * Node used by Trie to store one character and its children.
14
+ * @remarks Time O(1), Space O(1)
15
+ */
5
16
  class TrieNode {
17
+ /**
18
+ * Create a Trie node with a character key.
19
+ * @remarks Time O(1), Space O(1)
20
+ * @returns New TrieNode instance.
21
+ */
6
22
  constructor(key) {
7
23
  this._key = key;
8
24
  this._isEnd = false;
9
25
  this._children = new Map();
10
26
  }
11
27
  /**
12
- * The function returns the value of the protected variable _key.
13
- * @returns The value of the `_key` property, which is a string.
28
+ * Get the character key of this node.
29
+ * @remarks Time O(1), Space O(1)
30
+ * @returns Character key string.
14
31
  */
15
32
  get key() {
16
33
  return this._key;
17
34
  }
18
35
  /**
19
- * The above function sets the value of a protected variable called "key".
20
- * @param {string} value - The value parameter is a string that represents the value to be assigned
21
- * to the key.
36
+ * Set the character key of this node.
37
+ * @remarks Time O(1), Space O(1)
38
+ * @param value - New character key.
39
+ * @returns void
22
40
  */
23
41
  set key(value) {
24
42
  this._key = value;
25
43
  }
26
44
  /**
27
- * The function returns the children of a TrieNode as a Map.
28
- * @returns The `children` property of the TrieNode object, which is a Map containing string keys and
29
- * TrieNode values.
45
+ * Get the child map of this node.
46
+ * @remarks Time O(1), Space O(1)
47
+ * @returns Map from character to child node.
30
48
  */
31
49
  get children() {
32
50
  return this._children;
33
51
  }
34
52
  /**
35
- * The function sets the value of the `_children` property of a TrieNode object.
36
- * @param value - The value parameter is a Map object that represents the children of a TrieNode. The
37
- * keys of the map are strings, which represent the characters that are associated with each child
38
- * TrieNode. The values of the map are TrieNode objects, which represent the child nodes of the
39
- * current TrieNode.
53
+ * Replace the child map of this node.
54
+ * @remarks Time O(1), Space O(1)
55
+ * @param value - New map of character node.
56
+ * @returns void
40
57
  */
41
58
  set children(value) {
42
59
  this._children = value;
43
60
  }
44
61
  /**
45
- * The function returns a boolean value indicating whether a certain condition is met.
46
- * @returns The method is returning a boolean value, specifically the value of the variable `_isEnd`.
62
+ * Check whether this node marks the end of a word.
63
+ * @remarks Time O(1), Space O(1)
64
+ * @returns True if this node ends a word.
47
65
  */
48
66
  get isEnd() {
49
67
  return this._isEnd;
50
68
  }
51
69
  /**
52
- * The function sets the value of the "_isEnd" property.
53
- * @param {boolean} value - The value parameter is a boolean value that indicates whether the current
54
- * state is the end state or not.
70
+ * Mark this node as the end of a word or not.
71
+ * @remarks Time O(1), Space O(1)
72
+ * @param value - Whether this node ends a word.
73
+ * @returns void
55
74
  */
56
75
  set isEnd(value) {
57
76
  this._isEnd = value;
@@ -59,6 +78,9 @@ class TrieNode {
59
78
  }
60
79
  exports.TrieNode = TrieNode;
61
80
  /**
81
+ * Prefix tree (Trie) for fast prefix queries and word storage.
82
+ * @remarks Time O(1), Space O(1)
83
+ * @template R
62
84
  * 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.
63
85
  * 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'.
64
86
  * 3. Fast Retrieval: Trie allows retrieval in O(m) time complexity, where m is the length of the string to be searched.
@@ -154,16 +176,11 @@ exports.TrieNode = TrieNode;
154
176
  */
155
177
  class Trie extends base_1.IterableElementBase {
156
178
  /**
157
- * The constructor initializes a Trie data structure with optional options and words provided as
158
- * input.
159
- * @param {Iterable<string> | Iterable<R>} words - The `words` parameter in the constructor is an
160
- * iterable containing either strings or elements of type `R`. It is used to initialize the Trie with
161
- * a list of words or elements. If no `words` are provided, an empty iterable is used as the default
162
- * value.
163
- * @param [options] - The `options` parameter in the constructor is an optional object that can
164
- * contain configuration options for the Trie data structure. One of the options it can have is
165
- * `caseSensitive`, which is a boolean value indicating whether the Trie should be case-sensitive or
166
- * not. If `caseSensitive` is set to `
179
+ * Create a Trie and optionally bulk-insert words.
180
+ * @remarks Time O(totalChars), Space O(totalChars)
181
+ * @param [words] - Iterable of strings (or raw records if toElementFn is provided).
182
+ * @param [options] - Options such as toElementFn and caseSensitive.
183
+ * @returns New Trie instance.
167
184
  */
168
185
  constructor(words = [], options) {
169
186
  super(options);
@@ -180,33 +197,42 @@ class Trie extends base_1.IterableElementBase {
180
197
  }
181
198
  }
182
199
  /**
183
- * The size function returns the size of the stack.
184
- * @return The number of elements in the list
200
+ * Get the number of stored words.
201
+ * @remarks Time O(1), Space O(1)
202
+ * @returns Word count.
185
203
  */
186
204
  get size() {
187
205
  return this._size;
188
206
  }
189
207
  /**
190
- * The caseSensitive function is a getter that returns the value of the protected _caseSensitive property.
191
- * @return The value of the _caseSensitive protected variable
208
+ * Get whether comparisons are case-sensitive.
209
+ * @remarks Time O(1), Space O(1)
210
+ * @returns True if case-sensitive.
192
211
  */
193
212
  get caseSensitive() {
194
213
  return this._caseSensitive;
195
214
  }
196
215
  /**
197
- * The root function returns the root node of the tree.
198
- * @return The root node
216
+ * Get the root node.
217
+ * @remarks Time O(1), Space O(1)
218
+ * @returns Root TrieNode.
199
219
  */
200
220
  get root() {
201
221
  return this._root;
202
222
  }
203
223
  /**
204
- * Time Complexity: O(l), where l is the length of the word being added.
205
- * Space Complexity: O(l) - Each character in the word adds a TrieNode.
206
- *
207
- * Add a word to the Trie structure.
208
- * @param {string} word - The word to add.
209
- * @returns {boolean} True if the word was successfully added.
224
+ * (Protected) Get total count for base class iteration.
225
+ * @remarks Time O(1), Space O(1)
226
+ * @returns Total number of elements.
227
+ */
228
+ get _total() {
229
+ return this._size;
230
+ }
231
+ /**
232
+ * Insert one word into the trie.
233
+ * @remarks Time O(L), Space O(L)
234
+ * @param word - Word to insert.
235
+ * @returns True if the word was newly added.
210
236
  */
211
237
  add(word) {
212
238
  word = this._caseProcess(word);
@@ -228,16 +254,10 @@ class Trie extends base_1.IterableElementBase {
228
254
  return isNewWord;
229
255
  }
230
256
  /**
231
- * Time Complexity: O(n * l)
232
- * Space Complexity: O(1)
233
- *
234
- * The `addMany` function in TypeScript takes an iterable of strings or elements of type R, converts
235
- * them using a provided function if available, and adds them to a data structure while returning an
236
- * array of boolean values indicating success.
237
- * @param {Iterable<string> | Iterable<R>} words - The `words` parameter in the `addMany` function is
238
- * an iterable that contains either strings or elements of type `R`.
239
- * @returns The `addMany` method returns an array of boolean values indicating whether each word in
240
- * the input iterable was successfully added to the data structure.
257
+ * Insert many words from an iterable.
258
+ * @remarks Time O(ΣL), Space O(ΣL)
259
+ * @param words - Iterable of strings (or raw records if toElementFn is provided).
260
+ * @returns Array of per-word 'added' flags.
241
261
  */
242
262
  addMany(words) {
243
263
  const ans = [];
@@ -252,12 +272,10 @@ class Trie extends base_1.IterableElementBase {
252
272
  return ans;
253
273
  }
254
274
  /**
255
- * Time Complexity: O(l), where l is the length of the input word.
256
- * Space Complexity: O(1) - Constant space.
257
- *
258
- * Check if the Trie contains a given word.
259
- * @param {string} word - The word to check for.
260
- * @returns {boolean} True if the word is present in the Trie.
275
+ * Check whether a word exists.
276
+ * @remarks Time O(L), Space O(1)
277
+ * @param word - Word to search for.
278
+ * @returns True if present.
261
279
  */
262
280
  has(word) {
263
281
  word = this._caseProcess(word);
@@ -271,32 +289,27 @@ class Trie extends base_1.IterableElementBase {
271
289
  return cur.isEnd;
272
290
  }
273
291
  /**
274
- * Time Complexity: O(1)
275
- * Space Complexity: O(1)
276
- *
277
- * The isEmpty function checks if the size of the queue is 0.
278
- * @return True if the size of the queue is 0
292
+ * Check whether the trie is empty.
293
+ * @remarks Time O(1), Space O(1)
294
+ * @returns True if size is 0.
279
295
  */
280
296
  isEmpty() {
281
297
  return this._size === 0;
282
298
  }
283
299
  /**
284
- * Time Complexity: O(1)
285
- * Space Complexity: O(1)
286
- *
287
- * The clear function resets the size of the Trie to 0 and creates a new root TrieNode.
300
+ * Remove all words and reset to a fresh root.
301
+ * @remarks Time O(1), Space O(1)
302
+ * @returns void
288
303
  */
289
304
  clear() {
290
305
  this._size = 0;
291
306
  this._root = new TrieNode('');
292
307
  }
293
308
  /**
294
- * Time Complexity: O(l), where l is the length of the word being deleted.
295
- * Space Complexity: O(n) - Due to the recursive DFS approach.
296
- *
297
- * Remove a word from the Trie structure.
298
- * @param{string} word - The word to delete.
299
- * @returns {boolean} True if the word was successfully removed.
309
+ * Delete one word if present.
310
+ * @remarks Time O(L), Space O(1)
311
+ * @param word - Word to delete.
312
+ * @returns True if a word was removed.
300
313
  */
301
314
  delete(word) {
302
315
  word = this._caseProcess(word);
@@ -334,14 +347,9 @@ class Trie extends base_1.IterableElementBase {
334
347
  return isDeleted;
335
348
  }
336
349
  /**
337
- * Time Complexity: O(n)
338
- * Space Complexity: O(1)
339
- *
340
- * The function `getHeight` calculates the height of a trie data structure starting from the root
341
- * node.
342
- * @returns The `getHeight` method returns the maximum depth or height of the trie tree starting from
343
- * the root node. It calculates the depth using a breadth-first search (BFS) traversal of the trie
344
- * tree and returns the maximum depth found.
350
+ * Compute the height (max depth) of the trie.
351
+ * @remarks Time O(N), Space O(H)
352
+ * @returns Maximum depth from root to a leaf.
345
353
  */
346
354
  getHeight() {
347
355
  const startNode = this.root;
@@ -363,12 +371,10 @@ class Trie extends base_1.IterableElementBase {
363
371
  return maxDepth;
364
372
  }
365
373
  /**
366
- * Time Complexity: O(l), where l is the length of the input prefix.
367
- * Space Complexity: O(1) - Constant space.
368
- *
369
- * Check if a given input string has an absolute prefix in the Trie, meaning it's not a complete word.
370
- * @param {string} input - The input string to check.
371
- * @returns {boolean} True if it's an absolute prefix in the Trie.
374
+ * Check whether input is a proper prefix of at least one word.
375
+ * @remarks Time O(L), Space O(1)
376
+ * @param input - String to test as prefix.
377
+ * @returns True if input is a prefix but not a full word.
372
378
  */
373
379
  hasPurePrefix(input) {
374
380
  input = this._caseProcess(input);
@@ -382,12 +388,10 @@ class Trie extends base_1.IterableElementBase {
382
388
  return !cur.isEnd;
383
389
  }
384
390
  /**
385
- * Time Complexity: O(l), where l is the length of the input prefix.
386
- * Space Complexity: O(1) - Constant space.
387
- *
388
- * 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.
389
- * @param {string} input - The input string representing the prefix to check.
390
- * @returns {boolean} True if it's a prefix in the Trie.
391
+ * Check whether any word starts with input.
392
+ * @remarks Time O(L), Space O(1)
393
+ * @param input - String to test as prefix.
394
+ * @returns True if input matches a path from root.
391
395
  */
392
396
  hasPrefix(input) {
393
397
  input = this._caseProcess(input);
@@ -401,12 +405,10 @@ class Trie extends base_1.IterableElementBase {
401
405
  return true;
402
406
  }
403
407
  /**
404
- * Time Complexity: O(n), where n is the total number of nodes in the trie.
405
- * Space Complexity: O(l), where l is the length of the input prefix.
406
- *
407
- * Check if the input string is a common prefix in the Trie, meaning it's a prefix shared by all words in the Trie.
408
- * @param {string} input - The input string representing the common prefix to check for.
409
- * @returns {boolean} True if it's a common prefix in the Trie.
408
+ * Check whether the trie’s longest common prefix equals input.
409
+ * @remarks Time O(min(H,L)), Space O(1)
410
+ * @param input - Candidate longest common prefix.
411
+ * @returns True if input equals the common prefix.
410
412
  */
411
413
  hasCommonPrefix(input) {
412
414
  input = this._caseProcess(input);
@@ -426,11 +428,9 @@ class Trie extends base_1.IterableElementBase {
426
428
  return commonPre === input;
427
429
  }
428
430
  /**
429
- * Time Complexity: O(n), where n is the total number of nodes in the trie.
430
- * Space Complexity: O(l), where l is the length of the longest common prefix.
431
- *
432
- * Get the longest common prefix among all the words stored in the Trie.
433
- * @returns {string} The longest common prefix found in the Trie.
431
+ * Return the longest common prefix among all words.
432
+ * @remarks Time O(H), Space O(1)
433
+ * @returns The longest common prefix string.
434
434
  */
435
435
  getLongestCommonPrefix() {
436
436
  let commonPre = '';
@@ -447,15 +447,12 @@ class Trie extends base_1.IterableElementBase {
447
447
  return commonPre;
448
448
  }
449
449
  /**
450
- * Time Complexity: O(w * l), where w is the number of words retrieved, and l is the average length of the words.
451
- * Space Complexity: O(w * l) - The space required for the output array.
452
- *
453
- * The `getAll` function returns an array of all words in a Trie data structure that start with a given prefix.
454
- * @param {string} prefix - The `prefix` parameter is a string that represents the prefix that we want to search for in the
455
- * trie. It is an optional parameter, so if no prefix is provided, it will default to an empty string.
456
- * @param {number} max - The max count of words will be found
457
- * @param isAllWhenEmptyPrefix - If true, when the prefix provided as '', returns all the words in the trie.
458
- * @returns {string[]} an array of strings.
450
+ * Collect words under a prefix up to a maximum count.
451
+ * @remarks Time O(K·L), Space O(K·L)
452
+ * @param [prefix] - Prefix to match; default empty string for root.
453
+ * @param [max] - Maximum number of words to return; default is Number.MAX_SAFE_INTEGER.
454
+ * @param [isAllWhenEmptyPrefix] - When true, collect from root even if prefix is empty.
455
+ * @returns Array of collected words (at most max).
459
456
  */
460
457
  getWords(prefix = '', max = Number.MAX_SAFE_INTEGER, isAllWhenEmptyPrefix = false) {
461
458
  prefix = this._caseProcess(prefix);
@@ -483,7 +480,6 @@ class Trie extends base_1.IterableElementBase {
483
480
  startNode = nodeC;
484
481
  }
485
482
  else {
486
- // Early return if the whole prefix is not found
487
483
  return [];
488
484
  }
489
485
  }
@@ -493,32 +489,25 @@ class Trie extends base_1.IterableElementBase {
493
489
  return words;
494
490
  }
495
491
  /**
496
- * Time Complexity: O(n)
497
- * Space Complexity: O(n)
498
- *
499
- * The `clone` function returns a new instance of the Trie class with the same values and case
500
- * sensitivity as the original Trie.
501
- * @returns A new instance of the Trie class is being returned.
492
+ * Deep clone this trie by iterating and inserting all words.
493
+ * @remarks Time O(ΣL), Space O(ΣL)
494
+ * @returns A new trie with the same words and options.
502
495
  */
503
496
  clone() {
504
- return new Trie(this, { caseSensitive: this.caseSensitive, toElementFn: this.toElementFn });
505
- }
506
- /**
507
- * Time Complexity: O(n)
508
- * Space Complexity: O(n)
509
- *
510
- * The `filter` function takes a predicate function and returns a new array containing all the
511
- * elements for which the predicate function returns true.
512
- * @param predicate - The `predicate` parameter is a callback function that takes three arguments:
513
- * `word`, `index`, and `this`. It should return a boolean value indicating whether the current
514
- * element should be included in the filtered results or not.
515
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
516
- * specify the value of `this` within the `predicate` function. It is used when you want to bind a
517
- * specific object as the context for the `predicate` function. If `thisArg` is provided, it will be
518
- * @returns The `filter` method is returning an array of strings (`string[]`).
497
+ const next = this._createInstance();
498
+ for (const x of this)
499
+ next.add(x);
500
+ return next;
501
+ }
502
+ /**
503
+ * Filter words into a new trie of the same class.
504
+ * @remarks Time O(ΣL), Space O(ΣL)
505
+ * @param predicate - Predicate (word, index, trie) boolean to keep word.
506
+ * @param [thisArg] - Value for `this` inside the predicate.
507
+ * @returns A new trie containing words that satisfy the predicate.
519
508
  */
520
509
  filter(predicate, thisArg) {
521
- const results = new Trie([], { toElementFn: this.toElementFn, caseSensitive: this.caseSensitive });
510
+ const results = this._createInstance();
522
511
  let index = 0;
523
512
  for (const word of this) {
524
513
  if (predicate.call(thisArg, word, index, this)) {
@@ -528,39 +517,71 @@ class Trie extends base_1.IterableElementBase {
528
517
  }
529
518
  return results;
530
519
  }
531
- /**
532
- * Time Complexity: O(n)
533
- * Space Complexity: O(n)
534
- *
535
- * The `map` function creates a new Trie by applying a callback function to each element in the
536
- * current Trie.
537
- * @param callback - The callback parameter is a function that will be called for each element in the
538
- * Trie. It takes four arguments:
539
- * @param [toElementFn] - The `toElementFn` parameter is an optional function that can be used to
540
- * convert the raw element (`RM`) into a string representation. This can be useful if the raw element
541
- * is not already a string or if you want to customize how the element is converted into a string. If
542
- * this parameter is
543
- * @param {any} [thisArg] - The `thisArg` parameter is an optional argument that allows you to
544
- * specify the value of `this` within the callback function. It is used to set the context or scope
545
- * in which the callback function will be executed. If `thisArg` is provided, it will be used as the
546
- * value of
547
- * @returns a new Trie object.
548
- */
549
- map(callback, toElementFn, thisArg) {
550
- const newTrie = new Trie([], { toElementFn, caseSensitive: this.caseSensitive });
551
- let index = 0;
552
- for (const word of this) {
553
- newTrie.add(callback.call(thisArg, word, index, this));
554
- index++;
520
+ map(callback, options, thisArg) {
521
+ const newTrie = this._createLike([], options);
522
+ let i = 0;
523
+ for (const x of this) {
524
+ const v = thisArg === undefined ? callback(x, i++, this) : callback.call(thisArg, x, i++, this);
525
+ if (typeof v !== 'string') {
526
+ throw new TypeError(`Trie.map callback must return string; got ${typeof v}`);
527
+ }
528
+ newTrie.add(v);
555
529
  }
556
530
  return newTrie;
557
531
  }
558
532
  /**
559
- * Time Complexity: O(n)
560
- * Space Complexity: O(n)
561
- *
562
- * The function `_getIterator` returns an iterable iterator that performs a depth-first search on a
563
- * trie data structure and yields all the paths to the end nodes.
533
+ * Map words into a new trie of the same element type.
534
+ * @remarks Time O(ΣL), Space O(ΣL)
535
+ * @param callback - Mapping function (word, index, trie) → string.
536
+ * @param [thisArg] - Value for `this` inside the callback.
537
+ * @returns A new trie with mapped words.
538
+ */
539
+ mapSame(callback, thisArg) {
540
+ const next = this._createInstance();
541
+ let i = 0;
542
+ for (const key of this) {
543
+ const mapped = thisArg === undefined ? callback(key, i++, this) : callback.call(thisArg, key, i++, this);
544
+ next.add(mapped);
545
+ }
546
+ return next;
547
+ }
548
+ /**
549
+ * (Protected) Create an empty instance of the same concrete class.
550
+ * @remarks Time O(1), Space O(1)
551
+ * @param [options] - Options forwarded to the constructor.
552
+ * @returns An empty like-kind trie instance.
553
+ */
554
+ _createInstance(options) {
555
+ const Ctor = this.constructor;
556
+ const next = new Ctor([], Object.assign({ toElementFn: this.toElementFn, caseSensitive: this.caseSensitive }, (options !== null && options !== void 0 ? options : {})));
557
+ return next;
558
+ }
559
+ /**
560
+ * (Protected) Create a like-kind trie and seed it from an iterable.
561
+ * @remarks Time O(ΣL), Space O(ΣL)
562
+ * @template RM
563
+ * @param [elements] - Iterable used to seed the new trie.
564
+ * @param [options] - Options forwarded to the constructor.
565
+ * @returns A like-kind Trie instance.
566
+ */
567
+ _createLike(elements = [], options) {
568
+ const Ctor = this.constructor;
569
+ return new Ctor(elements, options);
570
+ }
571
+ /**
572
+ * (Protected) Spawn an empty like-kind trie instance.
573
+ * @remarks Time O(1), Space O(1)
574
+ * @template RM
575
+ * @param [options] - Options forwarded to the constructor.
576
+ * @returns An empty like-kind Trie instance.
577
+ */
578
+ _spawnLike(options) {
579
+ return this._createLike([], options);
580
+ }
581
+ /**
582
+ * (Protected) Iterate all words in lexicographic order of edges.
583
+ * @remarks Time O(ΣL), Space O(H)
584
+ * @returns Iterator of words.
564
585
  */
565
586
  *_getIterator() {
566
587
  function* _dfs(node, path) {
@@ -573,19 +594,15 @@ class Trie extends base_1.IterableElementBase {
573
594
  }
574
595
  yield* _dfs(this.root, '');
575
596
  }
576
- get _total() {
577
- return this._size;
578
- }
579
597
  /**
580
- * Time Complexity: O(l), where l is the length of the input string.
581
- * Space Complexity: O(1) - Constant space.
582
- *
583
- * @param str
584
- * @protected
598
+ * (Protected) Normalize a string according to case sensitivity.
599
+ * @remarks Time O(L), Space O(L)
600
+ * @param str - Input string to normalize.
601
+ * @returns Normalized string based on caseSensitive.
585
602
  */
586
603
  _caseProcess(str) {
587
604
  if (!this._caseSensitive) {
588
- str = str.toLowerCase(); // Convert str to lowercase if case-insensitive
605
+ str = str.toLowerCase();
589
606
  }
590
607
  return str;
591
608
  }
@@ -1,9 +1,59 @@
1
1
  import { BinaryTreeNode } from '../data-structures';
2
- import type { BinaryTreeDeleteResult, BinaryTreeOptions, BTNRep, NodePredicate } from '../types';
3
- export interface IBinaryTree<K = any, V = any, R = object, MK = any, MV = any, MR = object> {
4
- createNode(key: K, value?: BinaryTreeNode['value']): BinaryTreeNode;
5
- createTree(options?: Partial<BinaryTreeOptions<K, V, R>>): IBinaryTree<K, V, R, MK, MV, MR>;
2
+ import type { BinaryTreeDeleteResult, BinaryTreeOptions, BTNRep, DFSOrderPattern, EntryCallback, IterationType, NodeCallback, NodePredicate, OptNodeOrNull, ReduceEntryCallback, ToEntryFn } from '../types';
3
+ /**
4
+ * Public, implementation-agnostic binary tree API.
5
+ * K = key, V = value, R = raw/record used with toEntryFn (optional).
6
+ * Transforming methods like `map` use method-level generics MK/MV/MR.
7
+ */
8
+ export interface IBinaryTree<K = any, V = any, R extends object = object> {
9
+ readonly size: number;
10
+ readonly root: BinaryTreeNode<K, V> | null | undefined;
11
+ readonly isMapMode: boolean;
12
+ iterationType: IterationType;
13
+ readonly NIL: BinaryTreeNode<K, V>;
14
+ readonly store: Map<K, V | undefined>;
15
+ readonly toEntryFn?: ToEntryFn<K, V, R>;
16
+ readonly isDuplicate: boolean;
17
+ _createNode(key: K, value?: BinaryTreeNode<K, V>['value']): BinaryTreeNode<K, V>;
18
+ createTree(options?: Partial<BinaryTreeOptions<K, V, R>>): IBinaryTree<K, V, R>;
6
19
  add(keyOrNodeOrEntryOrRawElement: BTNRep<K, V, BinaryTreeNode<K, V>>, value?: V, count?: number): boolean;
7
- addMany(nodes: Iterable<BTNRep<K, V, BinaryTreeNode<K, V>>>, values?: Iterable<V | undefined>): boolean[];
8
- delete(predicate: R | BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V>>): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[];
20
+ addMany(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, values?: Iterable<V | undefined>): boolean[];
21
+ delete(keyNodeEntryRawOrPredicate: R | BTNRep<K, V, BinaryTreeNode<K, V>> | NodePredicate<BinaryTreeNode<K, V> | null>): BinaryTreeDeleteResult<BinaryTreeNode<K, V>>[];
22
+ clear(): void;
23
+ isEmpty(): boolean;
24
+ get(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): V | undefined;
25
+ has(keyNodeEntryOrPredicate?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V> | null>, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): boolean;
26
+ hasValue(value: V): boolean;
27
+ find(predicate: EntryCallback<K, V | undefined, boolean>, thisArg?: unknown): [K, V | undefined] | undefined;
28
+ [Symbol.iterator](): IterableIterator<[K, V | undefined]>;
29
+ entries(): IterableIterator<[K, V | undefined]>;
30
+ keys(): IterableIterator<K>;
31
+ values(): IterableIterator<V | undefined>;
32
+ forEach(callbackfn: EntryCallback<K, V | undefined, void>, thisArg?: unknown): void;
33
+ every(callbackfn: EntryCallback<K, V | undefined, boolean>, thisArg?: unknown): boolean;
34
+ some(callbackfn: EntryCallback<K, V | undefined, boolean>, thisArg?: unknown): boolean;
35
+ reduce<U>(reducer: ReduceEntryCallback<K, V | undefined, U>, initialValue: U): U;
36
+ getNode(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V> | null>, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): OptNodeOrNull<BinaryTreeNode<K, V>>;
37
+ getLeftMost<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>;
38
+ getRightMost<C extends NodeCallback<BinaryTreeNode<K, V> | undefined>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>;
39
+ dfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback?: C, pattern?: DFSOrderPattern, onlyOne?: boolean, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[];
40
+ dfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, pattern?: DFSOrderPattern, onlyOne?: boolean, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: boolean): ReturnType<C>[];
41
+ bfs<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: false): ReturnType<C>[];
42
+ bfs<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: true): ReturnType<C>[];
43
+ morris<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, pattern?: DFSOrderPattern, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): ReturnType<C>[];
44
+ leaves<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[];
45
+ listLevels<C extends NodeCallback<BinaryTreeNode<K, V>>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: false): ReturnType<C>[][];
46
+ listLevels<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType, includeNull?: true): ReturnType<C>[][];
47
+ getPathToRoot<C extends NodeCallback<OptNodeOrNull<BinaryTreeNode<K, V>>>>(beginNode: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, callback?: C, isReverse?: boolean): ReturnType<C>[];
48
+ getDepth(dist: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): number;
49
+ getHeight(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): number;
50
+ getMinHeight(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): number;
51
+ isPerfectlyBalanced(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined): boolean;
52
+ isBST(startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): boolean;
53
+ search<C extends NodeCallback<BinaryTreeNode<K, V> | null>>(keyNodeEntryOrPredicate: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | NodePredicate<BinaryTreeNode<K, V> | null>, onlyOne?: boolean, callback?: C, startNode?: K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined, iterationType?: IterationType): ReturnType<C>[];
54
+ clone(): this;
55
+ filter(predicate: EntryCallback<K, V | undefined, boolean>, thisArg?: unknown): this;
56
+ map<MK = K, MV = V, MR extends object = object>(callback: EntryCallback<K, V | undefined, [MK, MV]>, options?: Partial<BinaryTreeOptions<MK, MV, MR>>, thisArg?: unknown): IBinaryTree<MK, MV, MR>;
57
+ merge(anotherTree: IBinaryTree<K, V, R>): void;
58
+ refill(keysNodesEntriesOrRaws: Iterable<K | BinaryTreeNode<K, V> | [K | null | undefined, V | undefined] | null | undefined | R>, values?: Iterable<V | undefined>): void;
9
59
  }
@@ -2,4 +2,20 @@ import { VertexKey } from '../types';
2
2
  export interface IGraph<V, E, VO, EO> {
3
3
  createVertex(key: VertexKey, value?: V): VO;
4
4
  createEdge(srcOrV1: VertexKey, destOrV2: VertexKey, weight?: number, value?: E): EO;
5
+ getVertex(vertexKey: VertexKey): VO | undefined;
6
+ hasVertex(vertexOrKey: VO | VertexKey): boolean;
7
+ addVertex(vertex: VO): boolean;
8
+ addVertex(key: VertexKey, value?: V): boolean;
9
+ deleteVertex(vertexOrKey: VO | VertexKey): boolean;
10
+ deleteEdge(edge: EO): EO | undefined;
11
+ getEdge(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | undefined;
12
+ degreeOf(vertexOrKey: VO | VertexKey): number;
13
+ edgeSet(): EO[];
14
+ edgesOf(vertexOrKey: VO | VertexKey): EO[];
15
+ getNeighbors(vertexOrKey: VO | VertexKey): VO[];
16
+ getEndsOfEdge(edge: EO): [VO, VO] | undefined;
17
+ isEmpty(): boolean;
18
+ clear(): void;
19
+ clone(): this;
20
+ filter(...args: any[]): this;
5
21
  }