undirected-graph-typed 2.0.5 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-structures/base/iterable-element-base.d.ts +186 -83
- package/dist/data-structures/base/iterable-element-base.js +149 -107
- package/dist/data-structures/base/iterable-entry-base.d.ts +95 -119
- package/dist/data-structures/base/iterable-entry-base.js +59 -116
- package/dist/data-structures/base/linear-base.d.ts +250 -192
- package/dist/data-structures/base/linear-base.js +137 -274
- package/dist/data-structures/binary-tree/avl-tree-counter.d.ts +126 -158
- package/dist/data-structures/binary-tree/avl-tree-counter.js +171 -205
- package/dist/data-structures/binary-tree/avl-tree-multi-map.d.ts +100 -69
- package/dist/data-structures/binary-tree/avl-tree-multi-map.js +135 -87
- package/dist/data-structures/binary-tree/avl-tree.d.ts +138 -149
- package/dist/data-structures/binary-tree/avl-tree.js +208 -195
- package/dist/data-structures/binary-tree/binary-tree.d.ts +476 -632
- package/dist/data-structures/binary-tree/binary-tree.js +602 -873
- package/dist/data-structures/binary-tree/bst.d.ts +258 -306
- package/dist/data-structures/binary-tree/bst.js +505 -481
- package/dist/data-structures/binary-tree/red-black-tree.d.ts +107 -179
- package/dist/data-structures/binary-tree/red-black-tree.js +114 -209
- package/dist/data-structures/binary-tree/tree-counter.d.ts +132 -154
- package/dist/data-structures/binary-tree/tree-counter.js +172 -203
- package/dist/data-structures/binary-tree/tree-multi-map.d.ts +72 -69
- package/dist/data-structures/binary-tree/tree-multi-map.js +105 -85
- package/dist/data-structures/graph/abstract-graph.d.ts +238 -233
- package/dist/data-structures/graph/abstract-graph.js +267 -237
- package/dist/data-structures/graph/directed-graph.d.ts +108 -224
- package/dist/data-structures/graph/directed-graph.js +146 -233
- package/dist/data-structures/graph/map-graph.d.ts +49 -55
- package/dist/data-structures/graph/map-graph.js +56 -59
- package/dist/data-structures/graph/undirected-graph.d.ts +103 -146
- package/dist/data-structures/graph/undirected-graph.js +129 -149
- package/dist/data-structures/hash/hash-map.d.ts +164 -338
- package/dist/data-structures/hash/hash-map.js +270 -457
- package/dist/data-structures/heap/heap.d.ts +214 -289
- package/dist/data-structures/heap/heap.js +340 -349
- package/dist/data-structures/heap/max-heap.d.ts +11 -47
- package/dist/data-structures/heap/max-heap.js +11 -66
- package/dist/data-structures/heap/min-heap.d.ts +12 -47
- package/dist/data-structures/heap/min-heap.js +11 -66
- package/dist/data-structures/linked-list/doubly-linked-list.d.ts +231 -347
- package/dist/data-structures/linked-list/doubly-linked-list.js +368 -494
- package/dist/data-structures/linked-list/singly-linked-list.d.ts +261 -310
- package/dist/data-structures/linked-list/singly-linked-list.js +447 -466
- package/dist/data-structures/linked-list/skip-linked-list.d.ts +0 -107
- package/dist/data-structures/linked-list/skip-linked-list.js +0 -100
- package/dist/data-structures/priority-queue/max-priority-queue.d.ts +12 -56
- package/dist/data-structures/priority-queue/max-priority-queue.js +11 -78
- package/dist/data-structures/priority-queue/min-priority-queue.d.ts +11 -57
- package/dist/data-structures/priority-queue/min-priority-queue.js +10 -79
- package/dist/data-structures/priority-queue/priority-queue.d.ts +2 -61
- package/dist/data-structures/priority-queue/priority-queue.js +8 -83
- package/dist/data-structures/queue/deque.d.ts +227 -254
- package/dist/data-structures/queue/deque.js +309 -348
- package/dist/data-structures/queue/queue.d.ts +180 -201
- package/dist/data-structures/queue/queue.js +265 -248
- package/dist/data-structures/stack/stack.d.ts +124 -102
- package/dist/data-structures/stack/stack.js +181 -125
- package/dist/data-structures/trie/trie.d.ts +164 -165
- package/dist/data-structures/trie/trie.js +189 -172
- package/dist/interfaces/binary-tree.d.ts +56 -6
- package/dist/interfaces/graph.d.ts +16 -0
- package/dist/types/data-structures/base/base.d.ts +1 -1
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -0
- package/dist/types/utils/utils.d.ts +1 -0
- package/dist/utils/utils.d.ts +1 -1
- package/dist/utils/utils.js +2 -1
- package/package.json +2 -2
- package/src/data-structures/base/iterable-element-base.ts +238 -115
- package/src/data-structures/base/iterable-entry-base.ts +96 -120
- package/src/data-structures/base/linear-base.ts +271 -277
- package/src/data-structures/binary-tree/avl-tree-counter.ts +196 -217
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +188 -102
- package/src/data-structures/binary-tree/avl-tree.ts +237 -206
- package/src/data-structures/binary-tree/binary-tree.ts +665 -896
- package/src/data-structures/binary-tree/bst.ts +565 -572
- package/src/data-structures/binary-tree/red-black-tree.ts +157 -223
- package/src/data-structures/binary-tree/tree-counter.ts +195 -219
- package/src/data-structures/binary-tree/tree-multi-map.ts +127 -98
- package/src/data-structures/graph/abstract-graph.ts +339 -264
- package/src/data-structures/graph/directed-graph.ts +146 -236
- package/src/data-structures/graph/map-graph.ts +63 -60
- package/src/data-structures/graph/undirected-graph.ts +129 -152
- package/src/data-structures/hash/hash-map.ts +274 -496
- package/src/data-structures/heap/heap.ts +389 -402
- package/src/data-structures/heap/max-heap.ts +12 -76
- package/src/data-structures/heap/min-heap.ts +13 -76
- package/src/data-structures/linked-list/doubly-linked-list.ts +426 -530
- package/src/data-structures/linked-list/singly-linked-list.ts +495 -517
- package/src/data-structures/linked-list/skip-linked-list.ts +1 -108
- package/src/data-structures/priority-queue/max-priority-queue.ts +12 -87
- package/src/data-structures/priority-queue/min-priority-queue.ts +11 -88
- package/src/data-structures/priority-queue/priority-queue.ts +3 -92
- package/src/data-structures/queue/deque.ts +381 -357
- package/src/data-structures/queue/queue.ts +310 -264
- package/src/data-structures/stack/stack.ts +217 -131
- package/src/data-structures/trie/trie.ts +240 -175
- package/src/interfaces/binary-tree.ts +240 -6
- package/src/interfaces/graph.ts +37 -0
- package/src/types/data-structures/base/base.ts +5 -5
- package/src/types/data-structures/graph/abstract-graph.ts +5 -0
- package/src/types/utils/utils.ts +2 -0
- package/src/utils/utils.ts +9 -14
|
@@ -5,9 +5,11 @@
|
|
|
5
5
|
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
|
6
6
|
* @license MIT License
|
|
7
7
|
*/
|
|
8
|
+
|
|
8
9
|
import type {
|
|
9
10
|
AVLTreeCounterOptions,
|
|
10
11
|
BinaryTreeDeleteResult,
|
|
12
|
+
BinaryTreeOptions,
|
|
11
13
|
BSTNOptKeyOrNode,
|
|
12
14
|
EntryCallback,
|
|
13
15
|
IterationType
|
|
@@ -15,18 +17,22 @@ import type {
|
|
|
15
17
|
import { IBinaryTree } from '../../interfaces';
|
|
16
18
|
import { AVLTree, AVLTreeNode } from './avl-tree';
|
|
17
19
|
|
|
20
|
+
/**
|
|
21
|
+
* AVL node with an extra 'count' field; keeps parent/child links.
|
|
22
|
+
* @remarks Time O(1), Space O(1)
|
|
23
|
+
* @template K
|
|
24
|
+
* @template V
|
|
25
|
+
*/
|
|
18
26
|
export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
|
|
19
27
|
override parent?: AVLTreeCounterNode<K, V> = undefined;
|
|
20
28
|
|
|
21
29
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @
|
|
24
|
-
* of the
|
|
25
|
-
* @param
|
|
26
|
-
*
|
|
27
|
-
* @
|
|
28
|
-
* occurs in a binary tree node. It has a default value of 1, which means that if no value is provided for the `count`
|
|
29
|
-
* parameter when creating a new instance of the `BinaryTreeNode` class.
|
|
30
|
+
* Create an AVL counter node.
|
|
31
|
+
* @remarks Time O(1), Space O(1)
|
|
32
|
+
* @param key - Key of the node.
|
|
33
|
+
* @param [value] - Associated value (ignored in map mode).
|
|
34
|
+
* @param [count] - Initial count for this node (default 1).
|
|
35
|
+
* @returns New AVLTreeCounterNode instance.
|
|
30
36
|
*/
|
|
31
37
|
constructor(key: K, value?: V, count = 1) {
|
|
32
38
|
super(key, value);
|
|
@@ -35,10 +41,21 @@ export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
|
|
|
35
41
|
|
|
36
42
|
override _left?: AVLTreeCounterNode<K, V> | null | undefined = undefined;
|
|
37
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Get the left child pointer.
|
|
46
|
+
* @remarks Time O(1), Space O(1)
|
|
47
|
+
* @returns Left child node, or null/undefined.
|
|
48
|
+
*/
|
|
38
49
|
override get left(): AVLTreeCounterNode<K, V> | null | undefined {
|
|
39
50
|
return this._left;
|
|
40
51
|
}
|
|
41
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Set the left child and update its parent pointer.
|
|
55
|
+
* @remarks Time O(1), Space O(1)
|
|
56
|
+
* @param v - New left child node, or null/undefined.
|
|
57
|
+
* @returns void
|
|
58
|
+
*/
|
|
42
59
|
override set left(v: AVLTreeCounterNode<K, V> | null | undefined) {
|
|
43
60
|
if (v) {
|
|
44
61
|
v.parent = this;
|
|
@@ -48,10 +65,21 @@ export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
|
|
|
48
65
|
|
|
49
66
|
override _right?: AVLTreeCounterNode<K, V> | null | undefined = undefined;
|
|
50
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Get the right child pointer.
|
|
70
|
+
* @remarks Time O(1), Space O(1)
|
|
71
|
+
* @returns Right child node, or null/undefined.
|
|
72
|
+
*/
|
|
51
73
|
override get right(): AVLTreeCounterNode<K, V> | null | undefined {
|
|
52
74
|
return this._right;
|
|
53
75
|
}
|
|
54
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Set the right child and update its parent pointer.
|
|
79
|
+
* @remarks Time O(1), Space O(1)
|
|
80
|
+
* @param v - New right child node, or null/undefined.
|
|
81
|
+
* @returns void
|
|
82
|
+
*/
|
|
55
83
|
override set right(v: AVLTreeCounterNode<K, V> | null | undefined) {
|
|
56
84
|
if (v) {
|
|
57
85
|
v.parent = this;
|
|
@@ -61,19 +89,19 @@ export class AVLTreeCounterNode<K = any, V = any> extends AVLTreeNode<K, V> {
|
|
|
61
89
|
}
|
|
62
90
|
|
|
63
91
|
/**
|
|
64
|
-
*
|
|
92
|
+
* AVL tree that tracks an aggregate 'count' across nodes; supports balanced insert/delete and map-like mode.
|
|
93
|
+
* @remarks Time O(1), Space O(1)
|
|
94
|
+
* @template K
|
|
95
|
+
* @template V
|
|
96
|
+
* @template R
|
|
65
97
|
*/
|
|
66
|
-
export class AVLTreeCounter<K = any, V = any, R =
|
|
67
|
-
extends AVLTree<K, V, R, MK, MV, MR>
|
|
68
|
-
implements IBinaryTree<K, V, R, MK, MV, MR>
|
|
69
|
-
{
|
|
98
|
+
export class AVLTreeCounter<K = any, V = any, R = any> extends AVLTree<K, V, R> implements IBinaryTree<K, V, R> {
|
|
70
99
|
/**
|
|
71
|
-
*
|
|
72
|
-
* @
|
|
73
|
-
*
|
|
74
|
-
* @param
|
|
75
|
-
*
|
|
76
|
-
* `compareValues` functions to define custom comparison logic for keys and values, respectively.
|
|
100
|
+
* Create a AVLTreeCounter instance
|
|
101
|
+
* @remarks Time O(n), Space O(n)
|
|
102
|
+
* @param keysNodesEntriesOrRaws
|
|
103
|
+
* @param options
|
|
104
|
+
* @returns New AVLTreeCounterNode instance.
|
|
77
105
|
*/
|
|
78
106
|
constructor(
|
|
79
107
|
keysNodesEntriesOrRaws: Iterable<
|
|
@@ -87,22 +115,14 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
87
115
|
|
|
88
116
|
protected _count = 0;
|
|
89
117
|
|
|
90
|
-
/**
|
|
91
|
-
* The function calculates the sum of the count property of all nodes in a tree using depth-first
|
|
92
|
-
* search.
|
|
93
|
-
* @returns the sum of the count property of all nodes in the tree.
|
|
94
|
-
*/
|
|
95
118
|
get count(): number {
|
|
96
119
|
return this._count;
|
|
97
120
|
}
|
|
98
121
|
|
|
99
122
|
/**
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* The function calculates the sum of the count property of all nodes in a tree using depth-first
|
|
104
|
-
* search.
|
|
105
|
-
* @returns the sum of the count property of all nodes in the tree.
|
|
123
|
+
* Compute the total count by traversing the tree (sums node.count).
|
|
124
|
+
* @remarks Time O(N), Space O(H)
|
|
125
|
+
* @returns Total count recomputed from nodes.
|
|
106
126
|
*/
|
|
107
127
|
getComputedCount(): number {
|
|
108
128
|
let sum = 0;
|
|
@@ -110,45 +130,14 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
110
130
|
return sum;
|
|
111
131
|
}
|
|
112
132
|
|
|
113
|
-
|
|
114
|
-
* The function creates a new AVLTreeCounterNode with the specified key, value, and count.
|
|
115
|
-
* @param {K} key - The key parameter represents the key of the node being created. It is of type K,
|
|
116
|
-
* which is a generic type that can be replaced with any specific type when using the function.
|
|
117
|
-
* @param {V} [value] - The `value` parameter is an optional parameter that represents the value
|
|
118
|
-
* associated with the key in the node. It is of type `V`, which can be any data type.
|
|
119
|
-
* @param {number} [count] - The `count` parameter represents the number of occurrences of a
|
|
120
|
-
* key-value pair in the AVLTreeCounterNode. It is an optional parameter, so it can be omitted when
|
|
121
|
-
* calling the `createNode` method. If provided, it specifies the initial count for the node.
|
|
122
|
-
* @returns a new instance of the AVLTreeCounterNode class, casted as AVLTreeCounterNode<K, V>.
|
|
123
|
-
*/
|
|
124
|
-
override createNode(key: K, value?: V, count?: number): AVLTreeCounterNode<K, V> {
|
|
133
|
+
override _createNode(key: K, value?: V, count?: number): AVLTreeCounterNode<K, V> {
|
|
125
134
|
return new AVLTreeCounterNode(key, this._isMapMode ? undefined : value, count) as AVLTreeCounterNode<K, V>;
|
|
126
135
|
}
|
|
127
136
|
|
|
128
137
|
/**
|
|
129
|
-
*
|
|
130
|
-
* @
|
|
131
|
-
*
|
|
132
|
-
* @returns a new instance of the AVLTreeCounter class, with the specified options, as a TREE
|
|
133
|
-
* object.
|
|
134
|
-
*/
|
|
135
|
-
override createTree(options?: AVLTreeCounterOptions<K, V, R>) {
|
|
136
|
-
return new AVLTreeCounter<K, V, R, MK, MV, MR>([], {
|
|
137
|
-
iterationType: this.iterationType,
|
|
138
|
-
isMapMode: this._isMapMode,
|
|
139
|
-
specifyComparable: this._specifyComparable,
|
|
140
|
-
toEntryFn: this._toEntryFn,
|
|
141
|
-
isReverse: this._isReverse,
|
|
142
|
-
...options
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* The function checks if the input is an instance of AVLTreeCounterNode.
|
|
148
|
-
* @param {K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The parameter
|
|
149
|
-
* `keyNodeOrEntry` can be of type `R` or `K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined`.
|
|
150
|
-
* @returns a boolean value indicating whether the input parameter `keyNodeOrEntry` is
|
|
151
|
-
* an instance of the `AVLTreeCounterNode` class.
|
|
138
|
+
* Type guard: check whether the input is an AVLTreeCounterNode.
|
|
139
|
+
* @remarks Time O(1), Space O(1)
|
|
140
|
+
* @returns True if the value is an AVLTreeCounterNode.
|
|
152
141
|
*/
|
|
153
142
|
override isNode(
|
|
154
143
|
keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined
|
|
@@ -157,21 +146,12 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
157
146
|
}
|
|
158
147
|
|
|
159
148
|
/**
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* @
|
|
166
|
-
* `keyNodeOrEntry` parameter can accept a value of type `R`, which can be any type. It
|
|
167
|
-
* can also accept a value of type `K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined`, which represents a key, node,
|
|
168
|
-
* entry, or raw element
|
|
169
|
-
* @param {V} [value] - The `value` parameter represents the value associated with the key in the
|
|
170
|
-
* data structure. It is an optional parameter, so it can be omitted if not needed.
|
|
171
|
-
* @param [count=1] - The `count` parameter represents the number of times the key-value pair should
|
|
172
|
-
* be added to the data structure. By default, it is set to 1, meaning that the key-value pair will
|
|
173
|
-
* be added once. However, you can specify a different value for `count` if you want to add
|
|
174
|
-
* @returns a boolean value.
|
|
149
|
+
* Insert or increment a node and update aggregate count.
|
|
150
|
+
* @remarks Time O(log N), Space O(1)
|
|
151
|
+
* @param keyNodeOrEntry - Key, node, or [key, value] entry to insert.
|
|
152
|
+
* @param [value] - Value when a bare key is provided (ignored in map mode).
|
|
153
|
+
* @param [count] - How much to increase the node's count (default 1).
|
|
154
|
+
* @returns True if inserted/updated; false if ignored.
|
|
175
155
|
*/
|
|
176
156
|
override add(
|
|
177
157
|
keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
@@ -190,23 +170,11 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
190
170
|
}
|
|
191
171
|
|
|
192
172
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
* @param {K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined} keyNodeOrEntry - The `predicate`
|
|
199
|
-
* parameter in the `delete` method is used to specify the condition for deleting a node from the
|
|
200
|
-
* binary tree. It can be a key, node, or entry that determines which
|
|
201
|
-
* node(s) should be deleted.
|
|
202
|
-
* @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a
|
|
203
|
-
* boolean flag that determines whether to ignore the count of the node being deleted. If
|
|
204
|
-
* `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If
|
|
205
|
-
* `ignoreCount` is set to
|
|
206
|
-
* @returns The `delete` method overrides the default delete behavior in a binary tree data
|
|
207
|
-
* structure. It takes a predicate or node to be deleted and an optional flag to ignore count. The
|
|
208
|
-
* method returns an array of `BinaryTreeDeleteResult` objects, each containing information about the
|
|
209
|
-
* deleted node and whether balancing is needed in the tree.
|
|
173
|
+
* Delete a node (or decrement its count) and rebalance if needed.
|
|
174
|
+
* @remarks Time O(log N), Space O(1)
|
|
175
|
+
* @param keyNodeOrEntry - Key, node, or [key, value] entry identifying the node.
|
|
176
|
+
* @param [ignoreCount] - If true, remove the node regardless of its count.
|
|
177
|
+
* @returns Array of deletion results including deleted node and a rebalance hint when present.
|
|
210
178
|
*/
|
|
211
179
|
override delete(
|
|
212
180
|
keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
@@ -254,7 +222,7 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
254
222
|
}
|
|
255
223
|
}
|
|
256
224
|
this._size = this._size - 1;
|
|
257
|
-
|
|
225
|
+
|
|
258
226
|
if (orgCurrent) this._count -= orgCurrent.count;
|
|
259
227
|
}
|
|
260
228
|
|
|
@@ -268,11 +236,9 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
268
236
|
}
|
|
269
237
|
|
|
270
238
|
/**
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
* The "clear" function overrides the parent class's "clear" function and also resets the count to
|
|
275
|
-
* zero.
|
|
239
|
+
* Remove all nodes and reset aggregate counters.
|
|
240
|
+
* @remarks Time O(N), Space O(1)
|
|
241
|
+
* @returns void
|
|
276
242
|
*/
|
|
277
243
|
override clear() {
|
|
278
244
|
super.clear();
|
|
@@ -280,115 +246,138 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
280
246
|
}
|
|
281
247
|
|
|
282
248
|
/**
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
* tree using either a recursive or iterative approach.
|
|
288
|
-
* @param {IterationType} iterationType - The `iterationType` parameter is an optional parameter that
|
|
289
|
-
* specifies the type of iteration to use when building the balanced binary search tree. It has a
|
|
290
|
-
* default value of `this.iterationType`, which means it will use the iteration type currently set in
|
|
291
|
-
* the object.
|
|
292
|
-
* @returns The function `perfectlyBalance` returns a boolean value. It returns `true` if the
|
|
293
|
-
* balancing operation is successful, and `false` if there are no nodes to balance.
|
|
249
|
+
* Rebuild the tree into a perfectly balanced form using in-order nodes.
|
|
250
|
+
* @remarks Time O(N), Space O(N)
|
|
251
|
+
* @param [iterationType] - Traversal style to use when constructing the balanced tree.
|
|
252
|
+
* @returns True if rebalancing succeeded (tree not empty).
|
|
294
253
|
*/
|
|
295
254
|
override perfectlyBalance(iterationType: IterationType = this.iterationType): boolean {
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
if (
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
const midNode = sorted[m];
|
|
324
|
-
if (this._isMapMode) this.add(midNode.key, undefined, midNode.count);
|
|
325
|
-
else this.add(midNode.key, midNode.value, midNode.count);
|
|
326
|
-
stack.push([m + 1, r]);
|
|
327
|
-
stack.push([l, m - 1]);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return true;
|
|
332
|
-
}
|
|
255
|
+
const nodes = this.dfs(node => node, 'IN', false, this._root, iterationType);
|
|
256
|
+
const n = nodes.length;
|
|
257
|
+
if (n === 0) return false;
|
|
258
|
+
|
|
259
|
+
let total = 0;
|
|
260
|
+
for (const nd of nodes) total += nd ? nd.count : 0;
|
|
261
|
+
|
|
262
|
+
this._clearNodes();
|
|
263
|
+
|
|
264
|
+
const build = (l: number, r: number, parent?: any): any => {
|
|
265
|
+
if (l > r) return undefined;
|
|
266
|
+
const m = l + ((r - l) >> 1);
|
|
267
|
+
const root = nodes[m];
|
|
268
|
+
root.left = build(l, m - 1, root);
|
|
269
|
+
root.right = build(m + 1, r, root);
|
|
270
|
+
root.parent = parent;
|
|
271
|
+
const lh = root.left ? root.left.height : -1;
|
|
272
|
+
const rh = root.right ? root.right.height : -1;
|
|
273
|
+
root.height = Math.max(lh, rh) + 1;
|
|
274
|
+
return root;
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
const newRoot = build(0, n - 1, undefined);
|
|
278
|
+
this._setRoot(newRoot);
|
|
279
|
+
this._size = n;
|
|
280
|
+
this._count = total;
|
|
281
|
+
return true;
|
|
333
282
|
}
|
|
334
283
|
|
|
335
284
|
/**
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
* The function overrides the clone method to create a deep copy of a tree object.
|
|
340
|
-
* @returns The `clone()` method is returning a cloned instance of the `TREE` object.
|
|
285
|
+
* Deep copy this tree, preserving map mode and aggregate counts.
|
|
286
|
+
* @remarks Time O(N), Space O(N)
|
|
287
|
+
* @returns A deep copy of this tree.
|
|
341
288
|
*/
|
|
342
|
-
override clone() {
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
289
|
+
override clone(): this {
|
|
290
|
+
const out = this._createInstance();
|
|
291
|
+
|
|
292
|
+
if (this._isMapMode) {
|
|
293
|
+
this.bfs(node => out.add(node.key, undefined, node.count));
|
|
294
|
+
} else {
|
|
295
|
+
this.bfs(node => out.add(node.key, node.value, node.count));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (this._isMapMode) out._store = this._store;
|
|
299
|
+
|
|
300
|
+
return out as this;
|
|
348
301
|
}
|
|
349
302
|
|
|
350
303
|
/**
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
* @
|
|
354
|
-
*
|
|
355
|
-
* @
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
* @
|
|
360
|
-
* the value of `this` when executing the `callback` function. It allows you to set the context
|
|
361
|
-
* (value of `this`) for the callback function. This can be useful when you want to access properties
|
|
362
|
-
* or
|
|
363
|
-
* @returns The `map` method is returning a new `AVLTreeCounter` instance with the entries
|
|
364
|
-
* transformed by the provided `callback` function. Each entry in the original tree is passed to the
|
|
365
|
-
* `callback` function along with the index and the original tree itself. The transformed entries are
|
|
366
|
-
* then added to the new `AVLTreeCounter` instance, which is returned at the end.
|
|
304
|
+
* Create a new AVLTreeCounter by mapping each [key, value] entry.
|
|
305
|
+
* @remarks Time O(N log N), Space O(N)
|
|
306
|
+
* @template MK
|
|
307
|
+
* @template MV
|
|
308
|
+
* @template MR
|
|
309
|
+
* @param callback - Function mapping (key, value, index, tree) → [newKey, newValue].
|
|
310
|
+
* @param [options] - Options for the output tree.
|
|
311
|
+
* @param [thisArg] - Value for `this` inside the callback.
|
|
312
|
+
* @returns A new AVLTreeCounter with mapped entries.
|
|
367
313
|
*/
|
|
368
|
-
override map<MK, MV, MR>(
|
|
314
|
+
override map<MK = K, MV = V, MR = any>(
|
|
369
315
|
callback: EntryCallback<K, V | undefined, [MK, MV]>,
|
|
370
|
-
options?:
|
|
371
|
-
thisArg?:
|
|
316
|
+
options?: Partial<BinaryTreeOptions<MK, MV, MR>>,
|
|
317
|
+
thisArg?: unknown
|
|
372
318
|
): AVLTreeCounter<MK, MV, MR> {
|
|
373
|
-
const
|
|
319
|
+
const out = this._createLike<MK, MV, MR>([], options);
|
|
320
|
+
|
|
374
321
|
let index = 0;
|
|
375
322
|
for (const [key, value] of this) {
|
|
376
|
-
|
|
323
|
+
out.add(callback.call(thisArg, key, value, index++, this));
|
|
377
324
|
}
|
|
378
|
-
return
|
|
325
|
+
return out;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* (Protected) Create an empty instance of the same concrete class.
|
|
330
|
+
* @remarks Time O(1), Space O(1)
|
|
331
|
+
* @template TK
|
|
332
|
+
* @template TV
|
|
333
|
+
* @template TR
|
|
334
|
+
* @param [options] - Optional constructor options for the like-kind instance.
|
|
335
|
+
* @returns An empty like-kind instance.
|
|
336
|
+
*/
|
|
337
|
+
protected override _createInstance<TK = K, TV = V, TR = R>(
|
|
338
|
+
options?: Partial<AVLTreeCounterOptions<TK, TV, TR>>
|
|
339
|
+
): this {
|
|
340
|
+
const Ctor = this.constructor as unknown as new (
|
|
341
|
+
iter?: Iterable<
|
|
342
|
+
TK | AVLTreeCounterNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
|
|
343
|
+
>,
|
|
344
|
+
opts?: AVLTreeCounterOptions<TK, TV, TR>
|
|
345
|
+
) => AVLTreeCounter<TK, TV, TR>;
|
|
346
|
+
return new Ctor([], { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) }) as unknown as this;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* (Protected) Create a like-kind instance and seed it from an iterable.
|
|
351
|
+
* @remarks Time O(N log N), Space O(N)
|
|
352
|
+
* @template TK
|
|
353
|
+
* @template TV
|
|
354
|
+
* @template TR
|
|
355
|
+
* @param iter - Iterable used to seed the new tree.
|
|
356
|
+
* @param [options] - Options merged with the current snapshot.
|
|
357
|
+
* @returns A like-kind AVLTreeCounter built from the iterable.
|
|
358
|
+
*/
|
|
359
|
+
protected override _createLike<TK = K, TV = V, TR = R>(
|
|
360
|
+
iter: Iterable<
|
|
361
|
+
TK | AVLTreeCounterNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
|
|
362
|
+
> = [],
|
|
363
|
+
options?: Partial<AVLTreeCounterOptions<TK, TV, TR>>
|
|
364
|
+
): AVLTreeCounter<TK, TV, TR> {
|
|
365
|
+
const Ctor = this.constructor as unknown as new (
|
|
366
|
+
iter?: Iterable<
|
|
367
|
+
TK | AVLTreeCounterNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
|
|
368
|
+
>,
|
|
369
|
+
opts?: AVLTreeCounterOptions<TK, TV, TR>
|
|
370
|
+
) => AVLTreeCounter<TK, TV, TR>;
|
|
371
|
+
return new Ctor(iter, { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) });
|
|
379
372
|
}
|
|
380
373
|
|
|
381
374
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* @param
|
|
385
|
-
*
|
|
386
|
-
* @param
|
|
387
|
-
*
|
|
388
|
-
* value is provided, it will default to `undefined`.
|
|
389
|
-
* @param [count=1] - The `count` parameter is an optional parameter that specifies the number of
|
|
390
|
-
* times the key-value pair should be added to the data structure. If not provided, it defaults to 1.
|
|
391
|
-
* @returns either a AVLTreeCounterNode<K, V> object or undefined.
|
|
375
|
+
* (Protected) Normalize input into a node plus its effective value and count.
|
|
376
|
+
* @remarks Time O(1), Space O(1)
|
|
377
|
+
* @param keyNodeOrEntry - Key, node, or [key, value] entry.
|
|
378
|
+
* @param [value] - Value used when a bare key is provided.
|
|
379
|
+
* @param [count] - Count increment to apply (default 1).
|
|
380
|
+
* @returns Tuple [node, value] where node may be undefined.
|
|
392
381
|
*/
|
|
393
382
|
protected override _keyValueNodeOrEntryToNodeAndValue(
|
|
394
383
|
keyNodeOrEntry: K | AVLTreeCounterNode<K, V> | [K | null | undefined, V | undefined] | null | undefined,
|
|
@@ -402,24 +391,18 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
402
391
|
const [key, entryValue] = keyNodeOrEntry;
|
|
403
392
|
if (key === undefined || key === null) return [undefined, undefined];
|
|
404
393
|
const finalValue = value ?? entryValue;
|
|
405
|
-
return [this.
|
|
394
|
+
return [this._createNode(key, finalValue, count), finalValue];
|
|
406
395
|
}
|
|
407
396
|
|
|
408
|
-
return [this.
|
|
397
|
+
return [this._createNode(keyNodeOrEntry, value, count), value];
|
|
409
398
|
}
|
|
410
399
|
|
|
411
400
|
/**
|
|
412
|
-
*
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
* @param {BSTNOptKeyOrNode<K, AVLTreeCounterNode<K, V>>} srcNode - The `srcNode` parameter represents the source node
|
|
418
|
-
* that will be swapped with the `destNode`.
|
|
419
|
-
* @param {BSTNOptKeyOrNode<K, AVLTreeCounterNode<K, V>>} destNode - The `destNode` parameter represents the destination
|
|
420
|
-
* node where the properties will be swapped with the source node.
|
|
421
|
-
* @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.
|
|
422
|
-
* If either `srcNode` or `destNode` is undefined, it returns `undefined`.
|
|
401
|
+
* (Protected) Swap keys/values/counters between the source and destination nodes.
|
|
402
|
+
* @remarks Time O(1), Space O(1)
|
|
403
|
+
* @param srcNode - Source node (or key) whose properties will be moved.
|
|
404
|
+
* @param destNode - Destination node (or key) to receive properties.
|
|
405
|
+
* @returns Destination node after swap, or undefined.
|
|
423
406
|
*/
|
|
424
407
|
protected override _swapProperties(
|
|
425
408
|
srcNode: BSTNOptKeyOrNode<K, AVLTreeCounterNode<K, V>>,
|
|
@@ -429,7 +412,7 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
429
412
|
destNode = this.ensureNode(destNode);
|
|
430
413
|
if (srcNode && destNode) {
|
|
431
414
|
const { key, value, count, height } = destNode;
|
|
432
|
-
const tempNode = this.
|
|
415
|
+
const tempNode = this._createNode(key, value, count);
|
|
433
416
|
if (tempNode) {
|
|
434
417
|
tempNode.height = height;
|
|
435
418
|
|
|
@@ -450,15 +433,11 @@ export class AVLTreeCounter<K = any, V = any, R = object, MK = any, MV = any, MR
|
|
|
450
433
|
}
|
|
451
434
|
|
|
452
435
|
/**
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
* @
|
|
458
|
-
* data structure. It is of type AVLTreeCounterNode<K, V>.
|
|
459
|
-
* @param {AVLTreeCounterNode<K, V>} newNode - The `newNode` parameter is an instance of the `AVLTreeCounterNode<K, V>` class.
|
|
460
|
-
* @returns The method is returning the result of calling the `_replaceNode` method from the
|
|
461
|
-
* superclass, which is of type `AVLTreeCounterNode<K, V>`.
|
|
436
|
+
* (Protected) Replace one node by another and adjust counters accordingly.
|
|
437
|
+
* @remarks Time O(1), Space O(1)
|
|
438
|
+
* @param oldNode - Node being replaced.
|
|
439
|
+
* @param newNode - Replacement node.
|
|
440
|
+
* @returns The new node after replacement.
|
|
462
441
|
*/
|
|
463
442
|
protected override _replaceNode(
|
|
464
443
|
oldNode: AVLTreeCounterNode<K, V>,
|