data-structure-typed 1.19.6 → 1.19.8
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/dist/data-structures/binary-tree/abstract-binary-tree.d.ts +41 -58
- package/dist/data-structures/binary-tree/abstract-binary-tree.js +107 -145
- package/dist/data-structures/binary-tree/avl-tree.d.ts +1 -0
- package/dist/data-structures/binary-tree/avl-tree.js +4 -0
- package/dist/data-structures/binary-tree/binary-tree.d.ts +2 -1
- package/dist/data-structures/binary-tree/binary-tree.js +3 -0
- package/dist/data-structures/binary-tree/bst.d.ts +1 -0
- package/dist/data-structures/binary-tree/bst.js +4 -0
- package/dist/data-structures/binary-tree/rb-tree.d.ts +1 -1
- package/dist/data-structures/binary-tree/rb-tree.js +2 -3
- package/dist/data-structures/binary-tree/tree-multiset.d.ts +22 -16
- package/dist/data-structures/binary-tree/tree-multiset.js +138 -122
- package/dist/data-structures/interfaces/abstract-binary-tree.d.ts +6 -9
- package/dist/data-structures/types/abstract-binary-tree.d.ts +1 -2
- package/dist/data-structures/types/tree-multiset.d.ts +2 -2
- package/package.json +22 -5
- package/src/data-structures/binary-tree/abstract-binary-tree.ts +112 -161
- package/src/data-structures/binary-tree/avl-tree.ts +4 -0
- package/src/data-structures/binary-tree/binary-tree.ts +4 -2
- package/src/data-structures/binary-tree/bst.ts +4 -1
- package/src/data-structures/binary-tree/rb-tree.ts +3 -3
- package/src/data-structures/binary-tree/tree-multiset.ts +136 -118
- package/src/data-structures/interfaces/abstract-binary-tree.ts +6 -43
- package/src/data-structures/types/abstract-binary-tree.ts +1 -2
- package/src/data-structures/types/tree-multiset.ts +2 -2
- package/tsconfig.json +1 -2
- package/src/data-structures/binary-tree/diagrams/avl-tree-inserting.gif +0 -0
- package/src/data-structures/binary-tree/diagrams/bst-rotation.gif +0 -0
- package/src/data-structures/binary-tree/diagrams/segment-tree.png +0 -0
- package/src/data-structures/graph/diagrams/adjacency-list-pros-cons.jpg +0 -0
- package/src/data-structures/graph/diagrams/adjacency-list.jpg +0 -0
- package/src/data-structures/graph/diagrams/adjacency-matrix-pros-cons.jpg +0 -0
- package/src/data-structures/graph/diagrams/adjacency-matrix.jpg +0 -0
- package/src/data-structures/graph/diagrams/dfs-can-do.jpg +0 -0
- package/src/data-structures/graph/diagrams/edge-list-pros-cons.jpg +0 -0
- package/src/data-structures/graph/diagrams/edge-list.jpg +0 -0
- package/src/data-structures/graph/diagrams/max-flow.jpg +0 -0
- package/src/data-structures/graph/diagrams/mst.jpg +0 -0
- package/src/data-structures/graph/diagrams/tarjan-articulation-point-bridge.png +0 -0
- package/src/data-structures/graph/diagrams/tarjan-complicate-simple.png +0 -0
- package/src/data-structures/graph/diagrams/tarjan-strongly-connected-component.png +0 -0
- package/src/data-structures/graph/diagrams/tarjan.mp4 +0 -0
- package/src/data-structures/graph/diagrams/tarjan.webp +0 -0
|
@@ -10,6 +10,9 @@ exports.AVLTree = exports.AVLTreeNode = void 0;
|
|
|
10
10
|
*/
|
|
11
11
|
const bst_1 = require("./bst");
|
|
12
12
|
class AVLTreeNode extends bst_1.BSTNode {
|
|
13
|
+
constructor(id, val) {
|
|
14
|
+
super(id, val);
|
|
15
|
+
}
|
|
13
16
|
}
|
|
14
17
|
exports.AVLTreeNode = AVLTreeNode;
|
|
15
18
|
class AVLTree extends bst_1.BST {
|
|
@@ -41,6 +44,7 @@ class AVLTree extends bst_1.BST {
|
|
|
41
44
|
* @returns The method is returning the inserted node, or null or undefined if the insertion was not successful.
|
|
42
45
|
*/
|
|
43
46
|
add(id, val) {
|
|
47
|
+
// TODO support node as a param
|
|
44
48
|
const inserted = super.add(id, val);
|
|
45
49
|
if (inserted)
|
|
46
50
|
this.balancePath(inserted);
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions } from '../types';
|
|
9
9
|
import { AbstractBinaryTree, AbstractBinaryTreeNode } from './abstract-binary-tree';
|
|
10
|
-
import { IBinaryTree, IBinaryTreeNode } from '../interfaces
|
|
10
|
+
import { IBinaryTree, IBinaryTreeNode } from '../interfaces';
|
|
11
11
|
export declare class BinaryTreeNode<T = any, NEIGHBOR extends BinaryTreeNode<T, NEIGHBOR> = BinaryTreeNodeNested<T>> extends AbstractBinaryTreeNode<T, NEIGHBOR> implements IBinaryTreeNode<T, NEIGHBOR> {
|
|
12
|
+
constructor(id: BinaryTreeNodeId, val?: T);
|
|
12
13
|
}
|
|
13
14
|
export declare class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode> extends AbstractBinaryTree<N> implements IBinaryTree<N> {
|
|
14
15
|
/**
|
|
@@ -10,6 +10,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.BinaryTree = exports.BinaryTreeNode = void 0;
|
|
11
11
|
const abstract_binary_tree_1 = require("./abstract-binary-tree");
|
|
12
12
|
class BinaryTreeNode extends abstract_binary_tree_1.AbstractBinaryTreeNode {
|
|
13
|
+
constructor(id, val) {
|
|
14
|
+
super(id, val);
|
|
15
|
+
}
|
|
13
16
|
}
|
|
14
17
|
exports.BinaryTreeNode = BinaryTreeNode;
|
|
15
18
|
class BinaryTree extends abstract_binary_tree_1.AbstractBinaryTree {
|
|
@@ -10,6 +10,7 @@ import { CP } from '../types';
|
|
|
10
10
|
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
|
11
11
|
import { IBST, IBSTNode } from '../interfaces';
|
|
12
12
|
export declare class BSTNode<T = any, NEIGHBOR extends BSTNode<T, NEIGHBOR> = BSTNodeNested<T>> extends BinaryTreeNode<T, NEIGHBOR> implements IBSTNode<T, NEIGHBOR> {
|
|
13
|
+
constructor(id: BinaryTreeNodeId, val?: T);
|
|
13
14
|
}
|
|
14
15
|
export declare class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N> implements IBST<N> {
|
|
15
16
|
/**
|
|
@@ -4,6 +4,9 @@ exports.BST = exports.BSTNode = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const binary_tree_1 = require("./binary-tree");
|
|
6
6
|
class BSTNode extends binary_tree_1.BinaryTreeNode {
|
|
7
|
+
constructor(id, val) {
|
|
8
|
+
super(id, val);
|
|
9
|
+
}
|
|
7
10
|
}
|
|
8
11
|
exports.BSTNode = BSTNode;
|
|
9
12
|
class BST extends binary_tree_1.BinaryTree {
|
|
@@ -42,6 +45,7 @@ class BST extends binary_tree_1.BinaryTree {
|
|
|
42
45
|
* If the node was not added (e.g., due to a duplicate ID), it returns `null` or `undefined`.
|
|
43
46
|
*/
|
|
44
47
|
add(id, val) {
|
|
48
|
+
// TODO support node as a param
|
|
45
49
|
let inserted = null;
|
|
46
50
|
const newNode = this.createNode(id, val);
|
|
47
51
|
if (this.root === null) {
|
|
@@ -2,7 +2,7 @@ import { BinaryTreeNodeId, RBColor, RBTreeNodeNested, RBTreeOptions } from '../t
|
|
|
2
2
|
import { IRBTree, IRBTreeNode } from '../interfaces/rb-tree';
|
|
3
3
|
import { BST, BSTNode } from './bst';
|
|
4
4
|
export declare class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTreeNodeNested<T>> extends BSTNode<T, NEIGHBOR> implements IRBTreeNode<T, NEIGHBOR> {
|
|
5
|
-
constructor(id: BinaryTreeNodeId,
|
|
5
|
+
constructor(id: BinaryTreeNodeId, val?: T, color?: RBColor);
|
|
6
6
|
private _color;
|
|
7
7
|
get color(): RBColor;
|
|
8
8
|
set color(value: RBColor);
|
|
@@ -4,9 +4,8 @@ exports.RBTree = exports.RBTreeNode = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const bst_1 = require("./bst");
|
|
6
6
|
class RBTreeNode extends bst_1.BSTNode {
|
|
7
|
-
constructor(id,
|
|
7
|
+
constructor(id, val, color = types_1.RBColor.RED) {
|
|
8
8
|
super(id, val);
|
|
9
|
-
this._color = types_1.RBColor.RED;
|
|
10
9
|
this._color = color;
|
|
11
10
|
}
|
|
12
11
|
get color() {
|
|
@@ -22,7 +21,7 @@ class RBTree extends bst_1.BST {
|
|
|
22
21
|
super(options);
|
|
23
22
|
}
|
|
24
23
|
createNode(id, val) {
|
|
25
|
-
return new RBTreeNode(id, types_1.RBColor.RED
|
|
24
|
+
return new RBTreeNode(id, val, types_1.RBColor.RED);
|
|
26
25
|
}
|
|
27
26
|
// private override _root: BinaryTreeNode<N> | null = null;
|
|
28
27
|
//
|
|
@@ -57,17 +57,16 @@ export declare class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = Tree
|
|
|
57
57
|
*/
|
|
58
58
|
swapLocation(srcNode: N, destNode: N): N;
|
|
59
59
|
/**
|
|
60
|
-
* The `add` function adds a new node to a binary tree,
|
|
61
|
-
*
|
|
62
|
-
* @param {BinaryTreeNodeId}
|
|
63
|
-
*
|
|
64
|
-
* @param [val] - The `val` parameter
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
add(id: BinaryTreeNodeId, val?: N['val'], count?: number): N | null | undefined;
|
|
60
|
+
* The `add` function adds a new node to a binary search tree, maintaining the tree's properties and balancing if
|
|
61
|
+
* necessary.
|
|
62
|
+
* @param {BinaryTreeNodeId | N} idOrNode - The `idOrNode` parameter can be either a `BinaryTreeNodeId` or a `N` (which
|
|
63
|
+
* represents a `BinaryTreeNode`).
|
|
64
|
+
* @param [val] - The `val` parameter represents the value to be added to the binary tree node.
|
|
65
|
+
* @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the
|
|
66
|
+
* value should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
|
|
67
|
+
* @returns The method `add` returns either the inserted node (`N`), `null`, or `undefined`.
|
|
68
|
+
*/
|
|
69
|
+
add(idOrNode: BinaryTreeNodeId | N | null, val?: N['val'], count?: number): N | null | undefined;
|
|
71
70
|
/**
|
|
72
71
|
* The function adds a new node to a binary tree as the left or right child of a given parent node.
|
|
73
72
|
* @param {N | null} newNode - The `newNode` parameter represents the node that you want to add to the tree. It can be
|
|
@@ -79,13 +78,20 @@ export declare class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = Tree
|
|
|
79
78
|
*/
|
|
80
79
|
addTo(newNode: N | null, parent: N): N | null | undefined;
|
|
81
80
|
/**
|
|
82
|
-
* The `addMany` function
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* array of
|
|
81
|
+
* The `addMany` function adds multiple nodes to a binary tree and returns an array of the inserted nodes.
|
|
82
|
+
* @param {BinaryTreeNodeId[] | N[]} idsOrNodes - An array of BinaryTreeNodeId objects or N objects. These objects
|
|
83
|
+
* represent the IDs or nodes of the binary tree where the values will be added.
|
|
84
|
+
* @param {N['val'][]} [data] - Optional array of values to be associated with each node being added. If provided, the
|
|
85
|
+
* length of the `data` array should be equal to the length of the `idsOrNodes` array.
|
|
86
86
|
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
87
87
|
*/
|
|
88
|
-
addMany(
|
|
88
|
+
addMany(idsOrNodes: (BinaryTreeNodeId | N)[], data?: N['val'][]): (N | null | undefined)[];
|
|
89
|
+
/**
|
|
90
|
+
* The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
|
|
91
|
+
* constructs a balanced binary search tree using either a recursive or iterative approach.
|
|
92
|
+
* @returns The function `perfectlyBalance()` returns a boolean value.
|
|
93
|
+
*/
|
|
94
|
+
perfectlyBalance(): boolean;
|
|
89
95
|
/**
|
|
90
96
|
* The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
|
|
91
97
|
* node that needs to be balanced.
|
|
@@ -16,7 +16,6 @@ class TreeMultisetNode extends avl_tree_1.AVLTreeNode {
|
|
|
16
16
|
*/
|
|
17
17
|
constructor(id, val, count = 1) {
|
|
18
18
|
super(id, val);
|
|
19
|
-
this._count = 1;
|
|
20
19
|
this._count = count;
|
|
21
20
|
}
|
|
22
21
|
get count() {
|
|
@@ -38,7 +37,7 @@ class TreeMultiset extends avl_tree_1.AVLTree {
|
|
|
38
37
|
* TreeMultiset.
|
|
39
38
|
*/
|
|
40
39
|
constructor(options) {
|
|
41
|
-
super(Object.assign(Object.assign({}, options), {
|
|
40
|
+
super(Object.assign(Object.assign({}, options), { isMergeDuplicatedNodeById: true }));
|
|
42
41
|
this._count = 0;
|
|
43
42
|
}
|
|
44
43
|
get count() {
|
|
@@ -64,97 +63,98 @@ class TreeMultiset extends avl_tree_1.AVLTree {
|
|
|
64
63
|
* @returns the `destNode` after swapping its values with the `srcNode`.
|
|
65
64
|
*/
|
|
66
65
|
swapLocation(srcNode, destNode) {
|
|
67
|
-
const { val, count, height
|
|
66
|
+
const { id, val, count, height } = destNode;
|
|
68
67
|
const tempNode = this.createNode(id, val, count);
|
|
69
68
|
if (tempNode) {
|
|
70
69
|
tempNode.height = height;
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
srcNode.height = tempNode.height;
|
|
80
|
-
}
|
|
70
|
+
destNode.id = srcNode.id;
|
|
71
|
+
destNode.val = srcNode.val;
|
|
72
|
+
destNode.count = srcNode.count;
|
|
73
|
+
destNode.height = srcNode.height;
|
|
74
|
+
srcNode.id = tempNode.id;
|
|
75
|
+
srcNode.val = tempNode.val;
|
|
76
|
+
srcNode.count = tempNode.count;
|
|
77
|
+
srcNode.height = tempNode.height;
|
|
81
78
|
}
|
|
82
79
|
return destNode;
|
|
83
80
|
}
|
|
84
81
|
/**
|
|
85
|
-
* The `add` function adds a new node to a binary tree,
|
|
86
|
-
*
|
|
87
|
-
* @param {BinaryTreeNodeId}
|
|
88
|
-
*
|
|
89
|
-
* @param [val] - The `val` parameter
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* @returns The `add` method returns the inserted node (`N`), `null`, or `undefined`.
|
|
82
|
+
* The `add` function adds a new node to a binary search tree, maintaining the tree's properties and balancing if
|
|
83
|
+
* necessary.
|
|
84
|
+
* @param {BinaryTreeNodeId | N} idOrNode - The `idOrNode` parameter can be either a `BinaryTreeNodeId` or a `N` (which
|
|
85
|
+
* represents a `BinaryTreeNode`).
|
|
86
|
+
* @param [val] - The `val` parameter represents the value to be added to the binary tree node.
|
|
87
|
+
* @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the
|
|
88
|
+
* value should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
|
|
89
|
+
* @returns The method `add` returns either the inserted node (`N`), `null`, or `undefined`.
|
|
94
90
|
*/
|
|
95
|
-
add(
|
|
91
|
+
add(idOrNode, val, count) {
|
|
96
92
|
count = count !== null && count !== void 0 ? count : 1;
|
|
97
|
-
let inserted =
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
let inserted = undefined, newNode;
|
|
94
|
+
if (idOrNode instanceof TreeMultisetNode) {
|
|
95
|
+
newNode = this.createNode(idOrNode.id, idOrNode.val, idOrNode.count);
|
|
96
|
+
}
|
|
97
|
+
else if (idOrNode === null) {
|
|
98
|
+
newNode = null;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
newNode = this.createNode(idOrNode, val, count);
|
|
102
|
+
}
|
|
103
|
+
if (!this.root) {
|
|
100
104
|
this._setRoot(newNode);
|
|
101
105
|
this._setSize(this.size + 1);
|
|
102
|
-
this._setCount(this.count + count);
|
|
103
|
-
inserted =
|
|
106
|
+
newNode && this._setCount(this.count + newNode.count);
|
|
107
|
+
inserted = this.root;
|
|
104
108
|
}
|
|
105
109
|
else {
|
|
106
110
|
let cur = this.root;
|
|
107
111
|
let traversing = true;
|
|
108
112
|
while (traversing) {
|
|
109
|
-
if (cur
|
|
110
|
-
if (
|
|
111
|
-
if (newNode) {
|
|
113
|
+
if (cur) {
|
|
114
|
+
if (newNode) {
|
|
115
|
+
if (this._compare(cur.id, newNode.id) === types_1.CP.eq) {
|
|
112
116
|
cur.val = newNode.val;
|
|
113
|
-
cur.count += count;
|
|
114
|
-
this._setCount(this.count + newNode.count);
|
|
115
|
-
}
|
|
116
|
-
//Duplicates are not accepted.
|
|
117
|
-
traversing = false;
|
|
118
|
-
inserted = cur;
|
|
119
|
-
}
|
|
120
|
-
else if (this._compare(cur.id, id) === types_1.CP.gt) {
|
|
121
|
-
// Traverse left of the node
|
|
122
|
-
if (cur.left === undefined) {
|
|
123
|
-
if (newNode) {
|
|
124
|
-
newNode.parent = cur;
|
|
125
|
-
}
|
|
126
|
-
//Add to the left of the current node
|
|
127
|
-
cur.left = newNode;
|
|
128
|
-
this._setSize(this.size + 1);
|
|
117
|
+
cur.count += newNode.count;
|
|
129
118
|
this._setCount(this.count + newNode.count);
|
|
130
119
|
traversing = false;
|
|
131
|
-
inserted = cur
|
|
120
|
+
inserted = cur;
|
|
132
121
|
}
|
|
133
|
-
else {
|
|
134
|
-
//Traverse
|
|
135
|
-
if (cur.left)
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
122
|
+
else if (this._compare(cur.id, newNode.id) === types_1.CP.gt) {
|
|
123
|
+
// Traverse left of the node
|
|
124
|
+
if (cur.left === undefined) {
|
|
125
|
+
//Add to the left of the current node
|
|
126
|
+
cur.left = newNode;
|
|
127
|
+
this._setSize(this.size + 1);
|
|
128
|
+
this._setCount(this.count + newNode.count);
|
|
129
|
+
traversing = false;
|
|
130
|
+
inserted = cur.left;
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
//Traverse the left of the current node
|
|
134
|
+
if (cur.left)
|
|
135
|
+
cur = cur.left;
|
|
144
136
|
}
|
|
145
|
-
//Add to the right of the current node
|
|
146
|
-
cur.right = newNode;
|
|
147
|
-
this._setSize(this.size + 1);
|
|
148
|
-
this._setCount(this.count + newNode.count);
|
|
149
|
-
traversing = false;
|
|
150
|
-
inserted = (cur.right);
|
|
151
137
|
}
|
|
152
|
-
else {
|
|
153
|
-
//Traverse
|
|
154
|
-
if (cur.right)
|
|
155
|
-
|
|
138
|
+
else if (this._compare(cur.id, newNode.id) === types_1.CP.lt) {
|
|
139
|
+
// Traverse right of the node
|
|
140
|
+
if (cur.right === undefined) {
|
|
141
|
+
//Add to the right of the current node
|
|
142
|
+
cur.right = newNode;
|
|
143
|
+
this._setSize(this.size + 1);
|
|
144
|
+
this._setCount(this.count + newNode.count);
|
|
145
|
+
traversing = false;
|
|
146
|
+
inserted = (cur.right);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
//Traverse the left of the current node
|
|
150
|
+
if (cur.right)
|
|
151
|
+
cur = cur.right;
|
|
152
|
+
}
|
|
156
153
|
}
|
|
157
154
|
}
|
|
155
|
+
else {
|
|
156
|
+
// TODO may need to support null inserted
|
|
157
|
+
}
|
|
158
158
|
}
|
|
159
159
|
else {
|
|
160
160
|
traversing = false;
|
|
@@ -175,27 +175,20 @@ class TreeMultiset extends avl_tree_1.AVLTree {
|
|
|
175
175
|
* `undefined` in certain cases.
|
|
176
176
|
*/
|
|
177
177
|
addTo(newNode, parent) {
|
|
178
|
-
var _a, _b;
|
|
179
178
|
if (parent) {
|
|
180
179
|
if (parent.left === undefined) {
|
|
181
|
-
if (newNode) {
|
|
182
|
-
newNode.parent = parent;
|
|
183
|
-
}
|
|
184
180
|
parent.left = newNode;
|
|
185
181
|
if (newNode !== null) {
|
|
186
182
|
this._setSize(this.size + 1);
|
|
187
|
-
this._setCount(
|
|
183
|
+
this._setCount(this.count + newNode.count);
|
|
188
184
|
}
|
|
189
185
|
return parent.left;
|
|
190
186
|
}
|
|
191
187
|
else if (parent.right === undefined) {
|
|
192
|
-
if (newNode) {
|
|
193
|
-
newNode.parent = parent;
|
|
194
|
-
}
|
|
195
188
|
parent.right = newNode;
|
|
196
189
|
if (newNode !== null) {
|
|
197
190
|
this._setSize(this.size + 1);
|
|
198
|
-
this._setCount(
|
|
191
|
+
this._setCount(this.count + newNode.count);
|
|
199
192
|
}
|
|
200
193
|
return parent.right;
|
|
201
194
|
}
|
|
@@ -208,66 +201,86 @@ class TreeMultiset extends avl_tree_1.AVLTree {
|
|
|
208
201
|
}
|
|
209
202
|
}
|
|
210
203
|
/**
|
|
211
|
-
* The `addMany` function
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
* array of
|
|
204
|
+
* The `addMany` function adds multiple nodes to a binary tree and returns an array of the inserted nodes.
|
|
205
|
+
* @param {BinaryTreeNodeId[] | N[]} idsOrNodes - An array of BinaryTreeNodeId objects or N objects. These objects
|
|
206
|
+
* represent the IDs or nodes of the binary tree where the values will be added.
|
|
207
|
+
* @param {N['val'][]} [data] - Optional array of values to be associated with each node being added. If provided, the
|
|
208
|
+
* length of the `data` array should be equal to the length of the `idsOrNodes` array.
|
|
215
209
|
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
216
210
|
*/
|
|
217
|
-
addMany(data) {
|
|
211
|
+
addMany(idsOrNodes, data) {
|
|
218
212
|
var _a;
|
|
219
213
|
// TODO not sure addMany not be run multi times
|
|
220
214
|
const inserted = [];
|
|
221
215
|
const map = new Map();
|
|
222
|
-
if (this.
|
|
223
|
-
for (const
|
|
224
|
-
map.set(
|
|
216
|
+
if (this.isMergeDuplicatedNodeById) {
|
|
217
|
+
for (const idOrNode of idsOrNodes)
|
|
218
|
+
map.set(idOrNode, ((_a = map.get(idOrNode)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
225
219
|
}
|
|
226
|
-
for (
|
|
227
|
-
|
|
228
|
-
|
|
220
|
+
for (let i = 0; i < idsOrNodes.length; i++) {
|
|
221
|
+
const idOrNode = idsOrNodes[i];
|
|
222
|
+
if (idOrNode instanceof TreeMultisetNode) {
|
|
223
|
+
inserted.push(this.add(idOrNode.id, idOrNode.val, idOrNode.count));
|
|
229
224
|
continue;
|
|
230
225
|
}
|
|
231
|
-
if (
|
|
226
|
+
if (idOrNode === null) {
|
|
232
227
|
inserted.push(this.add(NaN, null, 0));
|
|
233
228
|
continue;
|
|
234
229
|
}
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
else if (nodeOrId instanceof Object) {
|
|
242
|
-
if (this.autoIncrementId) {
|
|
243
|
-
newId = this.maxId + 1;
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
if (Object.keys(nodeOrId).includes('id')) {
|
|
247
|
-
newId = nodeOrId.id;
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false');
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
230
|
+
const count = this.isMergeDuplicatedNodeById ? map.get(idOrNode) : 1;
|
|
231
|
+
const val = data === null || data === void 0 ? void 0 : data[i];
|
|
232
|
+
if (this.isMergeDuplicatedNodeById) {
|
|
233
|
+
if (map.has(idOrNode)) {
|
|
234
|
+
inserted.push(this.add(idOrNode, val, count));
|
|
235
|
+
map.delete(idOrNode);
|
|
253
236
|
}
|
|
254
237
|
}
|
|
255
238
|
else {
|
|
256
|
-
|
|
257
|
-
continue;
|
|
239
|
+
inserted.push(this.add(idOrNode, val, 1));
|
|
258
240
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
241
|
+
}
|
|
242
|
+
return inserted;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
|
|
246
|
+
* constructs a balanced binary search tree using either a recursive or iterative approach.
|
|
247
|
+
* @returns The function `perfectlyBalance()` returns a boolean value.
|
|
248
|
+
*/
|
|
249
|
+
perfectlyBalance() {
|
|
250
|
+
const sorted = this.DFS('in', 'node'), n = sorted.length;
|
|
251
|
+
if (sorted.length < 1)
|
|
252
|
+
return false;
|
|
253
|
+
this.clear();
|
|
254
|
+
if (this.loopType === types_1.LoopType.RECURSIVE) {
|
|
255
|
+
const buildBalanceBST = (l, r) => {
|
|
256
|
+
if (l > r)
|
|
257
|
+
return;
|
|
258
|
+
const m = l + Math.floor((r - l) / 2);
|
|
259
|
+
const midNode = sorted[m];
|
|
260
|
+
this.add(midNode.id, midNode.val, midNode.count);
|
|
261
|
+
buildBalanceBST(l, m - 1);
|
|
262
|
+
buildBalanceBST(m + 1, r);
|
|
263
|
+
};
|
|
264
|
+
buildBalanceBST(0, n - 1);
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
const stack = [[0, n - 1]];
|
|
269
|
+
while (stack.length > 0) {
|
|
270
|
+
const popped = stack.pop();
|
|
271
|
+
if (popped) {
|
|
272
|
+
const [l, r] = popped;
|
|
273
|
+
if (l <= r) {
|
|
274
|
+
const m = l + Math.floor((r - l) / 2);
|
|
275
|
+
const midNode = sorted[m];
|
|
276
|
+
this.add(midNode.id, midNode.val, midNode.count);
|
|
277
|
+
stack.push([m + 1, r]);
|
|
278
|
+
stack.push([l, m - 1]);
|
|
279
|
+
}
|
|
263
280
|
}
|
|
264
281
|
}
|
|
265
|
-
|
|
266
|
-
inserted.push(this.add(newId, nodeOrId, 1));
|
|
267
|
-
}
|
|
268
|
-
this._setMaxId(newId);
|
|
282
|
+
return true;
|
|
269
283
|
}
|
|
270
|
-
return inserted;
|
|
271
284
|
}
|
|
272
285
|
/**
|
|
273
286
|
* The `remove` function removes a node from a binary search tree and returns the deleted node along with the parent
|
|
@@ -282,7 +295,7 @@ class TreeMultiset extends avl_tree_1.AVLTree {
|
|
|
282
295
|
const bstDeletedResult = [];
|
|
283
296
|
if (!this.root)
|
|
284
297
|
return bstDeletedResult;
|
|
285
|
-
const curr =
|
|
298
|
+
const curr = this.get(nodeOrId);
|
|
286
299
|
if (!curr)
|
|
287
300
|
return bstDeletedResult;
|
|
288
301
|
const parent = (curr === null || curr === void 0 ? void 0 : curr.parent) ? curr.parent : null;
|
|
@@ -314,15 +327,18 @@ class TreeMultiset extends avl_tree_1.AVLTree {
|
|
|
314
327
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
315
328
|
orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
|
|
316
329
|
if (parentOfLeftSubTreeMax) {
|
|
317
|
-
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
330
|
+
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {
|
|
318
331
|
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
319
|
-
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
320
334
|
parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
|
|
335
|
+
}
|
|
321
336
|
needBalanced = parentOfLeftSubTreeMax;
|
|
322
337
|
}
|
|
323
338
|
}
|
|
324
339
|
}
|
|
325
340
|
this._setSize(this.size - 1);
|
|
341
|
+
// TODO How to handle when the count of target node is lesser than current node's count
|
|
326
342
|
this._setCount(this.count - orgCurrent.count);
|
|
327
343
|
}
|
|
328
344
|
bstDeletedResult.push({ deleted: orgCurrent, needBalanced });
|
|
@@ -21,20 +21,17 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
|
|
|
21
21
|
get visitedId(): BinaryTreeNodeId[];
|
|
22
22
|
get visitedVal(): Array<N['val']>;
|
|
23
23
|
get visitedNode(): N[];
|
|
24
|
-
get visitedCount(): number[];
|
|
25
24
|
get visitedLeftSum(): number[];
|
|
26
|
-
get
|
|
27
|
-
get maxId(): number;
|
|
28
|
-
get isMergeDuplicatedVal(): boolean;
|
|
25
|
+
get isMergeDuplicatedNodeById(): boolean;
|
|
29
26
|
get root(): N | null;
|
|
30
27
|
get size(): number;
|
|
31
28
|
swapLocation(srcNode: N, destNode: N): N;
|
|
32
29
|
clear(): void;
|
|
33
30
|
isEmpty(): boolean;
|
|
34
|
-
add(id: BinaryTreeNodeId, val?: N['val']
|
|
31
|
+
add(id: BinaryTreeNodeId | N, val?: N['val']): N | null | undefined;
|
|
35
32
|
addTo(newNode: N | null, parent: N): N | null | undefined;
|
|
36
|
-
addMany(
|
|
37
|
-
fill(
|
|
33
|
+
addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[];
|
|
34
|
+
fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array<N['val']>): boolean;
|
|
38
35
|
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[];
|
|
39
36
|
getDepth(node: N): number;
|
|
40
37
|
getHeight(beginRoot?: N | null): number;
|
|
@@ -50,8 +47,8 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
|
|
|
50
47
|
getRightMost(): N | null;
|
|
51
48
|
getRightMost(node: N): N;
|
|
52
49
|
getRightMost(node?: N | null): N | null;
|
|
53
|
-
|
|
54
|
-
isBST(
|
|
50
|
+
isSubtreeBST(node: N | null): boolean;
|
|
51
|
+
isBST(): boolean;
|
|
55
52
|
getSubTreeSize(subTreeRoot: N | null | undefined): number;
|
|
56
53
|
subTreeSum(subTreeRoot: N, propertyName?: BinaryTreeNodePropertyName): number;
|
|
57
54
|
subTreeAdd(subTreeRoot: N, delta: number, propertyName?: BinaryTreeNodePropertyName): boolean;
|
|
@@ -31,6 +31,5 @@ export type AbstractBinaryTreeNodeProperties<N extends AbstractBinaryTreeNode<N[
|
|
|
31
31
|
export type AbstractBinaryTreeNodeNested<T> = AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, AbstractBinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
32
32
|
export type AbstractBinaryTreeOptions = {
|
|
33
33
|
loopType?: LoopType;
|
|
34
|
-
|
|
35
|
-
isMergeDuplicatedVal?: boolean;
|
|
34
|
+
isMergeDuplicatedNodeById?: boolean;
|
|
36
35
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TreeMultisetNode } from '../binary-tree';
|
|
2
2
|
import { AVLTreeOptions } from './avl-tree';
|
|
3
3
|
export type TreeMultisetNodeNested<T> = TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, TreeMultisetNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>;
|
|
4
|
-
export type TreeMultisetOptions = Omit<AVLTreeOptions, '
|
|
5
|
-
|
|
4
|
+
export type TreeMultisetOptions = Omit<AVLTreeOptions, 'isMergeDuplicatedNodeById'> & {
|
|
5
|
+
isMergeDuplicatedNodeById: true;
|
|
6
6
|
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-structure-typed",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.8",
|
|
4
4
|
"description": "Javascript & TypeScript Data Structure Library, meticulously crafted to empower developers with a versatile set of essential data structures. Our library includes a wide range of data structures, such as Binary Tree, AVL Tree, Binary Search Tree (BST), Tree Multiset, Segment Tree, Binary Indexed Tree, Graph, Directed Graph, Undirected Graph, Singly Linked List, Hash, CoordinateSet, CoordinateMap, Heap, Doubly Linked List, Priority Queue, Max Priority Queue, Min Priority Queue, Queue, ObjectDeque, ArrayDeque, Stack, and Trie. Each data structure is thoughtfully designed and implemented using TypeScript to provide efficient, reliable, and easy-to-use solutions for your programming needs. Whether you're optimizing algorithms, managing data, or enhancing performance, our TypeScript Data Structure Library is your go-to resource. Elevate your coding experience with these fundamental building blocks for software development.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "rm -rf dist && npx tsc",
|
|
8
8
|
"test": "jest",
|
|
9
|
+
"update:test-deps": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multiset-typed trie-typed undirected-graph-typed --save-dev",
|
|
9
10
|
"build:docs": "typedoc --out docs ./src",
|
|
10
11
|
"deps:check": "dependency-cruiser src",
|
|
11
12
|
"build:publish": "npm run test && npm run build && npm run build:docs && npm publish"
|
|
@@ -58,16 +59,32 @@
|
|
|
58
59
|
"devDependencies": {
|
|
59
60
|
"@types/jest": "^29.5.3",
|
|
60
61
|
"@types/node": "^20.4.9",
|
|
62
|
+
"avl-tree-typed": "^1.19.7",
|
|
63
|
+
"binary-tree-typed": "^1.19.7",
|
|
64
|
+
"bst-typed": "^1.19.7",
|
|
61
65
|
"dependency-cruiser": "^13.1.2",
|
|
66
|
+
"deque-typed": "^1.19.7",
|
|
67
|
+
"directed-graph-typed": "^1.19.7",
|
|
68
|
+
"doubly-linked-list-typed": "^1.19.7",
|
|
69
|
+
"graph-typed": "^1.19.7",
|
|
70
|
+
"heap-typed": "^1.19.7",
|
|
62
71
|
"jest": "^29.6.2",
|
|
72
|
+
"linked-list-typed": "^1.19.7",
|
|
73
|
+
"max-heap-typed": "^1.19.7",
|
|
74
|
+
"max-priority-queue-typed": "^1.19.7",
|
|
75
|
+
"min-heap-typed": "^1.19.7",
|
|
76
|
+
"min-priority-queue-typed": "^1.19.7",
|
|
77
|
+
"priority-queue-typed": "^1.19.7",
|
|
78
|
+
"singly-linked-list-typed": "^1.19.7",
|
|
79
|
+
"stack-typed": "^1.19.7",
|
|
80
|
+
"tree-multiset-typed": "^1.19.7",
|
|
81
|
+
"trie-typed": "^1.19.7",
|
|
63
82
|
"ts-jest": "^29.1.1",
|
|
64
83
|
"typedoc": "^0.24.8",
|
|
65
|
-
"typescript": "^4.9.5"
|
|
84
|
+
"typescript": "^4.9.5",
|
|
85
|
+
"undirected-graph-typed": "^1.19.7"
|
|
66
86
|
},
|
|
67
87
|
"dependencies": {
|
|
68
|
-
"avl-tree-typed": "^1.19.6",
|
|
69
|
-
"bst-typed": "^1.19.6",
|
|
70
|
-
"heap-typed": "^1.19.6",
|
|
71
88
|
"zod": "^3.22.2"
|
|
72
89
|
}
|
|
73
90
|
}
|