data-structure-typed 1.48.3 → 1.48.4
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/graph/abstract-graph.d.ts +1 -0
- package/dist/cjs/data-structures/graph/abstract-graph.js +4 -0
- package/dist/cjs/data-structures/graph/abstract-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/directed-graph.d.ts +25 -7
- package/dist/cjs/data-structures/graph/directed-graph.js +58 -12
- package/dist/cjs/data-structures/graph/directed-graph.js.map +1 -1
- package/dist/cjs/data-structures/graph/undirected-graph.d.ts +25 -6
- package/dist/cjs/data-structures/graph/undirected-graph.js +70 -7
- package/dist/cjs/data-structures/graph/undirected-graph.js.map +1 -1
- package/dist/mjs/data-structures/graph/abstract-graph.d.ts +1 -0
- package/dist/mjs/data-structures/graph/abstract-graph.js +4 -0
- package/dist/mjs/data-structures/graph/directed-graph.d.ts +25 -7
- package/dist/mjs/data-structures/graph/directed-graph.js +58 -12
- package/dist/mjs/data-structures/graph/undirected-graph.d.ts +25 -6
- package/dist/mjs/data-structures/graph/undirected-graph.js +70 -7
- package/dist/umd/data-structure-typed.js +124 -18
- package/dist/umd/data-structure-typed.min.js +1 -1
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +1 -1
- package/src/data-structures/graph/abstract-graph.ts +5 -0
- package/src/data-structures/graph/directed-graph.ts +61 -12
- package/src/data-structures/graph/undirected-graph.ts +75 -7
- package/test/integration/bst.test.ts +1 -1
- package/test/unit/data-structures/graph/directed-graph.test.ts +37 -0
- package/test/unit/data-structures/graph/undirected-graph.test.ts +37 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-structure-typed",
|
|
3
|
-
"version": "1.48.
|
|
3
|
+
"version": "1.48.4",
|
|
4
4
|
"description": "Data Structures of Javascript & TypeScript. Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/mjs/index.js",
|
|
@@ -164,6 +164,11 @@ export abstract class AbstractGraph<
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
+
isVertexKey(potentialKey: any): potentialKey is VertexKey {
|
|
168
|
+
const potentialKeyType = typeof potentialKey;
|
|
169
|
+
return potentialKeyType === "string" || potentialKeyType === "number"
|
|
170
|
+
}
|
|
171
|
+
|
|
167
172
|
/**
|
|
168
173
|
* Time Complexity: O(1) - Constant time for Map operations.
|
|
169
174
|
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
|
@@ -178,38 +178,87 @@ export class DirectedGraph<
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
/**
|
|
181
|
-
* Time Complexity: O(
|
|
181
|
+
* Time Complexity: O(E) where E is the number of edges
|
|
182
182
|
* Space Complexity: O(1)
|
|
183
183
|
*/
|
|
184
184
|
|
|
185
|
+
|
|
185
186
|
/**
|
|
186
|
-
* Time Complexity: O(
|
|
187
|
+
* Time Complexity: O(E) where E is the number of edges
|
|
187
188
|
* Space Complexity: O(1)
|
|
188
189
|
*
|
|
189
|
-
* The function removes an edge from a graph and returns the removed edge
|
|
190
|
-
* @param {EO}
|
|
191
|
-
*
|
|
192
|
-
* @
|
|
193
|
-
|
|
194
|
-
|
|
190
|
+
* The `deleteEdge` function removes an edge from a graph and returns the removed edge.
|
|
191
|
+
* @param {EO | VertexKey} edgeOrSrcVertexKey - The `edge` parameter can be either an `EO` object (edge object) or
|
|
192
|
+
* a `VertexKey` (key of a vertex).
|
|
193
|
+
* @param {VertexKey} [destVertexKey] - The `destVertexKey` parameter is an optional parameter that
|
|
194
|
+
* represents the key of the destination vertex of the edge. It is used to specify the destination
|
|
195
|
+
* vertex when the `edge` parameter is a vertex key. If `destVertexKey` is not provided, the function
|
|
196
|
+
* assumes that the `edge`
|
|
197
|
+
* @returns the removed edge (EO) or undefined if no edge was removed.
|
|
198
|
+
*/
|
|
199
|
+
deleteEdge(edgeOrSrcVertexKey: EO | VertexKey, destVertexKey?: VertexKey): EO | undefined {
|
|
195
200
|
let removed: EO | undefined = undefined;
|
|
196
|
-
|
|
197
|
-
|
|
201
|
+
let src: VO | undefined, dest: VO | undefined;
|
|
202
|
+
if (this.isVertexKey(edgeOrSrcVertexKey)) {
|
|
203
|
+
if (this.isVertexKey(destVertexKey)) {
|
|
204
|
+
src = this._getVertex(edgeOrSrcVertexKey);
|
|
205
|
+
dest = this._getVertex(destVertexKey);
|
|
206
|
+
} else {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
} else {
|
|
210
|
+
src = this._getVertex(edgeOrSrcVertexKey.src);
|
|
211
|
+
dest = this._getVertex(edgeOrSrcVertexKey.dest);
|
|
212
|
+
}
|
|
213
|
+
|
|
198
214
|
if (src && dest) {
|
|
199
215
|
const srcOutEdges = this._outEdgeMap.get(src);
|
|
200
216
|
if (srcOutEdges && srcOutEdges.length > 0) {
|
|
201
|
-
arrayRemove(srcOutEdges, (edge: EO) => edge.src === src.key);
|
|
217
|
+
arrayRemove(srcOutEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest?.key);
|
|
202
218
|
}
|
|
203
219
|
|
|
204
220
|
const destInEdges = this._inEdgeMap.get(dest);
|
|
205
221
|
if (destInEdges && destInEdges.length > 0) {
|
|
206
|
-
removed = arrayRemove(destInEdges, (edge: EO) => edge.dest === dest
|
|
222
|
+
removed = arrayRemove(destInEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest!.key)[0];
|
|
207
223
|
}
|
|
208
224
|
}
|
|
209
225
|
|
|
210
226
|
return removed;
|
|
211
227
|
}
|
|
212
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Time Complexity: O(1) - Constant time for Map operations.
|
|
231
|
+
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Time Complexity: O(1) - Constant time for Map operations.
|
|
236
|
+
* Space Complexity: O(1) - Constant space, as it creates only a few variables.
|
|
237
|
+
*
|
|
238
|
+
* The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.
|
|
239
|
+
* @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
|
|
240
|
+
* (`VertexKey`).
|
|
241
|
+
* @returns The method is returning a boolean value.
|
|
242
|
+
*/
|
|
243
|
+
override deleteVertex(vertexOrKey: VO | VertexKey): boolean {
|
|
244
|
+
let vertexKey: VertexKey;
|
|
245
|
+
let vertex: VO | undefined;
|
|
246
|
+
if (this.isVertexKey(vertexOrKey)) {
|
|
247
|
+
vertex = this.getVertex(vertexOrKey);
|
|
248
|
+
vertexKey = vertexOrKey;
|
|
249
|
+
} else {
|
|
250
|
+
vertex = vertexOrKey;
|
|
251
|
+
vertexKey = this._getVertexKey(vertexOrKey)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (vertex) {
|
|
255
|
+
this._outEdgeMap.delete(vertex)
|
|
256
|
+
this._inEdgeMap.delete(vertex)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return this._vertices.delete(vertexKey);
|
|
260
|
+
}
|
|
261
|
+
|
|
213
262
|
/**
|
|
214
263
|
* Time Complexity: O(|E|) where |E| is the number of edges
|
|
215
264
|
* Space Complexity: O(1)
|
|
@@ -158,20 +158,88 @@ export class UndirectedGraph<
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
|
-
* Time Complexity: O(
|
|
161
|
+
* Time Complexity: O(E), where E is the number of edges 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 edges 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 vertices 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.vertices[0]);
|
|
190
|
+
otherSide = this._getVertex(edgeOrOneSideVertexKey.vertices[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.
|
|
172
204
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
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.
|
|
214
|
+
*/
|
|
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._edges.get(neighbor);
|
|
231
|
+
if (neighborEdges) {
|
|
232
|
+
const restEdges = neighborEdges.filter(edge => {
|
|
233
|
+
return !edge.vertices.includes(vertexKey);
|
|
234
|
+
});
|
|
235
|
+
this._edges.set(neighbor, restEdges);
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
this._edges.delete(vertex);
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return this._vertices.delete(vertexKey);
|
|
175
243
|
}
|
|
176
244
|
|
|
177
245
|
/**
|
|
@@ -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 }]);
|
|
@@ -634,5 +634,42 @@ describe('DirectedGraph iterative Methods', () => {
|
|
|
634
634
|
const concatenated = graph.reduce((acc, value, key) => acc + key, '');
|
|
635
635
|
expect(concatenated).toBe(vertices.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
|
|
|
@@ -173,6 +173,43 @@ describe('UndirectedGraph', () => {
|
|
|
173
173
|
expect(minWeightedPath?.minPath?.[3]?.key).toBe('Intersection_4');
|
|
174
174
|
expect(minWeightedPath?.minPath?.[4]?.key).toBe('Intersection_5');
|
|
175
175
|
});
|
|
176
|
+
|
|
177
|
+
test('Removing an edge of a UndirectedGraph should not delete additional edges', () => {
|
|
178
|
+
const dg = new UndirectedGraph();
|
|
179
|
+
dg.addVertex('hello')
|
|
180
|
+
dg.addVertex('hi')
|
|
181
|
+
dg.addVertex('hey')
|
|
182
|
+
dg.addEdge('hello', 'hi')
|
|
183
|
+
dg.addEdge('hello', 'hey')
|
|
184
|
+
expect(dg.getEdge('hello', 'hi')?.vertices[0]).toBe('hello')
|
|
185
|
+
expect(dg.getEdge('hello', 'hi')?.vertices[1]).toBe('hi')
|
|
186
|
+
expect(dg.getEdge('hello', 'hey')?.vertices[0]).toBe('hello')
|
|
187
|
+
expect(dg.getEdge('hello', 'hey')?.vertices[1]).toBe('hey')
|
|
188
|
+
dg.deleteEdge('hello', 'hi')
|
|
189
|
+
expect(dg.getEdge('hello', 'hi')).toBe(undefined)
|
|
190
|
+
expect(dg.getEdge('hello', 'hey')).toBeInstanceOf(UndirectedEdge)
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('Removing a vertex from a UndirectedGraph should remove its edges', () => {
|
|
194
|
+
const dg = new UndirectedGraph();
|
|
195
|
+
dg.addVertex('hello')
|
|
196
|
+
dg.addVertex('world')
|
|
197
|
+
dg.addVertex('earth')
|
|
198
|
+
|
|
199
|
+
dg.addEdge('hello', 'world')
|
|
200
|
+
dg.addEdge('hello', 'earth')
|
|
201
|
+
dg.addEdge('world', 'earth')
|
|
202
|
+
|
|
203
|
+
expect(dg.getEdge('hello', 'world')?.vertices[0]).toBe('hello');
|
|
204
|
+
expect(dg.edgeSet().length).toBe(3)
|
|
205
|
+
expect(dg.edgeSet()[0].vertices).toEqual(['hello', 'world'])
|
|
206
|
+
|
|
207
|
+
dg.deleteVertex('hello')
|
|
208
|
+
expect(dg.edgeSet().length).toBe(1)
|
|
209
|
+
expect(dg.edgeSet()?.[0].vertices[0]).toBe('world')
|
|
210
|
+
|
|
211
|
+
expect(dg.getEdge('hello', 'world')).toBe(undefined);
|
|
212
|
+
})
|
|
176
213
|
});
|
|
177
214
|
|
|
178
215
|
describe('cycles, strongly connected components, bridges, articular points in UndirectedGraph', () => {
|