data-structure-typed 1.36.9 → 1.37.1

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 (39) hide show
  1. package/CHANGELOG.md +2 -1
  2. package/dist/data-structures/binary-tree/binary-tree.d.ts +1 -11
  3. package/dist/data-structures/binary-tree/binary-tree.js +8 -57
  4. package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
  5. package/dist/data-structures/binary-tree/bst.d.ts +6 -20
  6. package/dist/data-structures/binary-tree/bst.js +22 -122
  7. package/dist/data-structures/binary-tree/bst.js.map +1 -1
  8. package/dist/data-structures/binary-tree/tree-multiset.d.ts +1 -55
  9. package/dist/data-structures/binary-tree/tree-multiset.js +3 -240
  10. package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
  11. package/dist/data-structures/graph/abstract-graph.js +4 -3
  12. package/dist/data-structures/graph/abstract-graph.js.map +1 -1
  13. package/lib/data-structures/binary-tree/binary-tree.d.ts +1 -11
  14. package/lib/data-structures/binary-tree/binary-tree.js +8 -57
  15. package/lib/data-structures/binary-tree/bst.d.ts +6 -20
  16. package/lib/data-structures/binary-tree/bst.js +22 -122
  17. package/lib/data-structures/binary-tree/tree-multiset.d.ts +1 -55
  18. package/lib/data-structures/binary-tree/tree-multiset.js +3 -240
  19. package/lib/data-structures/graph/abstract-graph.js +4 -3
  20. package/package.json +9 -7
  21. package/src/data-structures/binary-tree/binary-tree.ts +100 -504
  22. package/src/data-structures/binary-tree/bst.ts +58 -128
  23. package/src/data-structures/binary-tree/tree-multiset.ts +2 -312
  24. package/src/data-structures/graph/abstract-graph.ts +4 -3
  25. package/src/data-structures/heap/heap.ts +1 -1
  26. package/src/types/data-structures/binary-tree.ts +4 -0
  27. package/src/types/data-structures/index.ts +3 -0
  28. package/test/unit/data-structures/binary-tree/avl-tree.test.ts +14 -9
  29. package/test/unit/data-structures/binary-tree/binary-tree.test.ts +1 -1
  30. package/test/unit/data-structures/binary-tree/bst.test.ts +85 -18
  31. package/test/unit/data-structures/binary-tree/overall.test.ts +3 -2
  32. package/test/unit/data-structures/binary-tree/rb-tree.test.ts +5 -5
  33. package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +43 -18
  34. package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +1 -1
  35. package/test/unit/data-structures/queue/deque.test.ts +17 -0
  36. package/test/unit/data-structures/queue/queue.test.ts +42 -0
  37. package/test/utils/big-o.ts +5 -4
  38. package/umd/bundle.min.js +1 -1
  39. package/umd/bundle.min.js.map +1 -1
@@ -7,14 +7,16 @@
7
7
  */
8
8
  import type {
9
9
  BinaryTreeNodeKey,
10
- BinaryTreeNodePropertyName,
11
10
  BSTComparator,
12
11
  BSTNodeNested,
13
- BSTOptions
12
+ BSTOptions,
13
+ MapCallback,
14
+ MapCallbackReturn
14
15
  } from '../../types';
15
16
  import {CP, LoopType} from '../../types';
16
17
  import {BinaryTree, BinaryTreeNode} from './binary-tree';
17
18
  import {IBinaryTree} from '../../interfaces';
19
+ import {Queue} from '../queue';
18
20
 
