data-structure-typed 1.19.7 → 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/heap/heap.d.ts +4 -3
- package/dist/data-structures/heap/heap.js +12 -33
- 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/graph/abstract-graph.ts +1 -0
- package/src/data-structures/heap/heap.ts +12 -38
- 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
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
|
|
9
9
|
import type {BinaryTreeNodeId, BinaryTreeNodeNested, BinaryTreeOptions} from '../types';
|
|
10
10
|
import {AbstractBinaryTree, AbstractBinaryTreeNode} from './abstract-binary-tree';
|
|
11
|
-
import {IBinaryTree, IBinaryTreeNode} from '../interfaces
|
|
11
|
+
import {IBinaryTree, IBinaryTreeNode} from '../interfaces';
|
|
12
12
|
|
|
13
13
|
export class BinaryTreeNode<T = any, NEIGHBOR extends BinaryTreeNode<T, NEIGHBOR> = BinaryTreeNodeNested<T>> extends AbstractBinaryTreeNode<T, NEIGHBOR> implements IBinaryTreeNode<T, NEIGHBOR> {
|
|
14
|
-
|
|
14
|
+
constructor(id: BinaryTreeNodeId, val?: T) {
|
|
15
|
+
super(id, val);
|
|
16
|
+
}
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export class BinaryTree<N extends BinaryTreeNode<N['val'], N> = BinaryTreeNode> extends AbstractBinaryTree<N> implements IBinaryTree<N> {
|
|
@@ -11,7 +11,9 @@ import {BinaryTree, BinaryTreeNode} from './binary-tree';
|
|
|
11
11
|
import {IBST, IBSTNode} from '../interfaces';
|
|
12
12
|
|
|
13
13
|
export class BSTNode<T = any, NEIGHBOR extends BSTNode<T, NEIGHBOR> = BSTNodeNested<T>> extends BinaryTreeNode<T, NEIGHBOR> implements IBSTNode<T, NEIGHBOR> {
|
|
14
|
-
|
|
14
|
+
constructor(id: BinaryTreeNodeId, val?: T) {
|
|
15
|
+
super(id, val);
|
|
16
|
+
}
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N> implements IBST<N> {
|
|
@@ -51,6 +53,7 @@ export class BST<N extends BSTNode<N['val'], N> = BSTNode> extends BinaryTree<N>
|
|
|
51
53
|
* If the node was not added (e.g., due to a duplicate ID), it returns `null` or `undefined`.
|
|
52
54
|
*/
|
|
53
55
|
override add(id: BinaryTreeNodeId, val?: N['val']): N | null | undefined {
|
|
56
|
+
// TODO support node as a param
|
|
54
57
|
let inserted: N | null = null;
|
|
55
58
|
const newNode = this.createNode(id, val);
|
|
56
59
|
if (this.root === null) {
|
|
@@ -4,12 +4,12 @@ import {BST, BSTNode} from './bst';
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
export class RBTreeNode<T = any, NEIGHBOR extends RBTreeNode<T, NEIGHBOR> = RBTreeNodeNested<T>> extends BSTNode<T, NEIGHBOR> implements IRBTreeNode<T, NEIGHBOR> {
|
|
7
|
-
constructor(id: BinaryTreeNodeId, color: RBColor
|
|
7
|
+
constructor(id: BinaryTreeNodeId, val?: T, color: RBColor = RBColor.RED) {
|
|
8
8
|
super(id, val);
|
|
9
9
|
this._color = color;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
private _color: RBColor
|
|
12
|
+
private _color: RBColor;
|
|
13
13
|
|
|
14
14
|
get color(): RBColor {
|
|
15
15
|
return this._color;
|
|
@@ -60,7 +60,7 @@ export class RBTree<N extends RBTreeNode<N['val'], N> = RBTreeNode> extends BST<
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
override createNode(id: BinaryTreeNodeId, val?: N['val']): N {
|
|
63
|
-
return new RBTreeNode(id, RBColor.RED
|
|
63
|
+
return new RBTreeNode(id, val, RBColor.RED) as N;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// private override _root: BinaryTreeNode<N> | null = null;
|
|
@@ -9,7 +9,6 @@ import type {BinaryTreeNodeId, TreeMultisetNodeNested, TreeMultisetOptions} from
|
|
|
9
9
|
import {BinaryTreeDeletedResult, CP, DFSOrderPattern, FamilyPosition, LoopType, NodeOrPropertyName} from '../types';
|
|
10
10
|
import {ITreeMultiset, ITreeMultisetNode} from '../interfaces';
|
|
11
11
|
import {AVLTree, AVLTreeNode} from './avl-tree';
|
|
12
|
-
import {ObjectWithNumberId} from '../../utils';
|
|
13
12
|
|
|
14
13
|
export class TreeMultisetNode<T = any, NEIGHBOR extends TreeMultisetNode<T, NEIGHBOR> = TreeMultisetNodeNested<T>> extends AVLTreeNode<T, NEIGHBOR> implements ITreeMultisetNode<T, NEIGHBOR> {
|
|
15
14
|
|
|
@@ -28,7 +27,7 @@ export class TreeMultisetNode<T = any, NEIGHBOR extends TreeMultisetNode<T, NEIG
|
|
|
28
27
|
this._count = count;
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
private _count
|
|
30
|
+
private _count: number;
|
|
32
31
|
|
|
33
32
|
get count(): number {
|
|
34
33
|
return this._count;
|
|
@@ -51,7 +50,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
51
50
|
* TreeMultiset.
|
|
52
51
|
*/
|
|
53
52
|
constructor(options?: TreeMultisetOptions) {
|
|
54
|
-
super({...options,
|
|
53
|
+
super({...options, isMergeDuplicatedNodeById: true});
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
private _count = 0;
|
|
@@ -81,95 +80,93 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
81
80
|
* @returns the `destNode` after swapping its values with the `srcNode`.
|
|
82
81
|
*/
|
|
83
82
|
override swapLocation(srcNode: N, destNode: N): N {
|
|
84
|
-
const {val, count, height
|
|
83
|
+
const {id, val, count, height} = destNode;
|
|
85
84
|
const tempNode = this.createNode(id, val, count);
|
|
86
85
|
if (tempNode) {
|
|
87
86
|
tempNode.height = height;
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
destNode.height = srcNode.height;
|
|
88
|
+
destNode.id = srcNode.id;
|
|
89
|
+
destNode.val = srcNode.val;
|
|
90
|
+
destNode.count = srcNode.count;
|
|
91
|
+
destNode.height = srcNode.height;
|
|
94
92
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
93
|
+
srcNode.id = tempNode.id;
|
|
94
|
+
srcNode.val = tempNode.val;
|
|
95
|
+
srcNode.count = tempNode.count;
|
|
96
|
+
srcNode.height = tempNode.height;
|
|
100
97
|
}
|
|
101
98
|
|
|
102
99
|
return destNode;
|
|
103
100
|
}
|
|
104
101
|
|
|
105
102
|
/**
|
|
106
|
-
* The `add` function adds a new node to a binary tree,
|
|
107
|
-
*
|
|
108
|
-
* @param {BinaryTreeNodeId}
|
|
109
|
-
*
|
|
110
|
-
* @param [val] - The `val` parameter
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* @returns The `add` method returns the inserted node (`N`), `null`, or `undefined`.
|
|
103
|
+
* The `add` function adds a new node to a binary search tree, maintaining the tree's properties and balancing if
|
|
104
|
+
* necessary.
|
|
105
|
+
* @param {BinaryTreeNodeId | N} idOrNode - The `idOrNode` parameter can be either a `BinaryTreeNodeId` or a `N` (which
|
|
106
|
+
* represents a `BinaryTreeNode`).
|
|
107
|
+
* @param [val] - The `val` parameter represents the value to be added to the binary tree node.
|
|
108
|
+
* @param {number} [count] - The `count` parameter is an optional parameter that specifies the number of times the
|
|
109
|
+
* value should be added to the binary tree. If the `count` parameter is not provided, it defaults to 1.
|
|
110
|
+
* @returns The method `add` returns either the inserted node (`N`), `null`, or `undefined`.
|
|
115
111
|
*/
|
|
116
|
-
override add(
|
|
112
|
+
override add(idOrNode: BinaryTreeNodeId | N | null, val?: N['val'], count?: number): N | null | undefined {
|
|
117
113
|
count = count ?? 1;
|
|
118
|
-
let inserted: N | null = null;
|
|
119
|
-
|
|
120
|
-
|
|
114
|
+
let inserted: N | null | undefined = undefined, newNode: N | null;
|
|
115
|
+
if (idOrNode instanceof TreeMultisetNode) {
|
|
116
|
+
newNode = this.createNode(idOrNode.id, idOrNode.val, idOrNode.count);
|
|
117
|
+
} else if (idOrNode === null) {
|
|
118
|
+
newNode = null;
|
|
119
|
+
} else {
|
|
120
|
+
newNode = this.createNode(idOrNode, val, count);
|
|
121
|
+
}
|
|
122
|
+
if (!this.root) {
|
|
121
123
|
this._setRoot(newNode);
|
|
122
124
|
this._setSize(this.size + 1);
|
|
123
|
-
this._setCount(this.count + count);
|
|
124
|
-
inserted =
|
|
125
|
+
newNode && this._setCount(this.count + newNode.count);
|
|
126
|
+
inserted = this.root;
|
|
125
127
|
} else {
|
|
126
128
|
let cur = this.root;
|
|
127
129
|
let traversing = true;
|
|
128
130
|
while (traversing) {
|
|
129
|
-
if (cur
|
|
130
|
-
if (
|
|
131
|
-
if (newNode) {
|
|
131
|
+
if (cur) {
|
|
132
|
+
if (newNode) {
|
|
133
|
+
if (this._compare(cur.id, newNode.id) === CP.eq) {
|
|
132
134
|
cur.val = newNode.val;
|
|
133
|
-
cur.count += count;
|
|
135
|
+
cur.count += newNode.count;
|
|
134
136
|
this._setCount(this.count + newNode.count);
|
|
135
|
-
}
|
|
136
|
-
//Duplicates are not accepted.
|
|
137
|
-
traversing = false;
|
|
138
|
-
inserted = cur;
|
|
139
|
-
} else if (this._compare(cur.id, id) === CP.gt) {
|
|
140
|
-
// Traverse left of the node
|
|
141
|
-
if (cur.left === undefined) {
|
|
142
|
-
if (newNode) {
|
|
143
|
-
newNode.parent = cur;
|
|
144
|
-
}
|
|
145
|
-
//Add to the left of the current node
|
|
146
|
-
cur.left = newNode;
|
|
147
|
-
this._setSize(this.size + 1);
|
|
148
|
-
this._setCount(this.count + newNode.count);
|
|
149
|
-
|
|
150
137
|
traversing = false;
|
|
151
|
-
inserted = cur
|
|
152
|
-
} else {
|
|
153
|
-
//Traverse
|
|
154
|
-
if (cur.left
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
138
|
+
inserted = cur;
|
|
139
|
+
} else if (this._compare(cur.id, newNode.id) === CP.gt) {
|
|
140
|
+
// Traverse left of the node
|
|
141
|
+
if (cur.left === undefined) {
|
|
142
|
+
//Add to the left of the current node
|
|
143
|
+
cur.left = newNode;
|
|
144
|
+
this._setSize(this.size + 1);
|
|
145
|
+
this._setCount(this.count + newNode.count);
|
|
146
|
+
|
|
147
|
+
traversing = false;
|
|
148
|
+
inserted = cur.left;
|
|
149
|
+
} else {
|
|
150
|
+
//Traverse the left of the current node
|
|
151
|
+
if (cur.left) cur = cur.left;
|
|
152
|
+
}
|
|
153
|
+
} else if (this._compare(cur.id, newNode.id) === CP.lt) {
|
|
154
|
+
// Traverse right of the node
|
|
155
|
+
if (cur.right === undefined) {
|
|
156
|
+
//Add to the right of the current node
|
|
157
|
+
cur.right = newNode;
|
|
158
|
+
this._setSize(this.size + 1);
|
|
159
|
+
this._setCount(this.count + newNode.count);
|
|
160
|
+
|
|
161
|
+
traversing = false;
|
|
162
|
+
inserted = (cur.right);
|
|
163
|
+
} else {
|
|
164
|
+
//Traverse the left of the current node
|
|
165
|
+
if (cur.right) cur = cur.right;
|
|
161
166
|
}
|
|
162
|
-
//Add to the right of the current node
|
|
163
|
-
cur.right = newNode;
|
|
164
|
-
this._setSize(this.size + 1);
|
|
165
|
-
this._setCount(this.count + newNode.count);
|
|
166
|
-
|
|
167
|
-
traversing = false;
|
|
168
|
-
inserted = (cur.right);
|
|
169
|
-
} else {
|
|
170
|
-
//Traverse the left of the current node
|
|
171
|
-
if (cur.right) cur = cur.right;
|
|
172
167
|
}
|
|
168
|
+
} else {
|
|
169
|
+
// TODO may need to support null inserted
|
|
173
170
|
}
|
|
174
171
|
} else {
|
|
175
172
|
traversing = false;
|
|
@@ -192,24 +189,19 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
192
189
|
override addTo(newNode: N | null, parent: N): N | null | undefined {
|
|
193
190
|
if (parent) {
|
|
194
191
|
if (parent.left === undefined) {
|
|
195
|
-
if (newNode) {
|
|
196
|
-
newNode.parent = parent;
|
|
197
|
-
}
|
|
198
192
|
parent.left = newNode;
|
|
199
193
|
if (newNode !== null) {
|
|
200
194
|
this._setSize(this.size + 1);
|
|
201
|
-
this._setCount(this.count + newNode.count
|
|
195
|
+
this._setCount(this.count + newNode.count)
|
|
202
196
|
}
|
|
203
197
|
|
|
204
198
|
return parent.left;
|
|
205
199
|
} else if (parent.right === undefined) {
|
|
206
|
-
|
|
207
|
-
newNode.parent = parent;
|
|
208
|
-
}
|
|
200
|
+
|
|
209
201
|
parent.right = newNode;
|
|
210
202
|
if (newNode !== null) {
|
|
211
203
|
this._setSize(this.size + 1);
|
|
212
|
-
this._setCount(this.count + newNode.count
|
|
204
|
+
this._setCount(this.count + newNode.count);
|
|
213
205
|
}
|
|
214
206
|
return parent.right;
|
|
215
207
|
} else {
|
|
@@ -221,66 +213,88 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
221
213
|
}
|
|
222
214
|
|
|
223
215
|
/**
|
|
224
|
-
* The `addMany` function
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
* array of
|
|
216
|
+
* The `addMany` function adds multiple nodes to a binary tree and returns an array of the inserted nodes.
|
|
217
|
+
* @param {BinaryTreeNodeId[] | N[]} idsOrNodes - An array of BinaryTreeNodeId objects or N objects. These objects
|
|
218
|
+
* represent the IDs or nodes of the binary tree where the values will be added.
|
|
219
|
+
* @param {N['val'][]} [data] - Optional array of values to be associated with each node being added. If provided, the
|
|
220
|
+
* length of the `data` array should be equal to the length of the `idsOrNodes` array.
|
|
228
221
|
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
|
229
222
|
*/
|
|
230
|
-
override addMany(
|
|
223
|
+
override addMany(idsOrNodes: (BinaryTreeNodeId | N)[], data?: N['val'][]): (N | null | undefined)[] {
|
|
231
224
|
// TODO not sure addMany not be run multi times
|
|
232
225
|
const inserted: (N | null | undefined)[] = [];
|
|
233
|
-
const map: Map<N |
|
|
226
|
+
const map: Map<N | BinaryTreeNodeId, number> = new Map();
|
|
234
227
|
|
|
235
|
-
if (this.
|
|
236
|
-
for (const
|
|
228
|
+
if (this.isMergeDuplicatedNodeById) {
|
|
229
|
+
for (const idOrNode of idsOrNodes) map.set(idOrNode, (map.get(idOrNode) ?? 0) + 1);
|
|
237
230
|
}
|
|
238
231
|
|
|
239
|
-
for (
|
|
240
|
-
|
|
241
|
-
if (
|
|
242
|
-
inserted.push(this.add(
|
|
232
|
+
for (let i = 0; i < idsOrNodes.length; i++) {
|
|
233
|
+
const idOrNode = idsOrNodes[i];
|
|
234
|
+
if (idOrNode instanceof TreeMultisetNode) {
|
|
235
|
+
inserted.push(this.add(idOrNode.id, idOrNode.val, idOrNode.count));
|
|
243
236
|
continue;
|
|
244
237
|
}
|
|
245
238
|
|
|
246
|
-
if (
|
|
239
|
+
if (idOrNode === null) {
|
|
247
240
|
inserted.push(this.add(NaN, null, 0));
|
|
248
241
|
continue;
|
|
249
242
|
}
|
|
250
243
|
|
|
251
|
-
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (this.autoIncrementId) {
|
|
258
|
-
newId = this.maxId + 1;
|
|
259
|
-
} else {
|
|
260
|
-
if (Object.keys(nodeOrId).includes('id')) {
|
|
261
|
-
newId = (nodeOrId as ObjectWithNumberId).id;
|
|
262
|
-
} else {
|
|
263
|
-
console.warn(nodeOrId, 'Object value must has an id property when the autoIncrementId is false');
|
|
264
|
-
continue;
|
|
265
|
-
}
|
|
244
|
+
const count = this.isMergeDuplicatedNodeById ? map.get(idOrNode) : 1;
|
|
245
|
+
const val = data?.[i];
|
|
246
|
+
if (this.isMergeDuplicatedNodeById) {
|
|
247
|
+
if (map.has(idOrNode)) {
|
|
248
|
+
inserted.push(this.add(idOrNode, val, count));
|
|
249
|
+
map.delete(idOrNode);
|
|
266
250
|
}
|
|
267
251
|
} else {
|
|
268
|
-
|
|
269
|
-
continue;
|
|
252
|
+
inserted.push(this.add(idOrNode, val, 1));
|
|
270
253
|
}
|
|
254
|
+
}
|
|
255
|
+
return inserted;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* The `perfectlyBalance` function takes a binary tree, performs a depth-first search to sort the nodes, and then
|
|
260
|
+
* constructs a balanced binary search tree using either a recursive or iterative approach.
|
|
261
|
+
* @returns The function `perfectlyBalance()` returns a boolean value.
|
|
262
|
+
*/
|
|
263
|
+
override perfectlyBalance(): boolean {
|
|
264
|
+
const sorted = this.DFS('in', 'node'), n = sorted.length;
|
|
265
|
+
if (sorted.length < 1) return false;
|
|
266
|
+
|
|
267
|
+
this.clear();
|
|
268
|
+
|
|
269
|
+
if (this.loopType === LoopType.RECURSIVE) {
|
|
270
|
+
const buildBalanceBST = (l: number, r: number) => {
|
|
271
|
+
if (l > r) return;
|
|
272
|
+
const m = l + Math.floor((r - l) / 2);
|
|
273
|
+
const midNode = sorted[m];
|
|
274
|
+
this.add(midNode.id, midNode.val, midNode.count);
|
|
275
|
+
buildBalanceBST(l, m - 1);
|
|
276
|
+
buildBalanceBST(m + 1, r);
|
|
277
|
+
};
|
|
271
278
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
279
|
+
buildBalanceBST(0, n - 1);
|
|
280
|
+
return true;
|
|
281
|
+
} else {
|
|
282
|
+
const stack: [[number, number]] = [[0, n - 1]];
|
|
283
|
+
while (stack.length > 0) {
|
|
284
|
+
const popped = stack.pop();
|
|
285
|
+
if (popped) {
|
|
286
|
+
const [l, r] = popped;
|
|
287
|
+
if (l <= r) {
|
|
288
|
+
const m = l + Math.floor((r - l) / 2);
|
|
289
|
+
const midNode = sorted[m];
|
|
290
|
+
this.add(midNode.id, midNode.val, midNode.count);
|
|
291
|
+
stack.push([m + 1, r]);
|
|
292
|
+
stack.push([l, m - 1]);
|
|
293
|
+
}
|
|
276
294
|
}
|
|
277
|
-
} else {
|
|
278
|
-
inserted.push(this.add(newId, nodeOrId, 1));
|
|
279
295
|
}
|
|
280
|
-
|
|
281
|
-
this._setMaxId(newId);
|
|
296
|
+
return true;
|
|
282
297
|
}
|
|
283
|
-
return inserted;
|
|
284
298
|
}
|
|
285
299
|
|
|
286
300
|
/**
|
|
@@ -296,7 +310,7 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
296
310
|
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
|
297
311
|
if (!this.root) return bstDeletedResult;
|
|
298
312
|
|
|
299
|
-
const curr: N | null =
|
|
313
|
+
const curr: N | null = this.get(nodeOrId);
|
|
300
314
|
if (!curr) return bstDeletedResult;
|
|
301
315
|
|
|
302
316
|
const parent: N | null = curr?.parent ? curr.parent : null;
|
|
@@ -324,13 +338,17 @@ export class TreeMultiset<N extends TreeMultisetNode<N['val'], N> = TreeMultiset
|
|
|
324
338
|
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
|
325
339
|
orgCurrent = this.swapLocation(curr, leftSubTreeRightMost);
|
|
326
340
|
if (parentOfLeftSubTreeMax) {
|
|
327
|
-
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
|
328
|
-
|
|
341
|
+
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) {
|
|
342
|
+
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
|
343
|
+
} else {
|
|
344
|
+
parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
|
|
345
|
+
}
|
|
329
346
|
needBalanced = parentOfLeftSubTreeMax;
|
|
330
347
|
}
|
|
331
348
|
}
|
|
332
349
|
}
|
|
333
350
|
this._setSize(this.size - 1);
|
|
351
|
+
// TODO How to handle when the count of target node is lesser than current node's count
|
|
334
352
|
this._setCount(this.count - orgCurrent.count);
|
|
335
353
|
}
|
|
336
354
|
|
|
@@ -170,6 +170,7 @@ export abstract class AbstractGraph<V extends AbstractVertex<any>, E extends Abs
|
|
|
170
170
|
addVertex(idOrVertex: VertexId | V, val?: V['val']): boolean {
|
|
171
171
|
if (idOrVertex instanceof AbstractVertex) {
|
|
172
172
|
return this._addVertexOnly(idOrVertex);
|
|
173
|
+
|
|
173
174
|
} else {
|
|
174
175
|
const newVertex = this.createVertex(idOrVertex, val);
|
|
175
176
|
return this._addVertexOnly(newVertex);
|
|
@@ -44,9 +44,9 @@ export class HeapItem<T = number> {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
export abstract class Heap<T = number> {
|
|
47
|
-
|
|
48
47
|
/**
|
|
49
|
-
* The
|
|
48
|
+
* The function is a constructor for a class that initializes a priority callback function based on the
|
|
49
|
+
* options provided.
|
|
50
50
|
* @param [options] - An optional object that contains configuration options for the Heap.
|
|
51
51
|
*/
|
|
52
52
|
protected constructor(options?: HeapOptions<T>) {
|
|
@@ -91,16 +91,9 @@ export abstract class Heap<T = number> {
|
|
|
91
91
|
peek(isItem?: undefined): T | undefined;
|
|
92
92
|
peek(isItem: false): T | undefined;
|
|
93
93
|
peek(isItem: true): HeapItem<T> | null;
|
|
94
|
-
|
|
95
94
|
/**
|
|
96
|
-
* The `peek` function returns the top item
|
|
97
|
-
*
|
|
98
|
-
* @param {boolean} [isItem] - The `isItem` parameter is an optional boolean parameter that determines whether the
|
|
99
|
-
* method should return the entire `HeapItem` object or just the value of the item. If `isItem` is set to `true`, the
|
|
100
|
-
* method will return the `HeapItem` object. If `isItem`
|
|
101
|
-
* @returns The `peek` method returns either a `HeapItem<T>` object, `null`, `T`, or `undefined`. The specific return
|
|
102
|
-
* type depends on the value of the `isItem` parameter. If `isItem` is `true`, then the method returns a `HeapItem<T>`
|
|
103
|
-
* object or `null` if the heap is empty. If `isItem` is `false`
|
|
95
|
+
* The `peek` function returns the top item in the priority queue without removing it.
|
|
96
|
+
* @returns The `peek()` method is returning either a `HeapItem<T>` object or `null`.Returns an val with the highest priority in the queue
|
|
104
97
|
*/
|
|
105
98
|
peek(isItem?: boolean): HeapItem<T> | null | T | undefined {
|
|
106
99
|
isItem = isItem ?? false;
|
|
@@ -111,16 +104,9 @@ export abstract class Heap<T = number> {
|
|
|
111
104
|
peekLast(isItem?: undefined): T | undefined;
|
|
112
105
|
peekLast(isItem: false): T | undefined;
|
|
113
106
|
peekLast(isItem: true): HeapItem<T> | null;
|
|
114
|
-
|
|
115
107
|
/**
|
|
116
|
-
* The `peekLast` function returns the last item in the heap
|
|
117
|
-
*
|
|
118
|
-
* @param {boolean} [isItem] - A boolean parameter that indicates whether the method should return the HeapItem object
|
|
119
|
-
* or just the value of the last item in the heap. If isItem is true, the method will return the HeapItem object. If
|
|
120
|
-
* isItem is false or not provided, the method will return the value of the last item
|
|
121
|
-
* @returns The method `peekLast` returns either a `HeapItem<T>` object, `null`, `T`, or `undefined`. The specific
|
|
122
|
-
* return type depends on the value of the `isItem` parameter. If `isItem` is `true`, then the method returns a
|
|
123
|
-
* `HeapItem<T>` object or `null` if there are no items in the heap. If `isItem`
|
|
108
|
+
* The `peekLast` function returns the last item in the heap.
|
|
109
|
+
* @returns The method `peekLast()` returns either a `HeapItem<T>` object or `null`.Returns an val with the lowest priority in the queue
|
|
124
110
|
*/
|
|
125
111
|
peekLast(isItem?: boolean): HeapItem<T> | null | T | undefined {
|
|
126
112
|
isItem = isItem ?? false;
|
|
@@ -147,15 +133,9 @@ export abstract class Heap<T = number> {
|
|
|
147
133
|
poll(isItem?: undefined): T | undefined;
|
|
148
134
|
poll(isItem: false): T | undefined;
|
|
149
135
|
poll(isItem: true): HeapItem<T> | null;
|
|
150
|
-
|
|
151
136
|
/**
|
|
152
|
-
* The `poll` function returns the top item from a priority queue
|
|
153
|
-
*
|
|
154
|
-
* @param {boolean} [isItem] - The `isItem` parameter is a boolean flag that indicates whether the returned value
|
|
155
|
-
* should be a `HeapItem<T>` object or just the value `T` itself. If `isItem` is `true`, the method will return the
|
|
156
|
-
* `HeapItem<T>` object, otherwise it will return just
|
|
157
|
-
* @returns The function `poll` returns either a `HeapItem<T>` object, `null`, or `T` (the value of the `val` property
|
|
158
|
-
* of the `HeapItem<T>` object).
|
|
137
|
+
* The `poll` function returns the top item from a priority queue or null if the queue is empty.Removes and returns an val with the highest priority in the queue
|
|
138
|
+
* @returns either a HeapItem<T> object or null.
|
|
159
139
|
*/
|
|
160
140
|
poll(isItem?: boolean): HeapItem<T> | null | T | undefined {
|
|
161
141
|
isItem = isItem ?? false;
|
|
@@ -167,8 +147,8 @@ export abstract class Heap<T = number> {
|
|
|
167
147
|
}
|
|
168
148
|
|
|
169
149
|
/**
|
|
170
|
-
* The
|
|
171
|
-
* @param {T | HeapItem<T>} node - The `node`
|
|
150
|
+
* The function checks if a given node or value exists in the priority queue.
|
|
151
|
+
* @param {T | HeapItem<T>} node - The parameter `node` can be of type `T` or `HeapItem<T>`.
|
|
172
152
|
* @returns a boolean value.
|
|
173
153
|
*/
|
|
174
154
|
has(node: T | HeapItem<T>): boolean {
|
|
@@ -184,15 +164,9 @@ export abstract class Heap<T = number> {
|
|
|
184
164
|
toArray(isItem?: undefined): (T | undefined)[];
|
|
185
165
|
toArray(isItem: false): (T | undefined)[];
|
|
186
166
|
toArray(isItem: true): (HeapItem<T> | null)[];
|
|
187
|
-
|
|
188
167
|
/**
|
|
189
|
-
* The `toArray` function returns an array of
|
|
190
|
-
*
|
|
191
|
-
* @param {boolean} [isItem] - isItem is an optional boolean parameter that determines whether the returned array
|
|
192
|
-
* should contain the HeapItem objects or just the values of the HeapItem objects. If isItem is true, the array will
|
|
193
|
-
* contain the HeapItem objects. If isItem is false or not provided, the array will contain only the values
|
|
194
|
-
* @returns The method `toArray` returns an array of `HeapItem<T>` objects, or an array of `T` values if the `isItem`
|
|
195
|
-
* parameter is set to `false`.
|
|
168
|
+
* The `toArray` function returns an array of `HeapItem<T>` objects.
|
|
169
|
+
* @returns An array of HeapItem<T> objects.Returns a sorted list of vals
|
|
196
170
|
*/
|
|
197
171
|
toArray(isItem?: boolean): (HeapItem<T> | null | T | undefined)[] {
|
|
198
172
|
isItem = isItem ?? false;
|
|
@@ -51,15 +51,9 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
|
|
|
51
51
|
|
|
52
52
|
get visitedNode(): N[]
|
|
53
53
|
|
|
54
|
-
get visitedCount(): number[]
|
|
55
|
-
|
|
56
54
|
get visitedLeftSum(): number[]
|
|
57
55
|
|
|
58
|
-
get
|
|
59
|
-
|
|
60
|
-
get maxId(): number
|
|
61
|
-
|
|
62
|
-
get isMergeDuplicatedVal(): boolean
|
|
56
|
+
get isMergeDuplicatedNodeById(): boolean
|
|
63
57
|
|
|
64
58
|
get root(): N | null
|
|
65
59
|
|
|
@@ -71,13 +65,13 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
|
|
|
71
65
|
|
|
72
66
|
isEmpty(): boolean
|
|
73
67
|
|
|
74
|
-
add(id: BinaryTreeNodeId, val?: N['val']
|
|
68
|
+
add(id: BinaryTreeNodeId | N, val?: N['val']): N | null | undefined
|
|
75
69
|
|
|
76
70
|
addTo(newNode: N | null, parent: N): N | null | undefined
|
|
77
71
|
|
|
78
|
-
addMany(
|
|
72
|
+
addMany(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N['val'][]): (N | null | undefined)[]
|
|
79
73
|
|
|
80
|
-
fill(
|
|
74
|
+
fill(idsOrNodes: (BinaryTreeNodeId | N | null)[], data?: N[] | Array<N['val']>): boolean
|
|
81
75
|
|
|
82
76
|
remove(id: BinaryTreeNodeId, ignoreCount?: boolean): BinaryTreeDeletedResult<N>[]
|
|
83
77
|
|
|
@@ -109,9 +103,9 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
|
|
|
109
103
|
|
|
110
104
|
getRightMost(node?: N | null): N | null
|
|
111
105
|
|
|
112
|
-
|
|
106
|
+
isSubtreeBST(node: N | null): boolean
|
|
113
107
|
|
|
114
|
-
isBST(
|
|
108
|
+
isBST(): boolean
|
|
115
109
|
|
|
116
110
|
getSubTreeSize(subTreeRoot: N | null | undefined): number
|
|
117
111
|
|
|
@@ -195,37 +189,6 @@ export interface IAbstractBinaryTree<N extends AbstractBinaryTreeNode<N['val'],
|
|
|
195
189
|
|
|
196
190
|
morris(pattern?: 'in' | 'pre' | 'post', nodeOrPropertyName?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
|
|
197
191
|
|
|
198
|
-
// _setLoopType(value: LoopType): void
|
|
199
|
-
//
|
|
200
|
-
// _setVisitedId(value: BinaryTreeNodeId[]): void
|
|
201
|
-
//
|
|
202
|
-
// _setVisitedVal(value: Array<N>): void
|
|
203
|
-
//
|
|
204
|
-
// _setVisitedNode(value: N[]): void
|
|
205
|
-
//
|
|
206
|
-
// setVisitedCount(value: number[]): void
|
|
207
|
-
//
|
|
208
|
-
// _setVisitedLeftSum(value: number[]): void
|
|
209
|
-
//
|
|
210
|
-
// _setAutoIncrementId(value: boolean): void
|
|
211
|
-
//
|
|
212
|
-
// _setMaxId(value: number): void
|
|
213
|
-
//
|
|
214
|
-
// _setIsDuplicatedVal(value: boolean): void
|
|
215
|
-
//
|
|
216
|
-
// _setRoot(v: N | null): void
|
|
217
|
-
//
|
|
218
|
-
// _setSize(v: number): void
|
|
219
|
-
//
|
|
220
|
-
// _setCount(v: number): void
|
|
221
|
-
//
|
|
222
|
-
// _resetResults(): void
|
|
223
|
-
|
|
224
|
-
// _pushByPropertyNameStopOrNot(cur: N, result: (N | null | undefined)[], nodeProperty: BinaryTreeNodeId | N, propertyName ?: BinaryTreeNodePropertyName, onlyOne ?: boolean): void
|
|
225
|
-
//
|
|
226
|
-
// _accumulatedByPropertyName(node: N, nodeOrPropertyName ?: NodeOrPropertyName): void
|
|
227
|
-
//
|
|
228
|
-
// _getResultByPropertyName(nodeOrPropertyName ?: NodeOrPropertyName): AbstractBinaryTreeNodeProperties<N>
|
|
229
192
|
|
|
230
193
|
// --- end additional methods ---
|
|
231
194
|
}
|
|
@@ -3,6 +3,6 @@ import {AVLTreeOptions} from './avl-tree';
|
|
|
3
3
|
|
|
4
4
|
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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
|
5
5
|
|
|
6
|
-
export type TreeMultisetOptions = Omit<AVLTreeOptions, '
|
|
7
|
-
|
|
6
|
+
export type TreeMultisetOptions = Omit<AVLTreeOptions, 'isMergeDuplicatedNodeById'> & {
|
|
7
|
+
isMergeDuplicatedNodeById: true,
|
|
8
8
|
}
|