data-structure-typed 1.36.8 → 1.37.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.
- package/CHANGELOG.md +3 -1
- package/README.md +8 -0
- package/dist/data-structures/binary-tree/avl-tree.d.ts +5 -5
- package/dist/data-structures/binary-tree/avl-tree.js +6 -6
- package/dist/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/data-structures/binary-tree/binary-tree.d.ts +18 -95
- package/dist/data-structures/binary-tree/binary-tree.js +82 -183
- package/dist/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/data-structures/binary-tree/bst.d.ts +6 -20
- package/dist/data-structures/binary-tree/bst.js +22 -122
- package/dist/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +6 -67
- package/dist/data-structures/binary-tree/tree-multiset.js +10 -257
- package/dist/data-structures/binary-tree/tree-multiset.js.map +1 -1
- package/dist/data-structures/graph/abstract-graph.js +4 -3
- package/dist/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/data-structures/hash/hash-map.d.ts +1 -1
- package/dist/data-structures/hash/hash-map.js +1 -1
- package/dist/data-structures/hash/hash-table.d.ts +3 -3
- package/dist/data-structures/hash/hash-table.js +3 -3
- package/dist/data-structures/heap/heap.js.map +1 -1
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +3 -3
- package/dist/data-structures/linked-list/skip-linked-list.js +3 -3
- package/dist/data-structures/queue/deque.d.ts +2 -2
- package/dist/data-structures/queue/deque.js +2 -2
- package/dist/data-structures/queue/queue.js +1 -1
- package/dist/data-structures/trie/trie.d.ts +2 -2
- package/dist/data-structures/trie/trie.js +2 -2
- package/dist/interfaces/binary-tree.d.ts +1 -1
- package/lib/data-structures/binary-tree/avl-tree.d.ts +5 -5
- package/lib/data-structures/binary-tree/avl-tree.js +6 -6
- package/lib/data-structures/binary-tree/binary-tree.d.ts +18 -95
- package/lib/data-structures/binary-tree/binary-tree.js +82 -183
- package/lib/data-structures/binary-tree/bst.d.ts +6 -20
- package/lib/data-structures/binary-tree/bst.js +22 -122
- package/lib/data-structures/binary-tree/tree-multiset.d.ts +6 -67
- package/lib/data-structures/binary-tree/tree-multiset.js +10 -257
- package/lib/data-structures/graph/abstract-graph.js +4 -3
- package/lib/data-structures/hash/hash-map.d.ts +1 -1
- package/lib/data-structures/hash/hash-map.js +1 -1
- package/lib/data-structures/hash/hash-table.d.ts +3 -3
- package/lib/data-structures/hash/hash-table.js +3 -3
- package/lib/data-structures/linked-list/skip-linked-list.d.ts +3 -3
- package/lib/data-structures/linked-list/skip-linked-list.js +3 -3
- package/lib/data-structures/queue/deque.d.ts +2 -2
- package/lib/data-structures/queue/deque.js +2 -2
- package/lib/data-structures/queue/queue.js +1 -1
- package/lib/data-structures/trie/trie.d.ts +2 -2
- package/lib/data-structures/trie/trie.js +2 -2
- package/lib/interfaces/binary-tree.d.ts +1 -1
- package/package.json +9 -7
- package/src/data-structures/binary-tree/avl-tree.ts +6 -6
- package/src/data-structures/binary-tree/binary-tree.ts +85 -274
- package/src/data-structures/binary-tree/bst.ts +22 -106
- package/src/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/data-structures/binary-tree/tree-multiset.ts +10 -249
- package/src/data-structures/graph/abstract-graph.ts +4 -3
- package/src/data-structures/hash/hash-map.ts +1 -1
- package/src/data-structures/hash/hash-table.ts +3 -3
- package/src/data-structures/heap/heap.ts +5 -2
- package/src/data-structures/linked-list/skip-linked-list.ts +3 -3
- package/src/data-structures/queue/deque.ts +2 -2
- package/src/data-structures/queue/queue.ts +1 -1
- package/src/data-structures/trie/trie.ts +2 -2
- package/src/interfaces/binary-tree.ts +1 -1
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +19 -17
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +2 -2
- package/test/unit/data-structures/binary-tree/bst.test.ts +72 -35
- package/test/unit/data-structures/binary-tree/overall.test.ts +4 -4
- package/test/unit/data-structures/binary-tree/rb-tree.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/tree-multiset.test.ts +67 -37
- package/test/unit/data-structures/graph/directed-graph.test.ts +1 -1
- package/test/unit/data-structures/graph/undirected-graph.test.ts +1 -1
- package/test/unit/data-structures/hash/hash-map.test.ts +2 -2
- package/test/unit/data-structures/hash/hash-table.test.ts +5 -5
- package/test/unit/data-structures/heap/heap.test.ts +15 -12
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +7 -7
- package/test/unit/data-structures/linked-list/skip-list.test.ts +2 -2
- package/test/unit/data-structures/priority-queue/max-priority-queue.test.ts +1 -1
- package/test/unit/data-structures/queue/deque.test.ts +20 -3
- package/test/unit/data-structures/queue/queue.test.ts +42 -0
- package/test/unit/data-structures/trie/trie.test.ts +5 -5
- package/test/utils/big-o.ts +64 -57
- package/umd/bundle.min.js +1 -1
- package/umd/bundle.min.js.map +1 -1
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
import {CP, LoopType} from '../../types';
|
|
16
16
|
import {BinaryTree, BinaryTreeNode} from './binary-tree';
|
|
17
17
|
import {IBinaryTree} from '../../interfaces';
|
|
18
|
+
import {Queue} from '../queue';
|
|
18
19
|
|
|
19
20
|
export class BSTNode<V = any, FAMILY extends BSTNode<V, FAMILY> = BSTNodeNested<V>> extends BinaryTreeNode<V, FAMILY> {
|
|
20
21
|
constructor(key: BinaryTreeNodeKey, val?: V) {
|
|
@@ -59,7 +60,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|
|
59
60
|
* @returns The function `add` returns the inserted node (`inserted`) which can be of type `N`, `null`, or `undefined`.
|
|
60
61
|
*/
|
|
61
62
|
override add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined {
|
|
62
|
-
// TODO support node as a
|
|
63
|
+
// TODO support node as a parameter
|
|
63
64
|
let inserted: N | null = null;
|
|
64
65
|
let newNode: N | null = null;
|
|
65
66
|
if (keyOrNode instanceof BSTNode) {
|
|
@@ -137,8 +138,9 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|
|
137
138
|
override addMany(
|
|
138
139
|
keysOrNodes: (BinaryTreeNodeKey | null)[] | (N | null)[],
|
|
139
140
|
data?: N['val'][],
|
|
140
|
-
isBalanceAdd =
|
|
141
|
+
isBalanceAdd = true
|
|
141
142
|
): (N | null | undefined)[] {
|
|
143
|
+
// TODO this addMany function is inefficient, it should be optimized
|
|
142
144
|
function hasNoNull(arr: (BinaryTreeNodeKey | null)[] | (N | null)[]): arr is BinaryTreeNodeKey[] | N[] {
|
|
143
145
|
return arr.indexOf(null) === -1;
|
|
144
146
|
}
|
|
@@ -265,8 +267,8 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|
|
265
267
|
|
|
266
268
|
_traverse(this.root);
|
|
267
269
|
} else {
|
|
268
|
-
const queue
|
|
269
|
-
while (queue.
|
|
270
|
+
const queue = new Queue<N>([this.root]);
|
|
271
|
+
while (queue.size > 0) {
|
|
270
272
|
const cur = queue.shift();
|
|
271
273
|
if (cur) {
|
|
272
274
|
if (this._pushByPropertyNameStopOrNot(cur, result, nodeProperty, propertyName, onlyOne)) return result;
|
|
@@ -285,133 +287,47 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|
|
285
287
|
}
|
|
286
288
|
|
|
287
289
|
// --- 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
290
|
|
|
361
291
|
/**
|
|
362
|
-
* The `
|
|
292
|
+
* The `lesserOrGreaterForeach` function adds a delta value to the specified property of all nodes in a binary tree that
|
|
363
293
|
* 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
|
-
*
|
|
366
|
-
* @param
|
|
367
|
-
*
|
|
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.
|
|
294
|
+
* @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be either of type `N` (a generic type), `BinaryTreeNodeKey`, or `null`. It
|
|
295
|
+
* represents the node in the binary tree to which the delta value will be added.
|
|
296
|
+
* @param lesserOrGreater - The `lesserOrGreater` parameter is an optional parameter that specifies whether the delta
|
|
297
|
+
* @param callback - The `callback` parameter is a function that takes a node as a parameter and returns a boolean
|
|
372
298
|
*/
|
|
373
|
-
|
|
299
|
+
lesserOrGreaterForeach(
|
|
374
300
|
node: N | BinaryTreeNodeKey | null,
|
|
375
|
-
|
|
376
|
-
|
|
301
|
+
lesserOrGreater: CP = CP.lt,
|
|
302
|
+
callback: (node: N) => void
|
|
377
303
|
): boolean {
|
|
378
304
|
if (typeof node === 'number') node = this.get(node, 'key');
|
|
379
305
|
if (!node) return false;
|
|
380
306
|
const key = node.key;
|
|
381
307
|
if (!this.root) return false;
|
|
382
308
|
|
|
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
309
|
if (this.loopType === LoopType.RECURSIVE) {
|
|
394
310
|
const _traverse = (cur: N) => {
|
|
395
311
|
const compared = this._compare(cur.key, key);
|
|
396
|
-
if (compared ===
|
|
312
|
+
if (compared === lesserOrGreater) callback(cur);
|
|
397
313
|
|
|
398
314
|
if (!cur.left && !cur.right) return;
|
|
399
|
-
if (cur.left && this._compare(cur.left.key, key) ===
|
|
400
|
-
if (cur.right && this._compare(cur.right.key, key) ===
|
|
315
|
+
if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater) _traverse(cur.left);
|
|
316
|
+
if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater) _traverse(cur.right);
|
|
401
317
|
};
|
|
402
318
|
|
|
403
319
|
_traverse(this.root);
|
|
404
320
|
return true;
|
|
405
321
|
} else {
|
|
406
|
-
const queue
|
|
407
|
-
while (queue.
|
|
322
|
+
const queue = new Queue<N>([this.root]);
|
|
323
|
+
while (queue.size > 0) {
|
|
408
324
|
const cur = queue.shift();
|
|
409
325
|
if (cur) {
|
|
410
326
|
const compared = this._compare(cur.key, key);
|
|
411
|
-
if (compared ===
|
|
327
|
+
if (compared === lesserOrGreater) callback(cur);
|
|
412
328
|
|
|
413
|
-
if (cur.left && this._compare(cur.left.key, key) ===
|
|
414
|
-
if (cur.right && this._compare(cur.right.key, key) ===
|
|
329
|
+
if (cur.left && this._compare(cur.left.key, key) === lesserOrGreater) queue.push(cur.left);
|
|
330
|
+
if (cur.right && this._compare(cur.right.key, key) === lesserOrGreater) queue.push(cur.right);
|
|
415
331
|
}
|
|
416
332
|
}
|
|
417
333
|
return true;
|
|
@@ -164,10 +164,10 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
|
|
|
164
164
|
// // Remove a node
|
|
165
165
|
// private _removeNode(node: N, replacement: N | null | undefined): void {
|
|
166
166
|
// if (node === this.root && !replacement) {
|
|
167
|
-
// // If there's only the root node and no replacement, simply
|
|
167
|
+
// // If there's only the root node and no replacement, simply delete the root node
|
|
168
168
|
// this._setRoot(null);
|
|
169
169
|
// } else if (node === this.root || this._isNodeRed(node)) {
|
|
170
|
-
// // If the node is the root or a red node,
|
|
170
|
+
// // If the node is the root or a red node, delete it directly
|
|
171
171
|
// if (node.parent!.left === node) {
|
|
172
172
|
// node.parent!.left = replacement;
|
|
173
173
|
// } else {
|
|
@@ -205,7 +205,7 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
|
|
|
205
205
|
// node.right = null;
|
|
206
206
|
// }
|
|
207
207
|
//
|
|
208
|
-
// override
|
|
208
|
+
// override delete(nodeOrKey: BinaryTreeNodeKey | N): BinaryTreeDeletedResult<N>[] {
|
|
209
209
|
// const node = this.get(nodeOrKey);
|
|
210
210
|
// const result: BinaryTreeDeletedResult<N>[] = [{deleted: undefined, needBalanced: null}];
|
|
211
211
|
// if (!node) return result; // Node does not exist
|
|
@@ -9,6 +9,7 @@ import type {BinaryTreeNodeKey, TreeMultisetNodeNested, TreeMultisetOptions} fro
|
|
|
9
9
|
import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType} from '../../types';
|
|
10
10
|
import {IBinaryTree} from '../../interfaces';
|
|
11
11
|
import {AVLTree, AVLTreeNode} from './avl-tree';
|
|
12
|
+
import {Queue} from '../queue';
|
|
12
13
|
|
|
13
14
|
export class TreeMultisetNode<
|
|
14
15
|
V = any,
|
|
@@ -70,12 +71,12 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
70
71
|
|
|
71
72
|
/**
|
|
72
73
|
* The function swaps the location of two nodes in a tree data structure.
|
|
73
|
-
* @param {N} srcNode - The source node that we want to
|
|
74
|
+
* @param {N} srcNode - The source node that we want to _swap with the destination node.
|
|
74
75
|
* @param {N} destNode - The `destNode` parameter represents the destination node where the values from `srcNode` will
|
|
75
76
|
* be swapped with.
|
|
76
77
|
* @returns the `destNode` after swapping its values with the `srcNode`.
|
|
77
78
|
*/
|
|
78
|
-
override
|
|
79
|
+
protected override _swap(srcNode: N, destNode: N): N {
|
|
79
80
|
const {key, val, count, height} = destNode;
|
|
80
81
|
const tempNode = this.createNode(key, val, count);
|
|
81
82
|
if (tempNode) {
|
|
@@ -285,15 +286,15 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
285
286
|
}
|
|
286
287
|
|
|
287
288
|
/**
|
|
288
|
-
* The `
|
|
289
|
+
* The `delete` function removes a node from a binary search tree and returns the deleted node along with the parent
|
|
289
290
|
* node that needs to be balanced.
|
|
290
291
|
* @param {N | BinaryTreeNodeKey | null} nodeOrKey - The `nodeOrKey` parameter can be one of the following:
|
|
291
292
|
* @param {boolean} [ignoreCount] - The `ignoreCount` parameter is an optional boolean parameter that determines
|
|
292
293
|
* whether to ignore the count of the node being removed. If `ignoreCount` is set to `true`, the count of the node will
|
|
293
294
|
* not be taken into account when removing it. If `ignoreCount` is set to `false
|
|
294
|
-
* @returns The function `
|
|
295
|
+
* @returns The function `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
|
|
295
296
|
*/
|
|
296
|
-
override
|
|
297
|
+
override delete(nodeOrKey: N | BinaryTreeNodeKey, ignoreCount = false): BinaryTreeDeletedResult<N>[] {
|
|
297
298
|
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
|
298
299
|
if (!this.root) return bstDeletedResult;
|
|
299
300
|
|
|
@@ -324,7 +325,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
324
325
|
const leftSubTreeRightMost = curr.left ? this.getRightMost(curr.left) : null;
|
|
325
326
|
if (leftSubTreeRightMost) {
|
|
326
327
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
327
|
-
orgCurrent = this.
|
|
328
|
+
orgCurrent = this._swap(curr, leftSubTreeRightMost);
|
|
328
329
|
if (parentOfLeftSubTreeMax) {
|
|
329
330
|
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {
|
|
330
331
|
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
@@ -349,121 +350,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
349
350
|
return bstDeletedResult;
|
|
350
351
|
}
|
|
351
352
|
|
|
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
353
|
/**
|
|
468
354
|
* The function `getNodesByCount` returns an array of nodes that have a specific count property, either recursively or
|
|
469
355
|
* using a queue.
|
|
@@ -492,8 +378,8 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
492
378
|
|
|
493
379
|
_traverse(this.root);
|
|
494
380
|
} else {
|
|
495
|
-
const queue
|
|
496
|
-
while (queue.
|
|
381
|
+
const queue = new Queue<N>([this.root]);
|
|
382
|
+
while (queue.size > 0) {
|
|
497
383
|
const cur = queue.shift();
|
|
498
384
|
if (cur) {
|
|
499
385
|
if (cur.count === nodeProperty) {
|
|
@@ -515,7 +401,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
515
401
|
* @returns The BFSCount() function returns an array of numbers, specifically the count property of each node in the
|
|
516
402
|
* bfs traversal.
|
|
517
403
|
*/
|
|
518
|
-
|
|
404
|
+
bfsCount(): number[] {
|
|
519
405
|
const nodes = super.bfs('node');
|
|
520
406
|
return nodes.map(node => node.count);
|
|
521
407
|
}
|
|
@@ -545,131 +431,6 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
545
431
|
return nodes.map(node => node.count);
|
|
546
432
|
}
|
|
547
433
|
|
|
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
|
-
* @returns The dfsCountIterative function returns an array of numbers, which represents the count property of each node
|
|
554
|
-
* in the dfs traversal.
|
|
555
|
-
*/
|
|
556
|
-
dfsCountIterative(pattern: DFSOrderPattern = 'in'): number[] {
|
|
557
|
-
const nodes = super.dfsIterative(pattern, 'node');
|
|
558
|
-
return nodes.map(node => node.count);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
/**
|
|
562
|
-
* The dfsCount function returns an array of counts for each node in a depth-first search traversal.
|
|
563
|
-
* @param {DFSOrderPattern} [pattern] - The pattern parameter is an optional parameter that specifies the order in which
|
|
564
|
-
* the Depth-First Search (dfs) algorithm should traverse the nodes. It can have one of the following values:
|
|
565
|
-
* @returns The dfsCount function returns an array of numbers, specifically the count property of each node in the dfs
|
|
566
|
-
* traversal.
|
|
567
|
-
*/
|
|
568
|
-
dfsCount(pattern: DFSOrderPattern = 'in'): number[] {
|
|
569
|
-
const nodes = super.dfs(pattern, 'node');
|
|
570
|
-
return nodes.map(node => node.count);
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
/**
|
|
574
|
-
* The `lesserSumCount` function calculates the sum of the counts of all nodes in a binary tree that have a lesser
|
|
575
|
-
* value than a given node.
|
|
576
|
-
* @param {N | BinaryTreeNodeKey | null} beginNode - The `beginNode` parameter can be one of the following:
|
|
577
|
-
* @returns the sum of the counts of nodes in the binary tree that have a lesser value than the given beginNode.
|
|
578
|
-
*/
|
|
579
|
-
lesserSumCount(beginNode: N | BinaryTreeNodeKey | null): number {
|
|
580
|
-
if (typeof beginNode === 'number') beginNode = this.get(beginNode, 'key');
|
|
581
|
-
if (!beginNode) return 0;
|
|
582
|
-
if (!this.root) return 0;
|
|
583
|
-
const key = beginNode.key;
|
|
584
|
-
|
|
585
|
-
let sum = 0;
|
|
586
|
-
|
|
587
|
-
if (this.loopType === LoopType.RECURSIVE) {
|
|
588
|
-
const _traverse = (cur: N): void => {
|
|
589
|
-
const compared = this._compare(cur.key, key);
|
|
590
|
-
if (compared === CP.eq) {
|
|
591
|
-
if (cur.right) sum += this.subTreeSumCount(cur.right);
|
|
592
|
-
return;
|
|
593
|
-
} else if (compared === CP.lt) {
|
|
594
|
-
if (cur.left) sum += this.subTreeSumCount(cur.left);
|
|
595
|
-
sum += cur.count;
|
|
596
|
-
if (cur.right) _traverse(cur.right);
|
|
597
|
-
else return;
|
|
598
|
-
} else {
|
|
599
|
-
if (cur.left) _traverse(cur.left);
|
|
600
|
-
else return;
|
|
601
|
-
}
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
_traverse(this.root);
|
|
605
|
-
} else {
|
|
606
|
-
const queue: N[] = [this.root];
|
|
607
|
-
while (queue.length > 0) {
|
|
608
|
-
const cur = queue.shift();
|
|
609
|
-
if (cur) {
|
|
610
|
-
const compared = this._compare(cur.key, key);
|
|
611
|
-
if (compared === CP.eq) {
|
|
612
|
-
if (cur.right) sum += this.subTreeSumCount(cur.right);
|
|
613
|
-
return sum;
|
|
614
|
-
} else if (compared === CP.lt) {
|
|
615
|
-
// todo maybe a bug
|
|
616
|
-
if (cur.left) sum += this.subTreeSumCount(cur.left);
|
|
617
|
-
sum += cur.count;
|
|
618
|
-
if (cur.right) queue.push(cur.right);
|
|
619
|
-
else return sum;
|
|
620
|
-
} else {
|
|
621
|
-
if (cur.left) queue.push(cur.left);
|
|
622
|
-
else return sum;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
return sum;
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
/**
|
|
632
|
-
* The function `allGreaterNodesAddCount` updates the count property of all nodes in a binary tree that have an ID
|
|
633
|
-
* greater than a given ID by a specified delta value.
|
|
634
|
-
* @param {N | BinaryTreeNodeKey | null} node - The `node` parameter can be one of the following:
|
|
635
|
-
* @param {number} delta - The `delta` parameter is a number that represents the amount by which the `count` property
|
|
636
|
-
* of each node should be increased.
|
|
637
|
-
* @returns a boolean value.
|
|
638
|
-
*/
|
|
639
|
-
allGreaterNodesAddCount(node: N | BinaryTreeNodeKey | null, delta: number): boolean {
|
|
640
|
-
if (typeof node === 'number') node = this.get(node, 'key');
|
|
641
|
-
if (!node) return false;
|
|
642
|
-
const key = node.key;
|
|
643
|
-
if (!this.root) return false;
|
|
644
|
-
|
|
645
|
-
if (this.loopType === LoopType.RECURSIVE) {
|
|
646
|
-
const _traverse = (cur: N) => {
|
|
647
|
-
const compared = this._compare(cur.key, key);
|
|
648
|
-
if (compared === CP.gt) cur.count += delta;
|
|
649
|
-
|
|
650
|
-
if (!cur.left && !cur.right) return;
|
|
651
|
-
if (cur.left && this._compare(cur.left.key, key) === CP.gt) _traverse(cur.left);
|
|
652
|
-
if (cur.right && this._compare(cur.right.key, key) === CP.gt) _traverse(cur.right);
|
|
653
|
-
};
|
|
654
|
-
|
|
655
|
-
_traverse(this.root);
|
|
656
|
-
return true;
|
|
657
|
-
} else {
|
|
658
|
-
const queue: N[] = [this.root];
|
|
659
|
-
while (queue.length > 0) {
|
|
660
|
-
const cur = queue.shift();
|
|
661
|
-
if (cur) {
|
|
662
|
-
const compared = this._compare(cur.key, key);
|
|
663
|
-
if (compared === CP.gt) cur.count += delta;
|
|
664
|
-
|
|
665
|
-
if (cur.left && this._compare(cur.left.key, key) === CP.gt) queue.push(cur.left);
|
|
666
|
-
if (cur.right && this._compare(cur.right.key, key) === CP.gt) queue.push(cur.right);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
return true;
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
|
|
673
434
|
/**
|
|
674
435
|
* The clear() function clears the data and sets the count to 0.
|
|
675
436
|
*/
|
|
@@ -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
|
|
346
|
+
const queue = new Queue<V>([vertex1]);
|
|
346
347
|
visited.set(vertex1, true);
|
|
347
348
|
let cost = 0;
|
|
348
|
-
while (queue.
|
|
349
|
-
for (let i = 0; i < queue.
|
|
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;
|
|
@@ -213,13 +213,13 @@ export class HashTable<K, V> {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
/**
|
|
216
|
-
* The
|
|
216
|
+
* The delete function removes a key-value pair from a hash table.
|
|
217
217
|
* @param {K} key - The `key` parameter represents the key of the key-value pair that needs to be removed from the hash
|
|
218
218
|
* table.
|
|
219
|
-
* @returns Nothing is being returned. The `
|
|
219
|
+
* @returns Nothing is being returned. The `delete` method has a return type of `void`, which means it does not return
|
|
220
220
|
* any value.
|
|
221
221
|
*/
|
|
222
|
-
|
|
222
|
+
delete(key: K): void {
|
|
223
223
|
const index = this._hash(key);
|
|
224
224
|
let currentNode = this._buckets[index];
|
|
225
225
|
let prevNode: HashTableNode<K, V> | null = null;
|
|
@@ -375,7 +375,7 @@ export class FibonacciHeap<E> {
|
|
|
375
375
|
* @protected
|
|
376
376
|
* @returns FibonacciHeapNode<E>[] - An array containing the nodes of the linked list.
|
|
377
377
|
*/
|
|
378
|
-
|
|
378
|
+
consumeLinkedList(head?: FibonacciHeapNode<E>): FibonacciHeapNode<E>[] {
|
|
379
379
|
const nodes: FibonacciHeapNode<E>[] = [];
|
|
380
380
|
if (!head) return nodes;
|
|
381
381
|
|
|
@@ -448,7 +448,10 @@ export class FibonacciHeap<E> {
|
|
|
448
448
|
protected consolidate(): void {
|
|
449
449
|
const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this.size);
|
|
450
450
|
const nodes = this.consumeLinkedList(this.root);
|
|
451
|
-
let x: FibonacciHeapNode<E> | undefined,
|
|
451
|
+
let x: FibonacciHeapNode<E> | undefined,
|
|
452
|
+
y: FibonacciHeapNode<E> | undefined,
|
|
453
|
+
d: number,
|
|
454
|
+
t: FibonacciHeapNode<E> | undefined;
|
|
452
455
|
|
|
453
456
|
for (const node of nodes) {
|
|
454
457
|
x = node;
|
|
@@ -130,12 +130,12 @@ export class SkipList<K, V> {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
|
-
* The `
|
|
133
|
+
* The `delete` function removes a node with a specific key from a Skip List data structure.
|
|
134
134
|
* @param {K} key - The key parameter represents the key of the node that needs to be removed from the skip list.
|
|
135
|
-
* @returns The `
|
|
135
|
+
* @returns The `delete` method returns a boolean value. It returns `true` if the key was successfully removed from the
|
|
136
136
|
* skip list, and `false` if the key was not found in the skip list.
|
|
137
137
|
*/
|
|
138
|
-
|
|
138
|
+
delete(key: K): boolean {
|
|
139
139
|
const update: SkipListNode<K, V>[] = new Array(this.maxLevel).fill(this.head);
|
|
140
140
|
let current = this.head;
|
|
141
141
|
|
|
@@ -277,12 +277,12 @@ export class ArrayDeque<E> {
|
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
/**
|
|
280
|
-
* The
|
|
280
|
+
* The delete function removes an element from an array at a specified index.
|
|
281
281
|
* @param {number} index - The index parameter specifies the position of the element to be removed from the array. It
|
|
282
282
|
* is a number that represents the index of the element to be removed.
|
|
283
283
|
* @returns The method is returning an array containing the removed element.
|
|
284
284
|
*/
|
|
285
|
-
|
|
285
|
+
delete(index: number) {
|
|
286
286
|
return this._nodes.splice(index, 1);
|
|
287
287
|
}
|
|
288
288
|
|
|
@@ -106,7 +106,7 @@ export class Queue<E = any> {
|
|
|
106
106
|
|
|
107
107
|
if (this.offset * 2 < this.nodes.length) return first;
|
|
108
108
|
|
|
109
|
-
// only
|
|
109
|
+
// only delete dequeued elements when reaching half size
|
|
110
110
|
// to decrease latency of shifting elements.
|
|
111
111
|
this.nodes = this.nodes.slice(this.offset);
|
|
112
112
|
this.offset = 0;
|
|
@@ -119,10 +119,10 @@ export class Trie {
|
|
|
119
119
|
|
|
120
120
|
/**
|
|
121
121
|
* Remove a word from the Trie structure.
|
|
122
|
-
* @param{string} word - The word to
|
|
122
|
+
* @param{string} word - The word to delete.
|
|
123
123
|
* @returns {boolean} True if the word was successfully removed.
|
|
124
124
|
*/
|
|
125
|
-
|
|
125
|
+
delete(word: string) {
|
|
126
126
|
word = this._caseProcess(word);
|
|
127
127
|
let isDeleted = false;
|
|
128
128
|
const dfs = (cur: TrieNode, i: number): boolean => {
|
|
@@ -6,5 +6,5 @@ export interface IBinaryTree<N extends BinaryTreeNode<N['val'], N>> {
|
|
|
6
6
|
|
|
7
7
|
add(keyOrNode: BinaryTreeNodeKey | N | null, val?: N['val']): N | null | undefined;
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
delete(nodeOrKey: N | BinaryTreeNodeKey): BinaryTreeDeletedResult<N>[];
|
|
10
10
|
}
|