19
21
  export class BSTNode<V = any, FAMILY extends BSTNode<V, FAMILY> = BSTNodeNested<V>> extends BinaryTreeNode<V, FAMILY> {
20
22
  constructor(key: BinaryTreeNodeKey, val?: V) {
@@ -59,7 +61,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
59
61
  * @returns The function `add` returns the inserted node (`inserted`) which can be of type `N`, `null`, or `undefined`.
60
62
  */
61
63
  override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined {
62
- // TODO support node as a param
64
+ // TODO support node as a parameter
63
65
  let inserted: N | null = null;
64
66
  let newNode: N | null = null;
65
67
  if (keyOrNode instanceof BSTNode) {
@@ -137,8 +139,9 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
137
139
  override addMany(
138
140
  keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[],
139
141
  data?: N['val'][],
140
- isBalanceAdd = false
142
+ isBalanceAdd = true
141
143
  ): (N | null | undefined)[] {
144
+ // TODO this addMany function is inefficient, it should be optimized
142
145
  function hasNoNull(arr: (BinaryTreeNodeKey | null)[] | (N | null)[]): arr is BinaryTreeNodeKey[] | N[] {
143
146
  return arr.indexOf(null) === -1;
144
147
  }
@@ -209,12 +212,12 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
209
212
  * The function returns the first node in a binary tree that matches the given property name and value.
210
213
  * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or a
211
214
  * generic type `N`. It represents the property of the binary tree node that you want to search for.
212
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
215
+ * @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a value.
213
216
  * specifies the property name to use for searching the binary tree nodes. If not provided, it defaults to `'key'`.
214
217
  * @returns The method is returning either a BinaryTreeNodeKey or N (generic type) or null.
215
218
  */
216
- override get(nodeProperty: BinaryTreeNodeKey | N, propertyName: BinaryTreeNodePropertyName = 'key'): N | null {
217
- return this.getNodes(nodeProperty, propertyName, true)[0] ?? null;
219
+ override get(nodeProperty: BinaryTreeNodeKey | N, callback: MapCallback<N> = this._defaultCallbackByKey): N | null {
220
+ return this.getNodes(nodeProperty, callback, true)[0] ?? null;
218
221
  }
219
222
 
220
223
  /**
@@ -234,27 +237,34 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
234
237
  * The function `getNodes` returns an array of nodes in a binary tree that match a given property value.
235
238
  * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or an
236
239
  * `N` type. It represents the property of the binary tree node that you want to compare with.
237
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
240
+ * @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a value.
238
241
  * specifies the property name to use for comparison. If not provided, it defaults to `'key'`.
239
242
  * @param {boolean} [onlyOne] - The `onlyOne` parameter is an optional boolean parameter that determines whether to
240
243
  * return only one node that matches the given `nodeProperty` or all nodes that match the `nodeProperty`. If `onlyOne`
241
244
  * is set to `true`, the function will return an array with only one node (if
245
+ * @param beginRoot - The `beginRoot` parameter is an optional parameter that specifies the root node from which to
242
246
  * @returns an array of nodes (type N).
243
247
  */
244
248
  override getNodes(
245
249
  nodeProperty: BinaryTreeNodeKey | N,
246
- propertyName: BinaryTreeNodePropertyName = 'key',
247
- onlyOne = false
250
+ callback: MapCallback<N> = this._defaultCallbackByKey,
251
+ onlyOne = false,
252
+ beginRoot: N | null = this.root
248
253
  ): N[] {
249
- if (!this.root) return [];
250
- const result: N[] = [];
254
+ if (!beginRoot) return [];
255
+ const ans: N[] = [];
251
256
 
252
257
  if (this.loopType === LoopType.RECURSIVE) {
253
258
  const _traverse = (cur: N) => {
254
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return;
259
+ const callbackResult = callback(cur);
260
+ if (callbackResult === nodeProperty) {
261
+ ans.push(cur);
262
+ if (onlyOne) return;
263
+ }
255
264
 
256
265
  if (!cur.left && !cur.right) return;
257
- if (propertyName === 'key') {
266
+ // TODO potential bug
267
+ if (callback === this._defaultCallbackByKey) {
258
268
  if (this._compare(cur.key, nodeProperty as number) === CP.gt) cur.left && _traverse(cur.left);
259
269
  if (this._compare(cur.key, nodeProperty as number) === CP.lt) cur.right && _traverse(cur.right);
260
270
  } else {
@@ -263,14 +273,19 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
263
273
  }
264
274
  };
265
275
 
266
- _traverse(this.root);
276
+ _traverse(beginRoot);
267
277
  } else {
268
- const queue: N[] = [this.root];
269
- while (queue.length > 0) {
278
+ const queue = new Queue<N>([beginRoot]);
279
+ while (queue.size > 0) {
270
280
  const cur = queue.shift();
271
281
  if (cur) {
272
- if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return result;
273
- if (propertyName === 'key') {
282
+ const callbackResult = callback(cur);
283
+ if (callbackResult === nodeProperty) {
284
+ ans.push(cur);
285
+ if (onlyOne) return ans;
286
+ }
287
+ // TODO potential bug
288
+ if (callback === this._defaultCallbackByKey) {
274
289
  if (this._compare(cur.key, nodeProperty as number) === CP.gt) cur.left && queue.push(cur.left);
275
290
  if (this._compare(cur.key, nodeProperty as number) === CP.lt) cur.right && queue.push(cur.right);
276
291
  } else {
@@ -281,140 +296,55 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
281
296
  }
282
297
  }
283
298
 
284
- return result;
299
+ return ans;
285
300
  }
286
301
 
287
302
  // --- start additional functions
288
- /**
289
- * The `lesserSum` function calculates the sum of property values in a binary tree for nodes that have a property value
290
- * less than a given node.
291
- * @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
292
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
293
- * specifies the property name to use for calculating the sum. If not provided, it defaults to `'key'`.
294
- * @returns The function `lesserSum` returns a number, which represents the sum of the values of the nodes in the
295
- * binary tree that have a lesser value than the specified `beginNode` based on the `propertyName`.
296
- */
297
- lesserSum(beginNode: N | BinaryTreeNodeKey | null, propertyName: BinaryTreeNodePropertyName = 'key'): number {
298
- if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'key');
299
- if (!beginNode) return 0;
300
- if (!this.root) return 0;
301
- const key = beginNode.key;
302
- const getSumByPropertyName = (cur: N) => {
303
- let needSum: number;
304
- switch (propertyName) {
305
- case 'key':
306
- needSum = cur.key;
307
- break;
308
- default:
309
- needSum = cur.key;
310
- break;
311
- }
312
- return needSum;
313
- };
314
-
315
- let sum = 0;
316
-
317
- if (this.loopType === LoopType.RECURSIVE) {
318
- const _traverse = (cur: N): void => {
319
- const compared = this._compare(cur.key, key);
320
- if (compared === CP.eq) {
321
- if (cur.right) sum += this.subTreeSum(cur.right, propertyName);
322
- return;
323
- } else if (compared === CP.lt) {
324
- if (cur.left) sum += this.subTreeSum(cur.left, propertyName);
325
- sum += getSumByPropertyName(cur);
326
- if (cur.right) _traverse(cur.right);
327
- else return;
328
- } else {
329
- if (cur.left) _traverse(cur.left);
330
- else return;
331
- }
332
- };
333
-
334
- _traverse(this.root);
335
- } else {
336
- const queue: N[] = [this.root];
337
- while (queue.length > 0) {
338
- const cur = queue.shift();
339
- if (cur) {
340
- const compared = this._compare(cur.key, key);
341
- if (compared === CP.eq) {
342
- if (cur.right) sum += this.subTreeSum(cur.right, propertyName);
343
- return sum;
344
- } else if (compared === CP.lt) {
345
- // todo maybe a bug
346
- if (cur.left) sum += this.subTreeSum(cur.left, propertyName);
347
- sum += getSumByPropertyName(cur);
348
- if (cur.right) queue.push(cur.right);
349
- else return sum;
350
- } else {
351
- if (cur.left) queue.push(cur.left);
352
- else return sum;
353
- }
354
- }
355
- }
356
- }
357
-
358
- return sum;
359
- }
360
303
 
361
304
  /**
362
- * The `allGreaterNodesAdd` function adds a delta value to the specified property of all nodes in a binary tree that
305
+ * The `lesserOrGreaterTraverse` function adds a delta value to the specified property of all nodes in a binary tree that
363
306
  * have a greater value than a given node.
364
- * @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type),
365
- * `BinaryTreeNodeKey`, or `null`. It represents the node in the binary tree to which the delta value will be added.
366
- * @param {number} delta - The `delta` parameter is a number that represents the amount by which the property value of
367
- * each greater node should be increased.
368
- * @param {BinaryTreeNodePropertyName} [propertyName] - The `propertyName` parameter is an optional parameter that
369
- * specifies the property name of the nodes in the binary tree that you want to update. If not provided, it defaults to
370
- * 'key'.
371
- * @returns a boolean value.
307
+ * @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a value.
308
+ * @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type), `BinaryTreeNodeKey`, or `null`. It
309
+ * represents the node in the binary tree to which the delta value will be added.
310
+ * @param lesserOrGreater - The `lesserOrGreater` parameter is an optional parameter that specifies whether the delta
372
311
  */
373
- allGreaterNodesAdd(
374
- node: N | BinaryTreeNodeKey | null,
375
- delta: number,
376
- propertyName: BinaryTreeNodePropertyName = 'key'
377
- ): boolean {
378
- if (typeof node === 'number') node = this.get(node, 'key');
379
- if (!node) return false;
312
+ lesserOrGreaterTraverse(
313
+ callback: MapCallback<N> = this._defaultCallbackByKey,
314
+ lesserOrGreater: CP = CP.lt,
315
+ node: N | BinaryTreeNodeKey | null
316
+ ): MapCallbackReturn<N> {
317
+ if (typeof node === 'number') node = this.get(node);
318
+ const ans: MapCallbackReturn<N>[] = [];
319
+ if (!node) return [];
380
320
  const key = node.key;
381
321
  if (!this.root) return false;
382
322
 
383
- const _sumByPropertyName = (cur: N) => {
384
- switch (propertyName) {
385
- case 'key':
386
- cur.key += delta;
387
- break;
388
- default:
389
- cur.key += delta;
390
- break;
391
- }
392
- };
393
323
  if (this.loopType === LoopType.RECURSIVE) {
394
324
  const _traverse = (cur: N) => {
395
325
  const compared = this._compare(cur.key, key);
396
- if (compared === CP.gt) _sumByPropertyName(cur);
326
+ if (compared === lesserOrGreater) ans.push(callback(cur));
397
327
 
398
328
  if (!cur.left && !cur.right) return;
399
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) _traverse(cur.left);
400
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) _traverse(cur.right);
329
+ if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater) _traverse(cur.left);
330
+ if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater) _traverse(cur.right);
401
331
  };
402
332
 
403
333
  _traverse(this.root);
404
334
  return true;
405
335
  } else {
406
- const queue: N[] = [this.root];
407
- while (queue.length > 0) {
336
+ const queue = new Queue<N>([this.root]);
337
+ while (queue.size > 0) {
408
338
  const cur = queue.shift();
409
339
  if (cur) {
410
340
  const compared = this._compare(cur.key, key);
411
- if (compared === CP.gt) _sumByPropertyName(cur);
341
+ if (compared === lesserOrGreater) ans.push(callback(cur));
412
342
 
413
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) queue.push(cur.left);
414
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) queue.push(cur.right);
343
+ if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater) queue.push(cur.left);
344
+ if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater) queue.push(cur.right);
415
345
  }
416
346
  }
417
- return true;
347
+ return ans;
418
348
  }
419
349
  }
420
350
 
@@ -434,7 +364,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
434
364
  * @returns The function `perfectlyBalance()` returns a boolean value.
435
365
  */
436
366
  perfectlyBalance(): boolean {
437
- const sorted = this.dfs('in', 'node'),
367
+ const sorted = this.dfs(node => node, 'in'),
438
368
  n = sorted.length;
439
369
  this.clear();
440
370
 
@@ -6,7 +6,7 @@
6
6
  * @license MIT License
7
7
  */
8
8
  import type {BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions} from '../../types';
9
- import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType} from '../../types';
9
+ import {BinaryTreeDeletedResult, CP, FamilyPosition, LoopType} from '../../types';
10
10
  import {IBinaryTree} from '../../interfaces';
11
11
  import {AVLTree, AVLTreeNode} from './avl-tree';
12
12
 
@@ -247,7 +247,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
247
247
  * @returns The function `perfectlyBalance()` returns a boolean value.
248
248
  */
249
249
  override perfectlyBalance(): boolean {
250
- const sorted = this.dfs('in', 'node'),
250
+ const sorted = this.dfs(node => node, 'in'),
251
251
  n = sorted.length;
252
252
  if (sorted.length < 1) return false;
253
253
 
@@ -349,316 +349,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
349
349
  return bstDeletedResult;
350
350
  }
351
351
 
352
- /**
353
- * The function `getSubTreeCount` calculates the number of nodes and the sum of their counts in a subtree, using either
354
- * recursive or iterative traversal.
355
- * @param {N | null | undefined} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree in a
356
- * binary tree.
357
- * @returns The function `getSubTreeCount` returns an array `[number, number]`.
358
- */
359
- getSubTreeCount(subTreeRoot: N | null | undefined) {
360
- const res: [number, number] = [0, 0];
361
- if (!subTreeRoot) return res;
362
-
363
- if (this.loopType === LoopType.RECURSIVE) {
364
- const _traverse = (cur: N) => {
365
- res[0]++;
366
- res[1] += cur.count;
367
- cur.left && _traverse(cur.left);
368
- cur.right && _traverse(cur.right);
369
- };
370
-
371
- _traverse(subTreeRoot);
372
- return res;
373
- } else {
374
- const stack: N[] = [subTreeRoot];
375
-
376
- while (stack.length > 0) {
377
- const cur = stack.pop()!;
378
- res[0]++;
379
- res[1] += cur.count;
380
- cur.right && stack.push(cur.right);
381
- cur.left && stack.push(cur.left);
382
- }
383
-
384
- return res;
385
- }
386
- }
387
-
388
- /**
389
- * The function `subTreeSumCount` calculates the sum of the `count` property of each node in a subtree, either
390
- * recursively or iteratively.
391
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree
392
- * in a binary tree. It can be either a `BinaryTreeNodeKey` (a unique identifier for a node in the binary tree) or
393
- * `null` if the subtree is empty.
394
- * @returns the sum of the count values of all nodes in the subtree rooted at `subTreeRoot`.
395
- */
396
- subTreeSumCount(subTreeRoot: N | BinaryTreeNodeKey | null): number {
397
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
398
-
399
- if (!subTreeRoot) return 0;
400
-
401
- let sum = 0;
402
-
403
- if (this.loopType === LoopType.RECURSIVE) {
404
- const _traverse = (cur: N): void => {
405
- sum += cur.count;
406
- cur.left && _traverse(cur.left);
407
- cur.right && _traverse(cur.right);
408
- };
409
-
410
- _traverse(subTreeRoot);
411
- } else {
412
- const stack: N[] = [subTreeRoot];
413
-
414
- while (stack.length > 0) {
415
- const cur = stack.pop()!;
416
- sum += cur.count;
417
- cur.right && stack.push(cur.right);
418
- cur.left && stack.push(cur.left);
419
- }
420
- }
421
-
422
- return sum;
423
- }
424
-
425
- /**
426
- * The function `subTreeAddCount` recursively or iteratively traverses a binary tree and adds a given delta value to
427
- * the `count` property of each node.
428
- * @param {N | BinaryTreeNodeKey | null} subTreeRoot - The `subTreeRoot` parameter represents the root node of a subtree
429
- * in a binary tree. It can be either a `BinaryTreeNodeKey` (a unique identifier for a node in the binary tree), a
430
- * `BinaryTreeNode` object, or `null` if the subtree is empty.
431
- * @param {number} delta - The delta parameter is a number that represents the amount by which the count of each node
432
- * in the subtree should be increased or decreased.
433
- * @returns a boolean value.
434
- */
435
- subTreeAddCount(subTreeRoot: N | BinaryTreeNodeKey | null, delta: number): boolean {
436
- if (typeof subTreeRoot === 'number') subTreeRoot = this.get(subTreeRoot, 'key');
437
-
438
- if (!subTreeRoot) return false;
439
-
440
- const _addByProperty = (cur: N) => {
441
- cur.count += delta;
442
- this._setCount(this.count + delta);
443
- };
444
-
445
- if (this.loopType === LoopType.RECURSIVE) {
446
- const _traverse = (cur: N) => {
447
- _addByProperty(cur);
448
- cur.left && _traverse(cur.left);
449
- cur.right && _traverse(cur.right);
450
- };
451
-
452
- _traverse(subTreeRoot);
453
- } else {
454
- const stack: N[] = [subTreeRoot];
455
-
456
- while (stack.length > 0) {
457
- const cur = stack.pop()!;
458
-
459
- _addByProperty(cur);
460
- cur.right && stack.push(cur.right);
461
- cur.left && stack.push(cur.left);
462
- }
463
- }
464
- return true;
465
- }
466
-
467
- /**
468
- * The function `getNodesByCount` returns an array of nodes that have a specific count property, either recursively or
469
- * using a queue.
470
- * @param {BinaryTreeNodeKey | N} nodeProperty - The `nodeProperty` parameter can be either a `BinaryTreeNodeKey` or a
471
- * `N`. It represents the property of the nodes that you want to search for.
472
- * @param {boolean} [onlyOne] - The `onlyOne` parameter is an optional boolean parameter that determines whether to
473
- * return only one node that matches the `nodeProperty` or all nodes that match the `nodeProperty`. If `onlyOne` is set
474
- * to `true`, the function will return only one node. If `onlyOne`
475
- * @returns an array of nodes that match the given nodeProperty.
476
- */
477
- getNodesByCount(nodeProperty: BinaryTreeNodeKey | N, onlyOne = false): N[] {
478
- if (!this.root) return [];
479
- const result: N[] = [];
480
-
481
- if (this.loopType === LoopType.RECURSIVE) {
482
- const _traverse = (cur: N) => {
483
- if (cur.count === nodeProperty) {
484
- result.push(cur);
485
- if (onlyOne) return;
486
- }
487
-
488
- if (!cur.left && !cur.right) return;
489
- cur.left && _traverse(cur.left);
490
- cur.right && _traverse(cur.right);
491
- };
492
-
493
- _traverse(this.root);
494
- } else {
495
- const queue: N[] = [this.root];
496
- while (queue.length > 0) {
497
- const cur = queue.shift();
498
- if (cur) {
499
- if (cur.count === nodeProperty) {
500
- result.push(cur);
501
- if (onlyOne) return result;
502
- }
503
-
504
- cur.left && queue.push(cur.left);
505
- cur.right && queue.push(cur.right);
506
- }
507
- }
508
- }
509
-
510
- return result;
511
- }
512
-
513
- /**
514
- * The BFSCount function returns an array of counts from a breadth-first search of nodes.
515
- * @returns The BFSCount() function returns an array of numbers, specifically the count property of each node in the
516
- * bfs traversal.
517
- */
518
- bfsCount(): number[] {
519
- const nodes = super.bfs('node');
520
- return nodes.map(node => node.count);
521
- }
522
-
523
- /**
524
- * The function "listLevelsCount" takes a node and returns an array of arrays, where each inner array contains the
525
- * count property of each node at that level.
526
- * @param {N | null} node - The parameter `node` is of type `N | null`. This means that it can either be an instance of
527
- * the class `N` or `null`.
528
- * @returns a 2D array of numbers. Each inner array represents a level in the binary tree, and each number in the inner
529
- * array represents the count property of a node in that level.
530
- */
531
- listLevelsCount(node: N | null): number[][] {
532
- const levels = super.listLevels(node, 'node');
533
- return levels.map(level => level.map(node => node.count));
534
- }
535
-
536
- /**
537
- * The `morrisCount` function returns an array of counts for each node in a binary tree, based on a specified traversal
538
- * pattern.
539
- * @param {'in' | 'pre' | 'post'} [pattern] - The `pattern` parameter is an optional parameter that specifies the
540
- * traversal pattern for the Morris traversal algorithm. It can have one of three values: 'in', 'pre', or 'post'.
541
- * @returns The function `morrisCount` returns an array of numbers.
542
- */
543
- morrisCount(pattern: DFSOrderPattern = 'in'): number[] {
544
- const nodes = super.morris(pattern, 'node');
545
- return nodes.map(node => node.count);
546
- }
547
-
548
- /**
549
- * The function dfsCountIterative performs an iterative depth-first search and returns an array of node counts based on
550
- * the specified traversal pattern.
551
- * @param {'in' | 'pre' | 'post'} [pattern] - The pattern parameter is a string that specifies the traversal order for
552
- * the Depth-First Search (dfs) algorithm. It can have three possible values: 'in', 'pre', or 'post'.
553
- * @param loopType - The loopType parameter is a string that specifies the type of loop to use when traversing the
554
- * @returns The dfsCountIterative function returns an array of numbers, which represents the count property of each node
555
- * in the dfs traversal.
556
- */
557
- dfsCount(pattern: DFSOrderPattern = 'in', loopType: LoopType = LoopType.ITERATIVE): number[] {
558
- const nodes = super.dfs(pattern, 'node', loopType);
559
- return nodes.map(node => node.count);
560
- }
561
-
562
- /**
563
- * The `lesserSumCount` function calculates the sum of the counts of all nodes in a binary tree that have a lesser
564
- * value than a given node.
565
- * @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
566
- * @returns the sum of the counts of nodes in the binary tree that have a lesser value than the given beginNode.
567
- */
568
- lesserSumCount(beginNode: N | BinaryTreeNodeKey | null): number {
569
- if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'key');
570
- if (!beginNode) return 0;
571
- if (!this.root) return 0;
572
- const key = beginNode.key;
573
-
574
- let sum = 0;
575
-
576
- if (this.loopType === LoopType.RECURSIVE) {
577
- const _traverse = (cur: N): void => {
578
- const compared = this._compare(cur.key, key);
579
- if (compared === CP.eq) {
580
- if (cur.right) sum += this.subTreeSumCount(cur.right);
581
- return;
582
- } else if (compared === CP.lt) {
583
- if (cur.left) sum += this.subTreeSumCount(cur.left);
584
- sum += cur.count;
585
- if (cur.right) _traverse(cur.right);
586
- else return;
587
- } else {
588
- if (cur.left) _traverse(cur.left);
589
- else return;
590
- }
591
- };
592
-
593
- _traverse(this.root);
594
- } else {
595
- const queue: N[] = [this.root];
596
- while (queue.length > 0) {
597
- const cur = queue.shift();
598
- if (cur) {
599
- const compared = this._compare(cur.key, key);
600
- if (compared === CP.eq) {
601
- if (cur.right) sum += this.subTreeSumCount(cur.right);
602
- return sum;
603
- } else if (compared === CP.lt) {
604
- // todo maybe a bug
605
- if (cur.left) sum += this.subTreeSumCount(cur.left);
606
- sum += cur.count;
607
- if (cur.right) queue.push(cur.right);
608
- else return sum;
609
- } else {
610
- if (cur.left) queue.push(cur.left);
611
- else return sum;
612
- }
613
- }
614
- }
615
- }
616
-
617
- return sum;
618
- }
619
-
620
- /**
621
- * The function `allGreaterNodesAddCount` updates the count property of all nodes in a binary tree that have an ID
622
- * greater than a given ID by a specified delta value.
623
- * @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be one of the following:
624
- * @param {number} delta - The `delta` parameter is a number that represents the amount by which the `count` property
625
- * of each node should be increased.
626
- * @returns a boolean value.
627
- */
628
- allGreaterNodesAddCount(node: N | BinaryTreeNodeKey | null, delta: number): boolean {
629
- if (typeof node === 'number') node = this.get(node, 'key');
630
- if (!node) return false;
631
- const key = node.key;
632
- if (!this.root) return false;
633
-
634
- if (this.loopType === LoopType.RECURSIVE) {
635
- const _traverse = (cur: N) => {
636
- const compared = this._compare(cur.key, key);
637
- if (compared === CP.gt) cur.count += delta;
638
-
639
- if (!cur.left && !cur.right) return;
640
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) _traverse(cur.left);
641
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) _traverse(cur.right);
642
- };
643
-
644
- _traverse(this.root);
645
- return true;
646
- } else {
647
- const queue: N[] = [this.root];
648
- while (queue.length > 0) {
649
- const cur = queue.shift();
650
- if (cur) {
651
- const compared = this._compare(cur.key, key);
652
- if (compared === CP.gt) cur.count += delta;
653
-
654
- if (cur.left && this._compare(cur.left.key, key) === CP.gt) queue.push(cur.left);
655
- if (cur.right && this._compare(cur.right.key, key) === CP.gt) queue.push(cur.right);
656
- }
657
- }
658
- return true;
659
- }
660
- }
661
-
662
352
  /**
663
353
  * The clear() function clears the data and sets the count to 0.
664
354
  */
@@ -9,6 +9,7 @@ import {arrayRemove, uuidV4} from '../../utils';
9
9
  import {PriorityQueue} from '../priority-queue';
10
10
  import type {DijkstraResult, VertexKey} from '../../types';
11
11
  import {IGraph} from '../../interfaces';
12
+ import {Queue} from '../queue';
12
13
 
13
14
  export abstract class AbstractVertex<V = any> {
14
15
  /**
@@ -342,11 +343,11 @@ export abstract class AbstractGraph<
342
343
  }
343
344
 
344
345
  const visited: Map<V, boolean> = new Map();
345
- const queue: V[] = [vertex1];
346
+ const queue = new Queue<V>([vertex1]);
346
347
  visited.set(vertex1, true);
347
348
  let cost = 0;
348
- while (queue.length > 0) {
349
- for (let i = 0; i < queue.length; i++) {
349
+ while (queue.size > 0) {
350
+ for (let i = 0; i < queue.size; i++) {
350
351
  const cur = queue.shift();
351
352
  if (cur === vertex2) {
352
353
  return cost;
@@ -172,7 +172,7 @@ export class Heap<E> {
172
172
 
173
173
  /**
174
174
  * Depth-first search (DFS) method, different traversal orders can be selected。
175
- * @param order - Traversal order parameter: 'in' (in-order), 'pre' (pre-order) or 'post' (post-order).
175
+ * @param order - Traverse order parameter: 'in' (in-order), 'pre' (pre-order) or 'post' (post-order).
176
176
  * @returns An array containing elements traversed in the specified order.
177
177
  */
178
178
  dfs(order: DFSOrderPattern): E[] {
@@ -28,6 +28,10 @@ export type NodeOrPropertyName = 'node' | BinaryTreeNodePropertyName;
28
28
 
29
29
  export type BinaryTreeNodeKey = number;
30
30
 
31
+ export type BFSCallback<N> = (node: N, level?: number) => any;
32
+
33
+ export type BFSCallbackReturn<N> = ReturnType<BFSCallback<N>>;
34
+
31
35
  export type BinaryTreeNodeProperty<N extends BinaryTreeNode<N['val'], N>> =
32
36
  | N['val']
33
37
  | N
@@ -12,3 +12,6 @@ export * from './singly-linked-list';
12
12
  export * from './doubly-linked-list';
13
13
  export * from './navigator';
14
14
  export * from './hash';
15
+
16
+ export type MapCallback<N> = (node: N) => any;
17
+ export type MapCallbackReturn<N> = ReturnType<MapCallback<N>>;