data-structure-typed 1.48.3 → 1.48.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +6 -6
- package/dist/cjs/data-structures/base/iterable-base.d.ts +6 -6
- package/dist/cjs/data-structures/base/iterable-base.js +3 -3
- package/dist/cjs/data-structures/base/iterable-base.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/avl-tree.d.ts +5 -3
- package/dist/cjs/data-structures/binary-tree/avl-tree.js +6 -4
- package/dist/cjs/data-structures/binary-tree/avl-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/binary-tree.d.ts +18 -15
- package/dist/cjs/data-structures/binary-tree/binary-tree.js +16 -13
- package/dist/cjs/data-structures/binary-tree/binary-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/bst.d.ts +15 -11
- package/dist/cjs/data-structures/binary-tree/bst.js +17 -13
- package/dist/cjs/data-structures/binary-tree/bst.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/rb-tree.d.ts +19 -13
- package/dist/cjs/data-structures/binary-tree/rb-tree.js +20 -14
- package/dist/cjs/data-structures/binary-tree/rb-tree.js.map +1 -1
- package/dist/cjs/data-structures/binary-tree/tree-multimap.d.ts +21 -14
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js +25 -18
- package/dist/cjs/data-structures/binary-tree/tree-multimap.js.map +1 -1
- package/dist/cjs/data-structures/graph/abstract-graph.d.ts +53 -52
- package/dist/cjs/data-structures/graph/abstract-graph.js +82 -78
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/directed-graph.d.ts +70 -52
- package/dist/cjs/data-structures/graph/directed-graph.js +111 -65
- package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/map-graph.d.ts +5 -5
- package/dist/cjs/data-structures/graph/map-graph.js +8 -8
- package/dist/cjs/data-structures/graph/map-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/undirected-graph.d.ts +51 -32
- package/dist/cjs/data-structures/graph/undirected-graph.js +117 -54
- package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
- package/dist/cjs/data-structures/hash/hash-map.d.ts +8 -8
- package/dist/cjs/data-structures/hash/hash-map.js +2 -2
- package/dist/cjs/data-structures/hash/hash-map.js.map +1 -1
- package/dist/cjs/interfaces/binary-tree.d.ts +1 -1
- package/dist/cjs/types/data-structures/base/base.d.ts +3 -3
- package/dist/mjs/data-structures/base/iterable-base.d.ts +6 -6
- package/dist/mjs/data-structures/base/iterable-base.js +1 -1
- package/dist/mjs/data-structures/binary-tree/avl-tree.d.ts +5 -3
- package/dist/mjs/data-structures/binary-tree/avl-tree.js +6 -4
- package/dist/mjs/data-structures/binary-tree/binary-tree.d.ts +18 -15
- package/dist/mjs/data-structures/binary-tree/binary-tree.js +17 -14
- package/dist/mjs/data-structures/binary-tree/bst.d.ts +15 -11
- package/dist/mjs/data-structures/binary-tree/bst.js +17 -13
- package/dist/mjs/data-structures/binary-tree/rb-tree.d.ts +19 -13
- package/dist/mjs/data-structures/binary-tree/rb-tree.js +20 -14
- package/dist/mjs/data-structures/binary-tree/tree-multimap.d.ts +21 -14
- package/dist/mjs/data-structures/binary-tree/tree-multimap.js +25 -18
- package/dist/mjs/data-structures/graph/abstract-graph.d.ts +53 -52
- package/dist/mjs/data-structures/graph/abstract-graph.js +83 -79
- package/dist/mjs/data-structures/graph/directed-graph.d.ts +70 -52
- package/dist/mjs/data-structures/graph/directed-graph.js +111 -65
- package/dist/mjs/data-structures/graph/map-graph.d.ts +5 -5
- package/dist/mjs/data-structures/graph/map-graph.js +8 -8
- package/dist/mjs/data-structures/graph/undirected-graph.d.ts +51 -32
- package/dist/mjs/data-structures/graph/undirected-graph.js +119 -56
- package/dist/mjs/data-structures/hash/hash-map.d.ts +8 -8
- package/dist/mjs/data-structures/hash/hash-map.js +3 -3
- package/dist/mjs/interfaces/binary-tree.d.ts +1 -1
- package/dist/mjs/types/data-structures/base/base.d.ts +3 -3
- package/dist/umd/data-structure-typed.js +413 -285
- package/dist/umd/data-structure-typed.min.js +2 -2
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/base/iterable-base.ts +6 -6
- package/src/data-structures/binary-tree/avl-tree.ts +8 -5
- package/src/data-structures/binary-tree/binary-tree.ts +23 -19
- package/src/data-structures/binary-tree/bst.ts +19 -14
- package/src/data-structures/binary-tree/rb-tree.ts +20 -14
- package/src/data-structures/binary-tree/tree-multimap.ts +27 -19
- package/src/data-structures/graph/abstract-graph.ts +87 -82
- package/src/data-structures/graph/directed-graph.ts +114 -65
- package/src/data-structures/graph/map-graph.ts +8 -8
- package/src/data-structures/graph/undirected-graph.ts +124 -56
- package/src/data-structures/hash/hash-map.ts +8 -8
- package/src/interfaces/binary-tree.ts +1 -1
- package/src/types/data-structures/base/base.ts +3 -3
- package/test/integration/bst.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +1 -1
- package/test/unit/data-structures/binary-tree/tree-multimap.test.ts +3 -3
- package/test/unit/data-structures/graph/directed-graph.test.ts +52 -15
- package/test/unit/data-structures/graph/map-graph.test.ts +3 -3
- package/test/unit/data-structures/graph/undirected-graph.test.ts +42 -5
|
@@ -24,7 +24,7 @@ export class UndirectedVertex<V = any> extends AbstractVertex<V> {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|
27
|
-
|
|
27
|
+
vertexMap: [VertexKey, VertexKey];
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* The constructor function creates an instance of a class with two vertex IDs, an optional weight, and an optional
|
|
@@ -38,7 +38,7 @@ export class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|
|
38
38
|
*/
|
|
39
39
|
constructor(v1: VertexKey, v2: VertexKey, weight?: number, value?: E) {
|
|
40
40
|
super(weight, value);
|
|
41
|
-
this.
|
|
41
|
+
this.vertexMap = [v1, v2];
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -51,17 +51,17 @@ export class UndirectedGraph<
|
|
|
51
51
|
extends AbstractGraph<V, E, VO, EO>
|
|
52
52
|
implements IGraph<V, E, VO, EO> {
|
|
53
53
|
/**
|
|
54
|
-
* The constructor initializes a new Map object to store
|
|
54
|
+
* The constructor initializes a new Map object to store edgeMap.
|
|
55
55
|
*/
|
|
56
56
|
constructor() {
|
|
57
57
|
super();
|
|
58
|
-
this.
|
|
58
|
+
this._edgeMap = new Map<VO, EO[]>();
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
protected
|
|
61
|
+
protected _edgeMap: Map<VO, EO[]>;
|
|
62
62
|
|
|
63
|
-
get
|
|
64
|
-
return this.
|
|
63
|
+
get edgeMap(): Map<VO, EO[]> {
|
|
64
|
+
return this._edgeMap;
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/**
|
|
@@ -78,7 +78,7 @@ export class UndirectedGraph<
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
|
-
* The function creates an undirected edge between two
|
|
81
|
+
* The function creates an undirected edge between two vertexMap with an optional weight and value.
|
|
82
82
|
* @param {VertexKey} v1 - The parameter `v1` represents the first vertex of the edge.
|
|
83
83
|
* @param {VertexKey} v2 - The parameter `v2` represents the second vertex of the edge.
|
|
84
84
|
* @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the edge. If
|
|
@@ -92,15 +92,15 @@ export class UndirectedGraph<
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
* Time Complexity: O(|E|), where |E| is the number of
|
|
95
|
+
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
|
96
96
|
* Space Complexity: O(1)
|
|
97
97
|
*/
|
|
98
98
|
|
|
99
99
|
/**
|
|
100
|
-
* Time Complexity: O(|E|), where |E| is the number of
|
|
100
|
+
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
|
101
101
|
* Space Complexity: O(1)
|
|
102
102
|
*
|
|
103
|
-
* The function `getEdge` returns the first edge that connects two
|
|
103
|
+
* The function `getEdge` returns the first edge that connects two vertexMap, or undefined if no such edge exists.
|
|
104
104
|
* @param {VO | VertexKey | undefined} v1 - The parameter `v1` represents a vertex or vertex ID. It can be of type `VO` (vertex
|
|
105
105
|
* object), `undefined`, or `VertexKey` (a string or number representing the ID of a vertex).
|
|
106
106
|
* @param {VO | VertexKey | undefined} v2 - The parameter `v2` represents a vertex or vertex ID. It can be of type `VO` (vertex
|
|
@@ -108,34 +108,34 @@ export class UndirectedGraph<
|
|
|
108
108
|
* @returns an edge (EO) or undefined.
|
|
109
109
|
*/
|
|
110
110
|
getEdge(v1: VO | VertexKey | undefined, v2: VO | VertexKey | undefined): EO | undefined {
|
|
111
|
-
let
|
|
111
|
+
let edgeMap: EO[] | undefined = [];
|
|
112
112
|
|
|
113
113
|
if (v1 !== undefined && v2 !== undefined) {
|
|
114
114
|
const vertex1: VO | undefined = this._getVertex(v1);
|
|
115
115
|
const vertex2: VO | undefined = this._getVertex(v2);
|
|
116
116
|
|
|
117
117
|
if (vertex1 && vertex2) {
|
|
118
|
-
|
|
118
|
+
edgeMap = this._edgeMap.get(vertex1)?.filter(e => e.vertexMap.includes(vertex2.key));
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
return
|
|
122
|
+
return edgeMap ? edgeMap[0] || undefined : undefined;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/**
|
|
126
|
-
* Time Complexity: O(|E|), where |E| is the number of
|
|
126
|
+
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
|
127
127
|
* Space Complexity: O(1)
|
|
128
128
|
*/
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
|
-
* Time Complexity: O(|E|), where |E| is the number of
|
|
131
|
+
* Time Complexity: O(|E|), where |E| is the number of edgeMap incident to the given vertex.
|
|
132
132
|
* Space Complexity: O(1)
|
|
133
133
|
*
|
|
134
|
-
* The function removes an edge between two
|
|
134
|
+
* The function removes an edge between two vertexMap in a graph and returns the removed edge.
|
|
135
135
|
* @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
|
|
136
136
|
* @param {VO | VertexKey} v2 - VO | VertexKey - This parameter can be either a vertex object (VO) or a vertex ID
|
|
137
137
|
* (VertexKey). It represents the second vertex of the edge that needs to be removed.
|
|
138
|
-
* @returns the removed edge (EO) if it exists, or undefined if either of the
|
|
138
|
+
* @returns the removed edge (EO) if it exists, or undefined if either of the vertexMap (VO) does not exist.
|
|
139
139
|
*/
|
|
140
140
|
deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | undefined {
|
|
141
141
|
const vertex1: VO | undefined = this._getVertex(v1);
|
|
@@ -145,33 +145,101 @@ export class UndirectedGraph<
|
|
|
145
145
|
return undefined;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
const v1Edges = this.
|
|
148
|
+
const v1Edges = this._edgeMap.get(vertex1);
|
|
149
149
|
let removed: EO | undefined = undefined;
|
|
150
150
|
if (v1Edges) {
|
|
151
|
-
removed = arrayRemove<EO>(v1Edges, (e: EO) => e.
|
|
151
|
+
removed = arrayRemove<EO>(v1Edges, (e: EO) => e.vertexMap.includes(vertex2.key))[0] || undefined;
|
|
152
152
|
}
|
|
153
|
-
const v2Edges = this.
|
|
153
|
+
const v2Edges = this._edgeMap.get(vertex2);
|
|
154
154
|
if (v2Edges) {
|
|
155
|
-
arrayRemove<EO>(v2Edges, (e: EO) => e.
|
|
155
|
+
arrayRemove<EO>(v2Edges, (e: EO) => e.vertexMap.includes(vertex1.key));
|
|
156
156
|
}
|
|
157
157
|
return removed;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
|
-
* Time Complexity: O(
|
|
161
|
+
* Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.
|
|
162
162
|
* Space Complexity: O(1)
|
|
163
163
|
*/
|
|
164
164
|
|
|
165
|
+
|
|
165
166
|
/**
|
|
166
|
-
* Time Complexity: O(
|
|
167
|
+
* Time Complexity: O(E), where E is the number of edgeMap incident to the given vertex.
|
|
167
168
|
* Space Complexity: O(1)
|
|
168
169
|
*
|
|
169
|
-
* The deleteEdge
|
|
170
|
-
* @param {EO}
|
|
171
|
-
*
|
|
170
|
+
* The function `deleteEdge` deletes an edge between two vertexMap in a graph.
|
|
171
|
+
* @param {EO | VertexKey} edgeOrOneSideVertexKey - The parameter `edgeOrOneSideVertexKey` can be
|
|
172
|
+
* either an edge object or a vertex key.
|
|
173
|
+
* @param {VertexKey} [otherSideVertexKey] - The parameter `otherSideVertexKey` is an optional
|
|
174
|
+
* parameter that represents the key of the vertex on the other side of the edge. It is used when the
|
|
175
|
+
* `edgeOrOneSideVertexKey` parameter is a vertex key, and it specifies the key of the vertex on the
|
|
176
|
+
* other side of the
|
|
177
|
+
* @returns The `deleteEdge` function returns either the deleted edge object (EO) or `undefined`.
|
|
178
|
+
*/
|
|
179
|
+
deleteEdge(edgeOrOneSideVertexKey: EO | VertexKey, otherSideVertexKey?: VertexKey): EO | undefined {
|
|
180
|
+
let oneSide: VO | undefined, otherSide: VO | undefined;
|
|
181
|
+
if (this.isVertexKey(edgeOrOneSideVertexKey)) {
|
|
182
|
+
if (this.isVertexKey(otherSideVertexKey)) {
|
|
183
|
+
oneSide = this._getVertex(edgeOrOneSideVertexKey);
|
|
184
|
+
otherSide = this._getVertex(otherSideVertexKey);
|
|
185
|
+
} else {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
oneSide = this._getVertex(edgeOrOneSideVertexKey.vertexMap[0]);
|
|
190
|
+
otherSide = this._getVertex(edgeOrOneSideVertexKey.vertexMap[1]);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (oneSide && otherSide) {
|
|
194
|
+
return this.deleteEdgeBetween(oneSide, otherSide);
|
|
195
|
+
|
|
196
|
+
} else {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Time Complexity: O(1) - Constant time for Map operations.
|
|
203
|
+
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
|
204
|
+
*/
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Time Complexity: O(1) - Constant time for Map operations.
|
|
208
|
+
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
|
209
|
+
*
|
|
210
|
+
* The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.
|
|
211
|
+
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
|
|
212
|
+
* (`VertexKey`).
|
|
213
|
+
* @returns The method is returning a boolean value.
|
|
172
214
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
215
|
+
override deleteVertex(vertexOrKey: VO | VertexKey): boolean {
|
|
216
|
+
let vertexKey: VertexKey;
|
|
217
|
+
let vertex: VO | undefined;
|
|
218
|
+
if (this.isVertexKey(vertexOrKey)) {
|
|
219
|
+
vertex = this.getVertex(vertexOrKey);
|
|
220
|
+
vertexKey = vertexOrKey;
|
|
221
|
+
} else {
|
|
222
|
+
vertex = vertexOrKey;
|
|
223
|
+
vertexKey = this._getVertexKey(vertexOrKey)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const neighbors = this.getNeighbors(vertexOrKey)
|
|
227
|
+
|
|
228
|
+
if (vertex) {
|
|
229
|
+
neighbors.forEach(neighbor => {
|
|
230
|
+
const neighborEdges = this._edgeMap.get(neighbor);
|
|
231
|
+
if (neighborEdges) {
|
|
232
|
+
const restEdges = neighborEdges.filter(edge => {
|
|
233
|
+
return !edge.vertexMap.includes(vertexKey);
|
|
234
|
+
});
|
|
235
|
+
this._edgeMap.set(neighbor, restEdges);
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
this._edgeMap.delete(vertex);
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return this._vertexMap.delete(vertexKey);
|
|
175
243
|
}
|
|
176
244
|
|
|
177
245
|
/**
|
|
@@ -183,16 +251,16 @@ export class UndirectedGraph<
|
|
|
183
251
|
* Time Complexity: O(1)
|
|
184
252
|
* Space Complexity: O(1)
|
|
185
253
|
*
|
|
186
|
-
* The function `degreeOf` returns the degree of a vertex in a graph, which is the number of
|
|
254
|
+
* The function `degreeOf` returns the degree of a vertex in a graph, which is the number of edgeMap connected to that
|
|
187
255
|
* vertex.
|
|
188
256
|
* @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`.
|
|
189
257
|
* @returns The function `degreeOf` returns the degree of a vertex in a graph. The degree of a vertex is the number of
|
|
190
|
-
*
|
|
258
|
+
* edgeMap connected to that vertex.
|
|
191
259
|
*/
|
|
192
260
|
degreeOf(vertexOrKey: VertexKey | VO): number {
|
|
193
261
|
const vertex = this._getVertex(vertexOrKey);
|
|
194
262
|
if (vertex) {
|
|
195
|
-
return this.
|
|
263
|
+
return this._edgeMap.get(vertex)?.length || 0;
|
|
196
264
|
} else {
|
|
197
265
|
return 0;
|
|
198
266
|
}
|
|
@@ -207,36 +275,36 @@ export class UndirectedGraph<
|
|
|
207
275
|
* Time Complexity: O(1)
|
|
208
276
|
* Space Complexity: O(1)
|
|
209
277
|
*
|
|
210
|
-
* The function returns the
|
|
278
|
+
* The function returns the edgeMap of a given vertex or vertex ID.
|
|
211
279
|
* @param {VertexKey | VO} vertexOrKey - The parameter `vertexOrKey` can be either a `VertexKey` or a `VO`. A `VertexKey` is a
|
|
212
280
|
* unique identifier for a vertex in a graph, while `VO` represents the type of the vertex.
|
|
213
|
-
* @returns an array of
|
|
281
|
+
* @returns an array of edgeMap.
|
|
214
282
|
*/
|
|
215
283
|
edgesOf(vertexOrKey: VertexKey | VO): EO[] {
|
|
216
284
|
const vertex = this._getVertex(vertexOrKey);
|
|
217
285
|
if (vertex) {
|
|
218
|
-
return this.
|
|
286
|
+
return this._edgeMap.get(vertex) || [];
|
|
219
287
|
} else {
|
|
220
288
|
return [];
|
|
221
289
|
}
|
|
222
290
|
}
|
|
223
291
|
|
|
224
292
|
/**
|
|
225
|
-
* Time Complexity: O(|V| + |E|), where |V| is the number of
|
|
293
|
+
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
|
226
294
|
* Space Complexity: O(|E|)
|
|
227
295
|
*/
|
|
228
296
|
|
|
229
297
|
/**
|
|
230
|
-
* Time Complexity: O(|V| + |E|), where |V| is the number of
|
|
298
|
+
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
|
231
299
|
* Space Complexity: O(|E|)
|
|
232
300
|
*
|
|
233
|
-
* The function "edgeSet" returns an array of unique
|
|
301
|
+
* The function "edgeSet" returns an array of unique edgeMap from a set of edgeMap.
|
|
234
302
|
* @returns The method `edgeSet()` returns an array of type `EO[]`.
|
|
235
303
|
*/
|
|
236
304
|
edgeSet(): EO[] {
|
|
237
305
|
const edgeSet: Set<EO> = new Set();
|
|
238
|
-
this.
|
|
239
|
-
|
|
306
|
+
this._edgeMap.forEach(edgeMap => {
|
|
307
|
+
edgeMap.forEach(edge => {
|
|
240
308
|
edgeSet.add(edge);
|
|
241
309
|
});
|
|
242
310
|
});
|
|
@@ -244,18 +312,18 @@ export class UndirectedGraph<
|
|
|
244
312
|
}
|
|
245
313
|
|
|
246
314
|
/**
|
|
247
|
-
* Time Complexity: O(|V| + |E|), where |V| is the number of
|
|
315
|
+
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
|
248
316
|
* Space Complexity: O(|E|)
|
|
249
317
|
*/
|
|
250
318
|
|
|
251
319
|
/**
|
|
252
|
-
* Time Complexity: O(|V| + |E|), where |V| is the number of
|
|
320
|
+
* Time Complexity: O(|V| + |E|), where |V| is the number of vertexMap and |E| is the number of edgeMap.
|
|
253
321
|
* Space Complexity: O(|E|)
|
|
254
322
|
*
|
|
255
|
-
* The function "getNeighbors" returns an array of neighboring
|
|
323
|
+
* The function "getNeighbors" returns an array of neighboring vertexMap for a given vertex or vertex ID.
|
|
256
324
|
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
|
|
257
325
|
* (`VertexKey`).
|
|
258
|
-
* @returns an array of
|
|
326
|
+
* @returns an array of vertexMap (VO[]).
|
|
259
327
|
*/
|
|
260
328
|
getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
|
|
261
329
|
const neighbors: VO[] = [];
|
|
@@ -263,7 +331,7 @@ export class UndirectedGraph<
|
|
|
263
331
|
if (vertex) {
|
|
264
332
|
const neighborEdges = this.edgesOf(vertex);
|
|
265
333
|
for (const edge of neighborEdges) {
|
|
266
|
-
const neighbor = this._getVertex(edge.
|
|
334
|
+
const neighbor = this._getVertex(edge.vertexMap.filter(e => e !== vertex.key)[0]);
|
|
267
335
|
if (neighbor) {
|
|
268
336
|
neighbors.push(neighbor);
|
|
269
337
|
}
|
|
@@ -281,18 +349,18 @@ export class UndirectedGraph<
|
|
|
281
349
|
* Time Complexity: O(1)
|
|
282
350
|
* Space Complexity: O(1)
|
|
283
351
|
*
|
|
284
|
-
* The function "getEndsOfEdge" returns the
|
|
352
|
+
* The function "getEndsOfEdge" returns the vertexMap at the ends of an edge if the edge exists in the graph, otherwise
|
|
285
353
|
* it returns undefined.
|
|
286
354
|
* @param {EO} edge - The parameter "edge" is of type EO, which represents an edge in a graph.
|
|
287
|
-
* @returns The function `getEndsOfEdge` returns an array containing two
|
|
355
|
+
* @returns The function `getEndsOfEdge` returns an array containing two vertexMap `[VO, VO]` if the edge exists in the
|
|
288
356
|
* graph. If the edge does not exist, it returns `undefined`.
|
|
289
357
|
*/
|
|
290
358
|
getEndsOfEdge(edge: EO): [VO, VO] | undefined {
|
|
291
|
-
if (!this.hasEdge(edge.
|
|
359
|
+
if (!this.hasEdge(edge.vertexMap[0], edge.vertexMap[1])) {
|
|
292
360
|
return undefined;
|
|
293
361
|
}
|
|
294
|
-
const v1 = this._getVertex(edge.
|
|
295
|
-
const v2 = this._getVertex(edge.
|
|
362
|
+
const v1 = this._getVertex(edge.vertexMap[0]);
|
|
363
|
+
const v2 = this._getVertex(edge.vertexMap[1]);
|
|
296
364
|
if (v1 && v2) {
|
|
297
365
|
return [v1, v2];
|
|
298
366
|
} else {
|
|
@@ -309,20 +377,20 @@ export class UndirectedGraph<
|
|
|
309
377
|
* Time Complexity: O(1)
|
|
310
378
|
* Space Complexity: O(1)
|
|
311
379
|
*
|
|
312
|
-
* The function adds an edge to the graph by updating the adjacency list with the
|
|
380
|
+
* The function adds an edge to the graph by updating the adjacency list with the vertexMap of the edge.
|
|
313
381
|
* @param {EO} edge - The parameter "edge" is of type EO, which represents an edge in a graph.
|
|
314
382
|
* @returns a boolean value.
|
|
315
383
|
*/
|
|
316
384
|
protected _addEdgeOnly(edge: EO): boolean {
|
|
317
|
-
for (const end of edge.
|
|
385
|
+
for (const end of edge.vertexMap) {
|
|
318
386
|
const endVertex = this._getVertex(end);
|
|
319
387
|
if (endVertex === undefined) return false;
|
|
320
388
|
if (endVertex) {
|
|
321
|
-
const
|
|
322
|
-
if (
|
|
323
|
-
|
|
389
|
+
const edgeMap = this._edgeMap.get(endVertex);
|
|
390
|
+
if (edgeMap) {
|
|
391
|
+
edgeMap.push(edge);
|
|
324
392
|
} else {
|
|
325
|
-
this.
|
|
393
|
+
this._edgeMap.set(endVertex, [edge]);
|
|
326
394
|
}
|
|
327
395
|
}
|
|
328
396
|
}
|
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { isWeakKey, rangeCheck } from '../../utils';
|
|
10
|
-
import { HashMapLinkedNode, HashMapOptions, HashMapStoreItem
|
|
11
|
-
import {
|
|
10
|
+
import { EntryCallback, HashMapLinkedNode, HashMapOptions, HashMapStoreItem } from '../../types';
|
|
11
|
+
import { IterableEntryBase } from "../base";
|
|
12
12
|
|
|
13
|
-
export class HashMap<K = any, V = any> extends
|
|
13
|
+
export class HashMap<K = any, V = any> extends IterableEntryBase<K, V> {
|
|
14
14
|
protected _store: { [key: string]: HashMapStoreItem<K, V> } = {};
|
|
15
15
|
protected _objMap: Map<object, V> = new Map();
|
|
16
16
|
|
|
@@ -165,7 +165,7 @@ export class HashMap<K = any, V = any> extends IterablePairBase<K, V> {
|
|
|
165
165
|
* @returns The `map` method is returning a new `HashMap` object with the transformed values based on
|
|
166
166
|
* the provided callback function.
|
|
167
167
|
*/
|
|
168
|
-
map<U>(callbackfn:
|
|
168
|
+
map<U>(callbackfn: EntryCallback<K, V, U>, thisArg?: any): HashMap<K, U> {
|
|
169
169
|
const resultMap = new HashMap<K, U>();
|
|
170
170
|
let index = 0;
|
|
171
171
|
for (const [key, value] of this) {
|
|
@@ -195,7 +195,7 @@ export class HashMap<K = any, V = any> extends IterablePairBase<K, V> {
|
|
|
195
195
|
* @returns The `filter` method is returning a new `HashMap` object that contains the key-value pairs
|
|
196
196
|
* from the original `HashMap` that pass the provided `predicate` function.
|
|
197
197
|
*/
|
|
198
|
-
filter(predicate:
|
|
198
|
+
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): HashMap<K, V> {
|
|
199
199
|
const filteredMap = new HashMap<K, V>();
|
|
200
200
|
let index = 0;
|
|
201
201
|
for (const [key, value] of this) {
|
|
@@ -248,7 +248,7 @@ export class HashMap<K = any, V = any> extends IterablePairBase<K, V> {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
export class LinkedHashMap<K = any, V = any> extends
|
|
251
|
+
export class LinkedHashMap<K = any, V = any> extends IterableEntryBase<K, V> {
|
|
252
252
|
|
|
253
253
|
protected _noObjMap: Record<string, HashMapLinkedNode<K, V | undefined>> = {};
|
|
254
254
|
protected _objMap = new WeakMap<object, HashMapLinkedNode<K, V | undefined>>();
|
|
@@ -567,7 +567,7 @@ export class LinkedHashMap<K = any, V = any> extends IterablePairBase<K, V> {
|
|
|
567
567
|
* @returns a new `LinkedHashMap` object that contains the key-value pairs from the original
|
|
568
568
|
* `LinkedHashMap` object that satisfy the given predicate function.
|
|
569
569
|
*/
|
|
570
|
-
filter(predicate:
|
|
570
|
+
filter(predicate: EntryCallback<K, V, boolean>, thisArg?: any): LinkedHashMap<K, V> {
|
|
571
571
|
const filteredMap = new LinkedHashMap<K, V>();
|
|
572
572
|
let index = 0;
|
|
573
573
|
for (const [key, value] of this) {
|
|
@@ -601,7 +601,7 @@ export class LinkedHashMap<K = any, V = any> extends IterablePairBase<K, V> {
|
|
|
601
601
|
* @returns a new `LinkedHashMap` object with the values mapped according to the provided callback
|
|
602
602
|
* function.
|
|
603
603
|
*/
|
|
604
|
-
map<NV>(callback:
|
|
604
|
+
map<NV>(callback: EntryCallback<K, V, NV>, thisArg?: any): LinkedHashMap<K, NV> {
|
|
605
605
|
const mappedMap = new LinkedHashMap<K, NV>();
|
|
606
606
|
let index = 0;
|
|
607
607
|
for (const [key, value] of this) {
|
|
@@ -13,7 +13,7 @@ export interface IBinaryTree<K = number, V = any, N extends BinaryTreeNode<K, V,
|
|
|
13
13
|
|
|
14
14
|
createTree(options?: Partial<BinaryTreeOptions<K>>): TREE;
|
|
15
15
|
|
|
16
|
-
add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>, count?: number): N | null | undefined;
|
|
16
|
+
add(keyOrNodeOrEntry: BTNodeExemplar<K, V, N>, value?: V, count?: number): N | null | undefined;
|
|
17
17
|
|
|
18
18
|
addMany(nodes: Iterable<BTNodeExemplar<K, V, N>>): (N | null | undefined)[];
|
|
19
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IterableElementBase,
|
|
1
|
+
import { IterableElementBase, IterableEntryBase } from "../../../data-structures";
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type EntryCallback<K, V, R> = (value: V, key: K, index: number, container: IterableEntryBase<K, V>) => R;
|
|
4
4
|
export type ElementCallback<V, R> = (element: V, index: number, container: IterableElementBase<V>) => R;
|
|
5
|
-
export type
|
|
5
|
+
export type ReduceEntryCallback<K, V, R> = (accumulator: R, value: V, key: K, index: number, container: IterableEntryBase<K, V>) => R;
|
|
6
6
|
export type ReduceElementCallback<V, R> = (accumulator: R, element: V, index: number, container: IterableElementBase<V>) => R;
|
|
@@ -183,7 +183,7 @@ describe('Individual package BST operations test', () => {
|
|
|
183
183
|
});
|
|
184
184
|
|
|
185
185
|
it('should perform various operations on a Binary Search Tree with object values', () => {
|
|
186
|
-
const objBST = new BST<{ key: number; keyA: number }>();
|
|
186
|
+
const objBST = new BST<number, { key: number; keyA: number }>();
|
|
187
187
|
expect(objBST).toBeInstanceOf(BST);
|
|
188
188
|
objBST.add([11, { key: 11, keyA: 11 }]);
|
|
189
189
|
objBST.add([3, { key: 3, keyA: 3 }]);
|
|
@@ -605,9 +605,9 @@ describe('TreeMultimap iterative methods test', () => {
|
|
|
605
605
|
let treeMM: TreeMultimap<number, string>;
|
|
606
606
|
beforeEach(() => {
|
|
607
607
|
treeMM = new TreeMultimap<number, string>();
|
|
608
|
-
treeMM.add(
|
|
609
|
-
treeMM.add([2, 'b'], 10);
|
|
610
|
-
treeMM.add([3, 'c'], 1);
|
|
608
|
+
treeMM.add(1, 'a', 10);
|
|
609
|
+
treeMM.add([2, 'b'], undefined, 10);
|
|
610
|
+
treeMM.add([3, 'c'], undefined, 1);
|
|
611
611
|
});
|
|
612
612
|
|
|
613
613
|
test('The node obtained by get Node should match the node type', () => {
|
|
@@ -7,7 +7,7 @@ describe('DirectedGraph Operation Test', () => {
|
|
|
7
7
|
graph = new DirectedGraph();
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
-
it('should add
|
|
10
|
+
it('should add vertexMap', () => {
|
|
11
11
|
const vertex1 = new DirectedVertex('A');
|
|
12
12
|
const vertex2 = new DirectedVertex('B');
|
|
13
13
|
|
|
@@ -155,7 +155,7 @@ describe('Inherit from DirectedGraph and perform operations', () => {
|
|
|
155
155
|
myGraph = new MyDirectedGraph();
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
-
it('Add
|
|
158
|
+
it('Add vertexMap', () => {
|
|
159
159
|
myGraph.addVertex(1, 'data1');
|
|
160
160
|
myGraph.addVertex(2, 'data2');
|
|
161
161
|
myGraph.addVertex(3, 'data3');
|
|
@@ -204,7 +204,7 @@ describe('Inherit from DirectedGraph and perform operations', () => {
|
|
|
204
204
|
expect(true).toBeTruthy();
|
|
205
205
|
});
|
|
206
206
|
|
|
207
|
-
it('Remove edge between
|
|
207
|
+
it('Remove edge between vertexMap', () => {
|
|
208
208
|
myGraph.addVertex(1, 'data1');
|
|
209
209
|
myGraph.addVertex(2, 'data2');
|
|
210
210
|
myGraph.addEdge(1, 2, 10, 'edge-data1-2');
|
|
@@ -232,14 +232,14 @@ describe('Inherit from DirectedGraph and perform operations', () => {
|
|
|
232
232
|
}
|
|
233
233
|
});
|
|
234
234
|
|
|
235
|
-
it('Minimum path between
|
|
235
|
+
it('Minimum path between vertexMap', () => {
|
|
236
236
|
myGraph.addVertex(new MyVertex(1, 'data1'));
|
|
237
237
|
myGraph.addVertex(new MyVertex(2, 'data2'));
|
|
238
238
|
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
-
it('All paths between
|
|
242
|
-
// Add
|
|
241
|
+
it('All paths between vertexMap', () => {
|
|
242
|
+
// Add vertexMap and edges as needed for this test
|
|
243
243
|
myGraph.addVertex(new MyVertex(1, 'data1'));
|
|
244
244
|
myGraph.addVertex(new MyVertex(2, 'data2'));
|
|
245
245
|
myGraph.addEdge(new MyEdge(1, 2, 10, 'edge-data1-2'));
|
|
@@ -598,41 +598,78 @@ describe('cycles, strongly connected components, bridges, articular points in Di
|
|
|
598
598
|
|
|
599
599
|
describe('DirectedGraph iterative Methods', () => {
|
|
600
600
|
let graph: DirectedGraph<string>;
|
|
601
|
-
let
|
|
601
|
+
let vertexMap: string[];
|
|
602
602
|
|
|
603
603
|
beforeEach(() => {
|
|
604
604
|
graph = new DirectedGraph();
|
|
605
|
-
|
|
606
|
-
|
|
605
|
+
vertexMap = ['A', 'B', 'C', 'D'];
|
|
606
|
+
vertexMap.forEach(vertex => graph.addVertex(vertex));
|
|
607
607
|
});
|
|
608
608
|
|
|
609
|
-
test('[Symbol.iterator] should iterate over all
|
|
609
|
+
test('[Symbol.iterator] should iterate over all vertexMap', () => {
|
|
610
610
|
const iteratedVertices = [];
|
|
611
611
|
for (const vertex of graph) {
|
|
612
612
|
iteratedVertices.push(vertex[0]);
|
|
613
613
|
}
|
|
614
|
-
expect(iteratedVertices).toEqual(
|
|
614
|
+
expect(iteratedVertices).toEqual(vertexMap);
|
|
615
615
|
});
|
|
616
616
|
|
|
617
617
|
test('forEach should apply a function to each vertex', () => {
|
|
618
618
|
const result: VertexKey[] = [];
|
|
619
619
|
graph.forEach((value, key) => key && result.push(key));
|
|
620
|
-
expect(result).toEqual(
|
|
620
|
+
expect(result).toEqual(vertexMap);
|
|
621
621
|
});
|
|
622
622
|
|
|
623
|
-
test('filter should return
|
|
623
|
+
test('filter should return vertexMap that satisfy the condition', () => {
|
|
624
624
|
const filtered = graph.filter((value, vertex) => vertex === 'A' || vertex === 'B');
|
|
625
625
|
expect(filtered).toEqual([["A", undefined], ["B", undefined]]);
|
|
626
626
|
});
|
|
627
627
|
|
|
628
628
|
test('map should apply a function to each vertex and return a new array', () => {
|
|
629
629
|
const mapped = graph.map((value, vertex) => vertex + '_mapped');
|
|
630
|
-
expect(mapped).toEqual(
|
|
630
|
+
expect(mapped).toEqual(vertexMap.map(v => v + '_mapped'));
|
|
631
631
|
});
|
|
632
632
|
|
|
633
633
|
test('reduce should accumulate a value based on each vertex', () => {
|
|
634
634
|
const concatenated = graph.reduce((acc, value, key) => acc + key, '');
|
|
635
|
-
expect(concatenated).toBe(
|
|
635
|
+
expect(concatenated).toBe(vertexMap.join(''));
|
|
636
636
|
});
|
|
637
|
+
|
|
638
|
+
test('Removing an edge of a DirectedGraph should not delete additional edges', () => {
|
|
639
|
+
const dg = new DirectedGraph();
|
|
640
|
+
dg.addVertex('hello')
|
|
641
|
+
dg.addVertex('hi')
|
|
642
|
+
dg.addVertex('hey')
|
|
643
|
+
dg.addEdge('hello', 'hi')
|
|
644
|
+
dg.addEdge('hello', 'hey')
|
|
645
|
+
expect(dg.getEdge('hello', 'hi')?.src).toBe('hello')
|
|
646
|
+
expect(dg.getEdge('hello', 'hi')?.dest).toBe('hi')
|
|
647
|
+
expect(dg.getEdge('hello', 'hey')?.src).toBe('hello')
|
|
648
|
+
expect(dg.getEdge('hello', 'hey')?.dest).toBe('hey')
|
|
649
|
+
dg.deleteEdge('hello', 'hi')
|
|
650
|
+
expect(dg.getEdge('hello', 'hi')).toBe(undefined)
|
|
651
|
+
expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(DirectedEdge)
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
test('Removing a vertex from a UndirectedGraph should remove its edges', () => {
|
|
655
|
+
const dg = new DirectedGraph();
|
|
656
|
+
dg.addVertex('hello')
|
|
657
|
+
dg.addVertex('world')
|
|
658
|
+
dg.addVertex('earth')
|
|
659
|
+
|
|
660
|
+
dg.addEdge('hello', 'world')
|
|
661
|
+
dg.addEdge('hello', 'earth')
|
|
662
|
+
dg.addEdge('world', 'earth')
|
|
663
|
+
|
|
664
|
+
expect(dg.getEdge('hello', 'world')?.src).toBe('hello');
|
|
665
|
+
expect(dg.edgeSet().length).toBe(3)
|
|
666
|
+
expect(dg.edgeSet()[0].dest).toBe('world')
|
|
667
|
+
|
|
668
|
+
dg.deleteVertex('hello')
|
|
669
|
+
expect(dg.edgeSet().length).toBe(1)
|
|
670
|
+
expect(dg.edgeSet()?.[0].src).toBe('world')
|
|
671
|
+
|
|
672
|
+
expect(dg.getEdge('hello', 'world')).toBe(undefined);
|
|
673
|
+
})
|
|
637
674
|
});
|
|
638
675
|
|
|
@@ -52,8 +52,8 @@ describe('MapGraph', () => {
|
|
|
52
52
|
mapGraph = new MapGraph<string, string>([0, 0], [100, 100]);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
// Test adding
|
|
56
|
-
it('should add
|
|
55
|
+
// Test adding vertexMap to the graph
|
|
56
|
+
it('should add vertexMap to the graph', () => {
|
|
57
57
|
const locationA = new MapVertex('A', 'Location A', 10, 20);
|
|
58
58
|
const locationB = new MapVertex('B', 'Location B', 30, 40);
|
|
59
59
|
|
|
@@ -88,7 +88,7 @@ describe('MapGraph', () => {
|
|
|
88
88
|
const edgeAB = new MapEdge('A', 'B', 50, 'Edge from A to B');
|
|
89
89
|
const edgeBC = new MapEdge('B', 'C', 60, 'Edge from B to C');
|
|
90
90
|
|
|
91
|
-
expect(mapGraph.
|
|
91
|
+
expect(mapGraph.originCoord).toEqual([0, 0]);
|
|
92
92
|
expect(mapGraph.bottomRight).toEqual([100, 100]);
|
|
93
93
|
|
|
94
94
|
mapGraph.addVertex(locationA);
|