min-heap-typed 1.39.3 → 1.39.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.
Files changed (30) hide show
  1. package/dist/data-structures/binary-tree/avl-tree.d.ts +1 -1
  2. package/dist/data-structures/binary-tree/avl-tree.js +4 -2
  3. package/dist/data-structures/binary-tree/binary-tree.d.ts +5 -13
  4. package/dist/data-structures/binary-tree/binary-tree.js +17 -25
  5. package/dist/data-structures/binary-tree/bst.d.ts +1 -1
  6. package/dist/data-structures/binary-tree/bst.js +6 -6
  7. package/dist/data-structures/binary-tree/tree-multiset.d.ts +1 -1
  8. package/dist/data-structures/binary-tree/tree-multiset.js +2 -2
  9. package/dist/data-structures/graph/abstract-graph.d.ts +88 -88
  10. package/dist/data-structures/graph/abstract-graph.js +41 -41
  11. package/dist/data-structures/graph/directed-graph.d.ts +63 -63
  12. package/dist/data-structures/graph/directed-graph.js +36 -36
  13. package/dist/data-structures/graph/map-graph.d.ts +10 -10
  14. package/dist/data-structures/graph/map-graph.js +7 -7
  15. package/dist/data-structures/graph/undirected-graph.d.ts +38 -38
  16. package/dist/data-structures/graph/undirected-graph.js +21 -21
  17. package/dist/data-structures/queue/queue.d.ts +1 -1
  18. package/dist/data-structures/queue/queue.js +3 -3
  19. package/dist/interfaces/graph.d.ts +3 -3
  20. package/package.json +2 -2
  21. package/src/data-structures/binary-tree/avl-tree.ts +3 -2
  22. package/src/data-structures/binary-tree/binary-tree.ts +19 -28
  23. package/src/data-structures/binary-tree/bst.ts +6 -6
  24. package/src/data-structures/binary-tree/tree-multiset.ts +2 -2
  25. package/src/data-structures/graph/abstract-graph.ts +135 -133
  26. package/src/data-structures/graph/directed-graph.ts +92 -87
  27. package/src/data-structures/graph/map-graph.ts +17 -20
  28. package/src/data-structures/graph/undirected-graph.ts +56 -54
  29. package/src/data-structures/queue/queue.ts +1 -1
  30. package/src/interfaces/graph.ts +3 -3
@@ -45,29 +45,29 @@ export abstract class AbstractVertex<V = any> {
45
45
  }
46
46
  }
47
47
 
48
- export abstract class AbstractEdge<V = any> {
48
+ export abstract class AbstractEdge<VO = any> {
49
49
  /**
50
50
  * The above function is a protected constructor that initializes the weight, value, and hash code properties of an
51
51
  * object.
52
52
  * @param {number} [weight] - The `weight` parameter is an optional number that represents the weight of the object. If
53
53
  * a value is provided, it will be assigned to the `_weight` property. If no value is provided, the default value of 1
54
54
  * will be assigned.
55
- * @param {V} [val] - The `val` parameter is of type `V`, which means it can be any type. It is an optional parameter,
55
+ * @param {VO} [val] - The `val` parameter is of type `VO`, which means it can be any type. It is an optional parameter,
56
56
  * meaning it can be omitted when creating an instance of the class.
57
57
  */
58
- protected constructor(weight?: number, val?: V) {
58
+ protected constructor(weight?: number, val?: VO) {
59
59
  this._weight = weight !== undefined ? weight : 1;
60
60
  this._val = val;
61
61
  this._hashCode = uuidV4();
62
62
  }
63
63
 
64
- private _val: V | undefined;
64
+ private _val: VO | undefined;
65
65
 
66
- get val(): V | undefined {
66
+ get val(): VO | undefined {
67
67
  return this._val;
68
68
  }
69
69
 
70
- set val(value: V | undefined) {
70
+ set val(value: VO | undefined) {
71
71
  this._val = value;
72
72
  }
73
73
 
@@ -103,13 +103,15 @@ export abstract class AbstractEdge<V = any> {
103
103
  }
104
104
 
105
105
  export abstract class AbstractGraph<
106
- V extends AbstractVertex<any> = AbstractVertex<any>,
107
- E extends AbstractEdge<any> = AbstractEdge<any>
108
- > implements IGraph<V, E>
106
+ V = any,
107
+ E = any,
108
+ VO extends AbstractVertex<V> = AbstractVertex<V>,
109
+ EO extends AbstractEdge<E> = AbstractEdge<E>
110
+ > implements IGraph<V, E, VO, EO>
109
111
  {
110
- private _vertices: Map<VertexKey, V> = new Map<VertexKey, V>();
112
+ private _vertices: Map<VertexKey, VO> = new Map<VertexKey, VO>();
111
113
 
112
- get vertices(): Map<VertexKey, V> {
114
+ get vertices(): Map<VertexKey, VO> {
113
115
  return this._vertices;
114
116
  }
115
117
 
@@ -119,7 +121,7 @@ export abstract class AbstractGraph<
119
121
  * @param key
120
122
  * @param val
121
123
  */
122
- abstract createVertex(key: VertexKey, val?: V): V;
124
+ abstract createVertex(key: VertexKey, val?: V): VO;
123
125
 
124
126
  /**
125
127
  * In TypeScript, a subclass inherits the interface implementation of its parent class, without needing to implement the same interface again in the subclass. This behavior differs from Java's approach. In Java, if a parent class implements an interface, the subclass needs to explicitly implement the same interface, even if the parent class has already implemented it.
@@ -129,21 +131,21 @@ export abstract class AbstractGraph<
129
131
  * @param weight
130
132
  * @param val
131
133
  */
132
- abstract createEdge(srcOrV1: VertexKey | string, destOrV2: VertexKey | string, weight?: number, val?: E): E;
134
+ abstract createEdge(srcOrV1: VertexKey | string, destOrV2: VertexKey | string, weight?: number, val?: E): EO;
133
135
 
134
- abstract deleteEdge(edge: E): E | null;
136
+ abstract deleteEdge(edge: EO): EO | null;
135
137
 
136
- abstract getEdge(srcOrKey: V | VertexKey, destOrKey: V | VertexKey): E | null;
138
+ abstract getEdge(srcOrKey: VO | VertexKey, destOrKey: VO | VertexKey): EO | null;
137
139
 
138
- abstract degreeOf(vertexOrKey: V | VertexKey): number;
140
+ abstract degreeOf(vertexOrKey: VO | VertexKey): number;
139
141
 
140
- abstract edgeSet(): E[];
142
+ abstract edgeSet(): EO[];
141
143
 
142
- abstract edgesOf(vertexOrKey: V | VertexKey): E[];
144
+ abstract edgesOf(vertexOrKey: VO | VertexKey): EO[];
143
145
 
144
- abstract getNeighbors(vertexOrKey: V | VertexKey): V[];
146
+ abstract getNeighbors(vertexOrKey: VO | VertexKey): VO[];
145
147
 
146
- abstract getEndsOfEdge(edge: E): [V, V] | null;
148
+ abstract getEndsOfEdge(edge: EO): [VO, VO] | null;
147
149
 
148
150
  /**
149
151
  * The function "getVertex" returns the vertex with the specified ID or null if it doesn't exist.
@@ -152,25 +154,25 @@ export abstract class AbstractGraph<
152
154
  * @returns The method `getVertex` returns the vertex with the specified `vertexKey` if it exists in the `_vertices`
153
155
  * map. If the vertex does not exist, it returns `null`.
154
156
  */
155
- getVertex(vertexKey: VertexKey): V | null {
157
+ getVertex(vertexKey: VertexKey): VO | null {
156
158
  return this._vertices.get(vertexKey) || null;
157
159
  }
158
160
 
159
161
  /**
160
162
  * The function checks if a vertex exists in a graph.
161
- * @param {V | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`V`) or a vertex ID
163
+ * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
162
164
  * (`VertexKey`).
163
165
  * @returns a boolean value.
164
166
  */
165
- hasVertex(vertexOrKey: V | VertexKey): boolean {
167
+ hasVertex(vertexOrKey: VO | VertexKey): boolean {
166
168
  return this._vertices.has(this._getVertexKey(vertexOrKey));
167
169
  }
168
170
 
169
- addVertex(vertex: V): boolean;
171
+ addVertex(vertex: VO): boolean;
170
172
 
171
- addVertex(key: VertexKey, val?: V['val']): boolean;
173
+ addVertex(key: VertexKey, val?: V): boolean;
172
174
 
173
- addVertex(keyOrVertex: VertexKey | V, val?: V['val']): boolean {
175
+ addVertex(keyOrVertex: VertexKey | VO, val?: V): boolean {
174
176
  if (keyOrVertex instanceof AbstractVertex) {
175
177
  return this._addVertexOnly(keyOrVertex);
176
178
  } else {
@@ -181,23 +183,23 @@ export abstract class AbstractGraph<
181
183
 
182
184
  /**
183
185
  * The `deleteVertex` function removes a vertex from a graph by its ID or by the vertex object itself.
184
- * @param {V | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`V`) or a vertex ID
186
+ * @param {VO | VertexKey} vertexOrKey - The parameter `vertexOrKey` can be either a vertex object (`VO`) or a vertex ID
185
187
  * (`VertexKey`).
186
188
  * @returns The method is returning a boolean value.
187
189
  */
188
- deleteVertex(vertexOrKey: V | VertexKey): boolean {
190
+ deleteVertex(vertexOrKey: VO | VertexKey): boolean {
189
191
  const vertexKey = this._getVertexKey(vertexOrKey);
190
192
  return this._vertices.delete(vertexKey);
191
193
  }
192
194
 
193
195
  /**
194
196
  * The function removes all vertices from a graph and returns a boolean indicating if any vertices were removed.
195
- * @param {V[] | VertexKey[]} vertices - The `vertices` parameter can be either an array of vertices (`V[]`) or an array
197
+ * @param {VO[] | VertexKey[]} vertices - The `vertices` parameter can be either an array of vertices (`VO[]`) or an array
196
198
  * of vertex IDs (`VertexKey[]`).
197
199
  * @returns a boolean value. It returns true if at least one vertex was successfully removed, and false if no vertices
198
200
  * were removed.
199
201
  */
200
- removeManyVertices(vertices: V[] | VertexKey[]): boolean {
202
+ removeManyVertices(vertices: VO[] | VertexKey[]): boolean {
201
203
  const removed: boolean[] = [];
202
204
  for (const v of vertices) {
203
205
  removed.push(this.deleteVertex(v));
@@ -207,22 +209,22 @@ export abstract class AbstractGraph<
207
209
 
208
210
  /**
209
211
  * The function checks if there is an edge between two vertices and returns a boolean value indicating the result.
210
- * @param {VertexKey | V} v1 - The parameter v1 can be either a VertexKey or a V. A VertexKey represents the unique
211
- * identifier of a vertex in a graph, while V represents the type of the vertex object itself.
212
- * @param {VertexKey | V} v2 - The parameter `v2` represents the second vertex in the edge. It can be either a
213
- * `VertexKey` or a `V` type, which represents the type of the vertex.
212
+ * @param {VertexKey | VO} v1 - The parameter v1 can be either a VertexKey or a VO. A VertexKey represents the unique
213
+ * identifier of a vertex in a graph, while VO represents the type of the vertex object itself.
214
+ * @param {VertexKey | VO} v2 - The parameter `v2` represents the second vertex in the edge. It can be either a
215
+ * `VertexKey` or a `VO` type, which represents the type of the vertex.
214
216
  * @returns A boolean value is being returned.
215
217
  */
216
- hasEdge(v1: VertexKey | V, v2: VertexKey | V): boolean {
218
+ hasEdge(v1: VertexKey | VO, v2: VertexKey | VO): boolean {
217
219
  const edge = this.getEdge(v1, v2);
218
220
  return !!edge;
219
221
  }
220
222
 
221
- addEdge(edge: E): boolean;
223
+ addEdge(edge: EO): boolean;
222
224
 
223
- addEdge(src: V | VertexKey, dest: V | VertexKey, weight?: number, val?: E['val']): boolean;
225
+ addEdge(src: VO | VertexKey, dest: VO | VertexKey, weight?: number, val?: E): boolean;
224
226
 
225
- addEdge(srcOrEdge: V | VertexKey | E, dest?: V | VertexKey, weight?: number, val?: E['val']): boolean {
227
+ addEdge(srcOrEdge: VO | VertexKey | EO, dest?: VO | VertexKey, weight?: number, val?: E): boolean {
226
228
  if (srcOrEdge instanceof AbstractEdge) {
227
229
  return this._addEdgeOnly(srcOrEdge);
228
230
  } else {
@@ -240,16 +242,16 @@ export abstract class AbstractGraph<
240
242
 
241
243
  /**
242
244
  * The function sets the weight of an edge between two vertices in a graph.
243
- * @param {VertexKey | V} srcOrKey - The `srcOrKey` parameter can be either a `VertexKey` or a `V` object. It represents
245
+ * @param {VertexKey | VO} srcOrKey - The `srcOrKey` parameter can be either a `VertexKey` or a `VO` object. It represents
244
246
  * the source vertex of the edge.
245
- * @param {VertexKey | V} destOrKey - The `destOrKey` parameter represents the destination vertex of the edge. It can be
246
- * either a `VertexKey` or a vertex object `V`.
247
+ * @param {VertexKey | VO} destOrKey - The `destOrKey` parameter represents the destination vertex of the edge. It can be
248
+ * either a `VertexKey` or a vertex object `VO`.
247
249
  * @param {number} weight - The weight parameter represents the weight of the edge between the source vertex (srcOrKey)
248
250
  * and the destination vertex (destOrKey).
249
251
  * @returns a boolean value. If the edge exists between the source and destination vertices, the function will update
250
252
  * the weight of the edge and return true. If the edge does not exist, the function will return false.
251
253
  */
252
- setEdgeWeight(srcOrKey: VertexKey | V, destOrKey: VertexKey | V, weight: number): boolean {
254
+ setEdgeWeight(srcOrKey: VertexKey | VO, destOrKey: VertexKey | VO, weight: number): boolean {
253
255
  const edge = this.getEdge(srcOrKey, destOrKey);
254
256
  if (edge) {
255
257
  edge.weight = weight;
@@ -261,20 +263,20 @@ export abstract class AbstractGraph<
261
263
 
262
264
  /**
263
265
  * The function `getAllPathsBetween` finds all paths between two vertices in a graph using depth-first search.
264
- * @param {V | VertexKey} v1 - The parameter `v1` represents either a vertex object (`V`) or a vertex ID (`VertexKey`).
266
+ * @param {VO | VertexKey} v1 - The parameter `v1` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
265
267
  * It is the starting vertex for finding paths.
266
- * @param {V | VertexKey} v2 - The parameter `v2` represents either a vertex object (`V`) or a vertex ID (`VertexKey`).
267
- * @returns The function `getAllPathsBetween` returns an array of arrays of vertices (`V[][]`).
268
+ * @param {VO | VertexKey} v2 - The parameter `v2` represents either a vertex object (`VO`) or a vertex ID (`VertexKey`).
269
+ * @returns The function `getAllPathsBetween` returns an array of arrays of vertices (`VO[][]`).
268
270
  */
269
- getAllPathsBetween(v1: V | VertexKey, v2: V | VertexKey): V[][] {
270
- const paths: V[][] = [];
271
+ getAllPathsBetween(v1: VO | VertexKey, v2: VO | VertexKey): VO[][] {
272
+ const paths: VO[][] = [];
271
273
  const vertex1 = this._getVertex(v1);
272
274
  const vertex2 = this._getVertex(v2);
273
275
  if (!(vertex1 && vertex2)) {
274
276
  return [];
275
277
  }
276
278
 
277
- const dfs = (cur: V, dest: V, visiting: Map<V, boolean>, path: V[]) => {
279
+ const dfs = (cur: VO, dest: VO, visiting: Map<VO, boolean>, path: VO[]) => {
278
280
  visiting.set(cur, true);
279
281
 
280
282
  if (cur === dest) {
@@ -286,23 +288,23 @@ export abstract class AbstractGraph<
286
288
  if (!visiting.get(neighbor)) {
287
289
  path.push(neighbor);
288
290
  dfs(neighbor, dest, visiting, path);
289
- arrayRemove(path, (vertex: V) => vertex === neighbor);
291
+ arrayRemove(path, (vertex: VO) => vertex === neighbor);
290
292
  }
291
293
  }
292
294
 
293
295
  visiting.set(cur, false);
294
296
  };
295
297
 
296
- dfs(vertex1, vertex2, new Map<V, boolean>(), []);
298
+ dfs(vertex1, vertex2, new Map<VO, boolean>(), []);
297
299
  return paths;
298
300
  }
299
301
 
300
302
  /**
301
303
  * The function calculates the sum of weights along a given path.
302
- * @param {V[]} path - An array of vertices (V) representing a path in a graph.
304
+ * @param {VO[]} path - An array of vertices (VO) representing a path in a graph.
303
305
  * @returns The function `getPathSumWeight` returns the sum of the weights of the edges in the given path.
304
306
  */
305
- getPathSumWeight(path: V[]): number {
307
+ getPathSumWeight(path: VO[]): number {
306
308
  let sum = 0;
307
309
  for (let i = 0; i < path.length; i++) {
308
310
  sum += this.getEdge(path[i], path[i + 1])?.weight || 0;
@@ -313,8 +315,8 @@ export abstract class AbstractGraph<
313
315
  /**
314
316
  * The function `getMinCostBetween` calculates the minimum cost between two vertices in a graph, either based on edge
315
317
  * weights or using a breadth-first search algorithm.
316
- * @param {V | VertexKey} v1 - The parameter `v1` represents the starting vertex or its ID.
317
- * @param {V | VertexKey} v2 - The parameter `v2` represents the destination vertex or its ID. It is the vertex to which
318
+ * @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex or its ID.
319
+ * @param {VO | VertexKey} v2 - The parameter `v2` represents the destination vertex or its ID. It is the vertex to which
318
320
  * you want to find the minimum cost or weight from the source vertex `v1`.
319
321
  * @param {boolean} [isWeight] - isWeight is an optional parameter that indicates whether the graph edges have weights.
320
322
  * If isWeight is set to true, the function will calculate the minimum cost between v1 and v2 based on the weights of
@@ -324,7 +326,7 @@ export abstract class AbstractGraph<
324
326
  * vertices. If `isWeight` is `false` or not provided, it uses a breadth-first search (BFS) algorithm to calculate the
325
327
  * minimum number of
326
328
  */
327
- getMinCostBetween(v1: V | VertexKey, v2: V | VertexKey, isWeight?: boolean): number | null {
329
+ getMinCostBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): number | null {
328
330
  if (isWeight === undefined) isWeight = false;
329
331
 
330
332
  if (isWeight) {
@@ -342,8 +344,8 @@ export abstract class AbstractGraph<
342
344
  return null;
343
345
  }
344
346
 
345
- const visited: Map<V, boolean> = new Map();
346
- const queue = new Queue<V>([vertex1]);
347
+ const visited: Map<VO, boolean> = new Map();
348
+ const queue = new Queue<VO>([vertex1]);
347
349
  visited.set(vertex1, true);
348
350
  let cost = 0;
349
351
  while (queue.size > 0) {
@@ -372,17 +374,17 @@ export abstract class AbstractGraph<
372
374
  /**
373
375
  * The function `getMinPathBetween` returns the minimum path between two vertices in a graph, either based on weight or
374
376
  * using a breadth-first search algorithm.
375
- * @param {V | VertexKey} v1 - The parameter `v1` represents the starting vertex of the path. It can be either a vertex
376
- * object (`V`) or a vertex ID (`VertexKey`).
377
- * @param {V | VertexKey} v2 - V | VertexKey - The second vertex or vertex ID between which we want to find the minimum
377
+ * @param {VO | VertexKey} v1 - The parameter `v1` represents the starting vertex of the path. It can be either a vertex
378
+ * object (`VO`) or a vertex ID (`VertexKey`).
379
+ * @param {VO | VertexKey} v2 - VO | VertexKey - The second vertex or vertex ID between which we want to find the minimum
378
380
  * path.
379
381
  * @param {boolean} [isWeight] - A boolean flag indicating whether to consider the weight of edges in finding the
380
382
  * minimum path. If set to true, the function will use Dijkstra's algorithm to find the minimum weighted path. If set
381
383
  * to false, the function will use breadth-first search (BFS) to find the minimum path.
382
- * @returns The function `getMinPathBetween` returns an array of vertices (`V[]`) representing the minimum path between
384
+ * @returns The function `getMinPathBetween` returns an array of vertices (`VO[]`) representing the minimum path between
383
385
  * two vertices (`v1` and `v2`). If there is no path between the vertices, it returns `null`.
384
386
  */
385
- getMinPathBetween(v1: V | VertexKey, v2: V | VertexKey, isWeight?: boolean): V[] | null {
387
+ getMinPathBetween(v1: VO | VertexKey, v2: VO | VertexKey, isWeight?: boolean): VO[] | null {
386
388
  if (isWeight === undefined) isWeight = false;
387
389
 
388
390
  if (isWeight) {
@@ -401,14 +403,14 @@ export abstract class AbstractGraph<
401
403
  return allPaths[minIndex] || null;
402
404
  } else {
403
405
  // BFS
404
- let minPath: V[] = [];
406
+ let minPath: VO[] = [];
405
407
  const vertex1 = this._getVertex(v1);
406
408
  const vertex2 = this._getVertex(v2);
407
409
  if (!(vertex1 && vertex2)) {
408
410
  return [];
409
411
  }
410
412
 
411
- const dfs = (cur: V, dest: V, visiting: Map<V, boolean>, path: V[]) => {
413
+ const dfs = (cur: VO, dest: VO, visiting: Map<VO, boolean>, path: VO[]) => {
412
414
  visiting.set(cur, true);
413
415
 
414
416
  if (cur === dest) {
@@ -421,29 +423,29 @@ export abstract class AbstractGraph<
421
423
  if (!visiting.get(neighbor)) {
422
424
  path.push(neighbor);
423
425
  dfs(neighbor, dest, visiting, path);
424
- arrayRemove(path, (vertex: V) => vertex === neighbor);
426
+ arrayRemove(path, (vertex: VO) => vertex === neighbor);
425
427
  }
426
428
  }
427
429
 
428
430
  visiting.set(cur, false);
429
431
  };
430
432
 
431
- dfs(vertex1, vertex2, new Map<V, boolean>(), []);
433
+ dfs(vertex1, vertex2, new Map<VO, boolean>(), []);
432
434
  return minPath;
433
435
  }
434
436
  }
435
437
 
436
438
  /**
437
- * Dijkstra algorithm time: O(VE) space: O(V + E)
439
+ * Dijkstra algorithm time: O(VE) space: O(VO + EO)
438
440
  * /
439
441
 
440
442
  /**
441
- * Dijkstra algorithm time: O(VE) space: O(V + E)
443
+ * Dijkstra algorithm time: O(VE) space: O(VO + EO)
442
444
  * The function `dijkstraWithoutHeap` implements Dijkstra's algorithm to find the shortest path between two vertices in
443
445
  * a graph without using a heap data structure.
444
- * @param {V | VertexKey} src - The source vertex from which to start the Dijkstra's algorithm. It can be either a
446
+ * @param {VO | VertexKey} src - The source vertex from which to start the Dijkstra's algorithm. It can be either a
445
447
  * vertex object or a vertex ID.
446
- * @param {V | VertexKey | null} [dest] - The `dest` parameter in the `dijkstraWithoutHeap` function is an optional
448
+ * @param {VO | VertexKey | null} [dest] - The `dest` parameter in the `dijkstraWithoutHeap` function is an optional
447
449
  * parameter that specifies the destination vertex for the Dijkstra algorithm. It can be either a vertex object or its
448
450
  * identifier. If no destination is provided, the value is set to `null`.
449
451
  * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum
@@ -452,27 +454,27 @@ export abstract class AbstractGraph<
452
454
  * @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate
453
455
  * paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the
454
456
  * shortest paths from the source vertex to all other vertices in the graph. If `genPaths
455
- * @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<V>`.
457
+ * @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<VO>`.
456
458
  */
457
459
  dijkstraWithoutHeap(
458
- src: V | VertexKey,
459
- dest?: V | VertexKey | null,
460
+ src: VO | VertexKey,
461
+ dest?: VO | VertexKey | null,
460
462
  getMinDist?: boolean,
461
463
  genPaths?: boolean
462
- ): DijkstraResult<V> {
464
+ ): DijkstraResult<VO> {
463
465
  if (getMinDist === undefined) getMinDist = false;
464
466
  if (genPaths === undefined) genPaths = false;
465
467
 
466
468
  if (dest === undefined) dest = null;
467
469
  let minDist = Infinity;
468
- let minDest: V | null = null;
469
- let minPath: V[] = [];
470
- const paths: V[][] = [];
470
+ let minDest: VO | null = null;
471
+ let minPath: VO[] = [];
472
+ const paths: VO[][] = [];
471
473
 
472
474
  const vertices = this._vertices;
473
- const distMap: Map<V, number> = new Map();
474
- const seen: Set<V> = new Set();
475
- const preMap: Map<V, V | null> = new Map(); // predecessor
475
+ const distMap: Map<VO, number> = new Map();
476
+ const seen: Set<VO> = new Set();
477
+ const preMap: Map<VO, VO | null> = new Map(); // predecessor
476
478
  const srcVertex = this._getVertex(src);
477
479
 
478
480
  const destVertex = dest ? this._getVertex(dest) : null;
@@ -490,7 +492,7 @@ export abstract class AbstractGraph<
490
492
 
491
493
  const getMinOfNoSeen = () => {
492
494
  let min = Infinity;
493
- let minV: V | null = null;
495
+ let minV: VO | null = null;
494
496
  for (const [key, val] of distMap) {
495
497
  if (!seen.has(key)) {
496
498
  if (val < min) {
@@ -502,12 +504,12 @@ export abstract class AbstractGraph<
502
504
  return minV;
503
505
  };
504
506
 
505
- const getPaths = (minV: V | null) => {
507
+ const getPaths = (minV: VO | null) => {
506
508
  for (const vertex of vertices) {
507
509
  const vertexOrKey = vertex[1];
508
510
 
509
511
  if (vertexOrKey instanceof AbstractVertex) {
510
- const path: V[] = [vertexOrKey];
512
+ const path: VO[] = [vertexOrKey];
511
513
  let parent = preMap.get(vertexOrKey);
512
514
  while (parent) {
513
515
  path.push(parent);
@@ -569,11 +571,11 @@ export abstract class AbstractGraph<
569
571
  }
570
572
 
571
573
  /**
572
- * Dijkstra algorithm time: O(logVE) space: O(V + E)
574
+ * Dijkstra algorithm time: O(logVE) space: O(VO + EO)
573
575
  *
574
576
  * Dijkstra's algorithm only solves the single-source shortest path problem, while the Bellman-Ford algorithm and Floyd-Warshall algorithm can address shortest paths between all pairs of nodes.
575
577
  * Dijkstra's algorithm is suitable for graphs with non-negative edge weights, whereas the Bellman-Ford algorithm and Floyd-Warshall algorithm can handle negative-weight edges.
576
- * The time complexity of Dijkstra's algorithm and the Bellman-Ford algorithm depends on the size of the graph, while the time complexity of the Floyd-Warshall algorithm is O(V^3), where V is the number of nodes. For dense graphs, Floyd-Warshall might become slower.
578
+ * The time complexity of Dijkstra's algorithm and the Bellman-Ford algorithm depends on the size of the graph, while the time complexity of the Floyd-Warshall algorithm is O(VO^3), where VO is the number of nodes. For dense graphs, Floyd-Warshall might become slower.
577
579
  *
578
580
  * /
579
581
 
@@ -581,9 +583,9 @@ export abstract class AbstractGraph<
581
583
  * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative.
582
584
  * The `dijkstra` function implements Dijkstra's algorithm to find the shortest path between a source vertex and an
583
585
  * optional destination vertex, and optionally returns the minimum distance, the paths, and other information.
584
- * @param {V | VertexKey} src - The `src` parameter represents the source vertex from which the Dijkstra algorithm will
586
+ * @param {VO | VertexKey} src - The `src` parameter represents the source vertex from which the Dijkstra algorithm will
585
587
  * start. It can be either a vertex object or a vertex ID.
586
- * @param {V | VertexKey | null} [dest] - The `dest` parameter is the destination vertex or vertex ID. It specifies the
588
+ * @param {VO | VertexKey | null} [dest] - The `dest` parameter is the destination vertex or vertex ID. It specifies the
587
589
  * vertex to which the shortest path is calculated from the source vertex. If no destination is provided, the algorithm
588
590
  * will calculate the shortest paths to all other vertices from the source vertex.
589
591
  * @param {boolean} [getMinDist] - The `getMinDist` parameter is a boolean flag that determines whether the minimum
@@ -592,26 +594,26 @@ export abstract class AbstractGraph<
592
594
  * @param {boolean} [genPaths] - The `genPaths` parameter is a boolean flag that determines whether or not to generate
593
595
  * paths in the Dijkstra algorithm. If `genPaths` is set to `true`, the algorithm will calculate and return the
594
596
  * shortest paths from the source vertex to all other vertices in the graph. If `genPaths
595
- * @returns The function `dijkstra` returns an object of type `DijkstraResult<V>`.
597
+ * @returns The function `dijkstra` returns an object of type `DijkstraResult<VO>`.
596
598
  */
597
599
  dijkstra(
598
- src: V | VertexKey,
599
- dest?: V | VertexKey | null,
600
+ src: VO | VertexKey,
601
+ dest?: VO | VertexKey | null,
600
602
  getMinDist?: boolean,
601
603
  genPaths?: boolean
602
- ): DijkstraResult<V> {
604
+ ): DijkstraResult<VO> {
603
605
  if (getMinDist === undefined) getMinDist = false;
604
606
  if (genPaths === undefined) genPaths = false;
605
607
 
606
608
  if (dest === undefined) dest = null;
607
609
  let minDist = Infinity;
608
- let minDest: V | null = null;
609
- let minPath: V[] = [];
610
- const paths: V[][] = [];
610
+ let minDest: VO | null = null;
611
+ let minPath: VO[] = [];
612
+ const paths: VO[][] = [];
611
613
  const vertices = this._vertices;
612
- const distMap: Map<V, number> = new Map();
613
- const seen: Set<V> = new Set();
614
- const preMap: Map<V, V | null> = new Map(); // predecessor
614
+ const distMap: Map<VO, number> = new Map();
615
+ const seen: Set<VO> = new Set();
616
+ const preMap: Map<VO, VO | null> = new Map(); // predecessor
615
617
 
616
618
  const srcVertex = this._getVertex(src);
617
619
  const destVertex = dest ? this._getVertex(dest) : null;
@@ -623,7 +625,7 @@ export abstract class AbstractGraph<
623
625
  if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
624
626
  }
625
627
 
626
- const heap = new PriorityQueue<{key: number; val: V}>({comparator: (a, b) => a.key - b.key});
628
+ const heap = new PriorityQueue<{key: number; val: VO}>({comparator: (a, b) => a.key - b.key});
627
629
  heap.add({key: 0, val: srcVertex});
628
630
 
629
631
  distMap.set(srcVertex, 0);
@@ -631,14 +633,14 @@ export abstract class AbstractGraph<
631
633
 
632
634
  /**
633
635
  * The function `getPaths` retrieves all paths from vertices to a specified minimum vertex.
634
- * @param {V | null} minV - The parameter `minV` is of type `V | null`. It represents the minimum vertex value or
636
+ * @param {VO | null} minV - The parameter `minV` is of type `VO | null`. It represents the minimum vertex value or
635
637
  * null.
636
638
  */
637
- const getPaths = (minV: V | null) => {
639
+ const getPaths = (minV: VO | null) => {
638
640
  for (const vertex of vertices) {
639
641
  const vertexOrKey = vertex[1];
640
642
  if (vertexOrKey instanceof AbstractVertex) {
641
- const path: V[] = [vertexOrKey];
643
+ const path: VO[] = [vertexOrKey];
642
644
  let parent = preMap.get(vertexOrKey);
643
645
  while (parent) {
644
646
  path.push(parent);
@@ -706,17 +708,17 @@ export abstract class AbstractGraph<
706
708
  }
707
709
 
708
710
  /**
709
- * BellmanFord time:O(VE) space:O(V)
711
+ * BellmanFord time:O(VE) space:O(VO)
710
712
  * one to rest pairs
711
713
  * /
712
714
 
713
715
  /**
714
- * BellmanFord time:O(VE) space:O(V)
716
+ * BellmanFord time:O(VE) space:O(VO)
715
717
  * one to rest pairs
716
718
  * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edges for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edges, the Bellman-Ford algorithm is more flexible in some scenarios.
717
719
  * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to
718
720
  * all other vertices in a graph, and optionally detects negative cycles and generates the minimum path.
719
- * @param {V | VertexKey} src - The `src` parameter is the source vertex from which the Bellman-Ford algorithm will
721
+ * @param {VO | VertexKey} src - The `src` parameter is the source vertex from which the Bellman-Ford algorithm will
720
722
  * start calculating the shortest paths. It can be either a vertex object or a vertex ID.
721
723
  * @param {boolean} [scanNegativeCycle] - A boolean flag indicating whether to scan for negative cycles in the graph.
722
724
  * @param {boolean} [getMin] - The `getMin` parameter is a boolean flag that determines whether the algorithm should
@@ -726,16 +728,16 @@ export abstract class AbstractGraph<
726
728
  * vertex.
727
729
  * @returns The function `bellmanFord` returns an object with the following properties:
728
730
  */
729
- bellmanFord(src: V | VertexKey, scanNegativeCycle?: boolean, getMin?: boolean, genPath?: boolean) {
731
+ bellmanFord(src: VO | VertexKey, scanNegativeCycle?: boolean, getMin?: boolean, genPath?: boolean) {
730
732
  if (getMin === undefined) getMin = false;
731
733
  if (genPath === undefined) genPath = false;
732
734
 
733
735
  const srcVertex = this._getVertex(src);
734
- const paths: V[][] = [];
735
- const distMap: Map<V, number> = new Map();
736
- const preMap: Map<V, V> = new Map(); // predecessor
736
+ const paths: VO[][] = [];
737
+ const distMap: Map<VO, number> = new Map();
738
+ const preMap: Map<VO, VO> = new Map(); // predecessor
737
739
  let min = Infinity;
738
- let minPath: V[] = [];
740
+ let minPath: VO[] = [];
739
741
  // TODO
740
742
  let hasNegativeCycle: boolean | undefined;
741
743
  if (scanNegativeCycle) hasNegativeCycle = false;
@@ -770,7 +772,7 @@ export abstract class AbstractGraph<
770
772
  }
771
773
  }
772
774
 
773
- let minDest: V | null = null;
775
+ let minDest: VO | null = null;
774
776
  if (getMin) {
775
777
  distMap.forEach((d, v) => {
776
778
  if (v !== srcVertex) {
@@ -786,7 +788,7 @@ export abstract class AbstractGraph<
786
788
  for (const vertex of vertices) {
787
789
  const vertexOrKey = vertex[1];
788
790
  if (vertexOrKey instanceof AbstractVertex) {
789
- const path: V[] = [vertexOrKey];
791
+ const path: VO[] = [vertexOrKey];
790
792
  let parent = preMap.get(vertexOrKey);
791
793
  while (parent !== undefined) {
792
794
  path.push(parent);
@@ -815,34 +817,34 @@ export abstract class AbstractGraph<
815
817
  }
816
818
 
817
819
  /**
818
- * Dijkstra algorithm time: O(logVE) space: O(V + E)
820
+ * Dijkstra algorithm time: O(logVE) space: O(VO + EO)
819
821
  * /
820
822
 
821
823
  /**
822
- * Dijkstra algorithm time: O(logVE) space: O(V + E)
824
+ * Dijkstra algorithm time: O(logVE) space: O(VO + EO)
823
825
  * Dijkstra's algorithm is used to find the shortest paths from a source node to all other nodes in a graph. Its basic idea is to repeatedly choose the node closest to the source node and update the distances of other nodes using this node as an intermediary. Dijkstra's algorithm requires that the edge weights in the graph are non-negative.
824
826
  */
825
827
 
826
828
  /**
827
- * BellmanFord time:O(VE) space:O(V)
829
+ * BellmanFord time:O(VE) space:O(VO)
828
830
  * one to rest pairs
829
831
  * The Bellman-Ford algorithm is also used to find the shortest paths from a source node to all other nodes in a graph. Unlike Dijkstra's algorithm, it can handle edge weights that are negative. Its basic idea involves iterative relaxation of all edges for several rounds to gradually approximate the shortest paths. Due to its ability to handle negative-weight edges, the Bellman-Ford algorithm is more flexible in some scenarios.
830
832
  * The `bellmanFord` function implements the Bellman-Ford algorithm to find the shortest path from a source vertex to
831
833
  */
832
834
 
833
835
  /**
834
- * Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle
836
+ * Floyd algorithm time: O(VO^3) space: O(VO^2), not support graph with negative weight cycle
835
837
  * all pairs
836
838
  * The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edges, and it can simultaneously compute shortest paths between any two nodes.
837
839
  */
838
840
 
839
841
  /**
840
- * Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle
842
+ * Floyd algorithm time: O(VO^3) space: O(VO^2), not support graph with negative weight cycle
841
843
  * all pairs
842
844
  * /
843
845
 
844
846
  /**
845
- * Floyd algorithm time: O(V^3) space: O(V^2), not support graph with negative weight cycle
847
+ * Floyd algorithm time: O(VO^3) space: O(VO^2), not support graph with negative weight cycle
846
848
  * all pairs
847
849
  * The Floyd-Warshall algorithm is used to find the shortest paths between all pairs of nodes in a graph. It employs dynamic programming to compute the shortest paths from any node to any other node. The Floyd-Warshall algorithm's advantage lies in its ability to handle graphs with negative-weight edges, and it can simultaneously compute shortest paths between any two nodes.
848
850
  * The function implements the Floyd-Warshall algorithm to find the shortest path between all pairs of vertices in a
@@ -852,12 +854,12 @@ export abstract class AbstractGraph<
852
854
  * `predecessor` property is a 2D array of vertices (or `null`) representing the predecessor vertices in the shortest
853
855
  * path between vertices in the
854
856
  */
855
- floyd(): {costs: number[][]; predecessor: (V | null)[][]} {
857
+ floyd(): {costs: number[][]; predecessor: (VO | null)[][]} {
856
858
  const idAndVertices = [...this._vertices];
857
859
  const n = idAndVertices.length;
858
860
 
859
861
  const costs: number[][] = [];
860
- const predecessor: (V | null)[][] = [];
862
+ const predecessor: (VO | null)[][] = [];
861
863
  // successors
862
864
 
863
865
  for (let i = 0; i < n; i++) {
@@ -927,8 +929,8 @@ export abstract class AbstractGraph<
927
929
  if (needSCCs === undefined) needSCCs = defaultConfig;
928
930
  if (needCycles === undefined) needCycles = defaultConfig;
929
931
 
930
- const dfnMap: Map<V, number> = new Map();
931
- const lowMap: Map<V, number> = new Map();
932
+ const dfnMap: Map<VO, number> = new Map();
933
+ const lowMap: Map<VO, number> = new Map();
932
934
  const vertices = this._vertices;
933
935
  vertices.forEach(v => {
934
936
  dfnMap.set(v, -1);
@@ -937,10 +939,10 @@ export abstract class AbstractGraph<
937
939
 
938
940
  const [root] = vertices.values();
939
941
 
940
- const articulationPoints: V[] = [];
941
- const bridges: E[] = [];
942
+ const articulationPoints: VO[] = [];
943
+ const bridges: EO[] = [];
942
944
  let dfn = 0;
943
- const dfs = (cur: V, parent: V | null) => {
945
+ const dfs = (cur: VO, parent: VO | null) => {
944
946
  dfn++;
945
947
  dfnMap.set(cur, dfn);
946
948
  lowMap.set(cur, dfn);
@@ -983,10 +985,10 @@ export abstract class AbstractGraph<
983
985
 
984
986
  dfs(root, null);
985
987
 
986
- let SCCs: Map<number, V[]> = new Map();
988
+ let SCCs: Map<number, VO[]> = new Map();
987
989
 
988
990
  const getSCCs = () => {
989
- const SCCs: Map<number, V[]> = new Map();
991
+ const SCCs: Map<number, VO[]> = new Map();
990
992
  lowMap.forEach((low, vertex) => {
991
993
  if (!SCCs.has(low)) {
992
994
  SCCs.set(low, [vertex]);
@@ -1001,9 +1003,9 @@ export abstract class AbstractGraph<
1001
1003
  SCCs = getSCCs();
1002
1004
  }
1003
1005
 
1004
- const cycles: Map<number, V[]> = new Map();
1006
+ const cycles: Map<number, VO[]> = new Map();
1005
1007
  if (needCycles) {
1006
- let SCCs: Map<number, V[]> = new Map();
1008
+ let SCCs: Map<number, VO[]> = new Map();
1007
1009
  if (SCCs.size < 1) {
1008
1010
  SCCs = getSCCs();
1009
1011
  }
@@ -1018,9 +1020,9 @@ export abstract class AbstractGraph<
1018
1020
  return {dfnMap, lowMap, bridges, articulationPoints, SCCs, cycles};
1019
1021
  }
1020
1022
 
1021
- protected abstract _addEdgeOnly(edge: E): boolean;
1023
+ protected abstract _addEdgeOnly(edge: EO): boolean;
1022
1024
 
1023
- protected _addVertexOnly(newVertex: V): boolean {
1025
+ protected _addVertexOnly(newVertex: VO): boolean {
1024
1026
  if (this.hasVertex(newVertex)) {
1025
1027
  return false;
1026
1028
  // throw (new Error('Duplicated vertex key is not allowed'));
@@ -1029,16 +1031,16 @@ export abstract class AbstractGraph<
1029
1031
  return true;
1030
1032
  }
1031
1033
 
1032
- protected _getVertex(vertexOrKey: VertexKey | V): V | null {
1034
+ protected _getVertex(vertexOrKey: VertexKey | VO): VO | null {
1033
1035
  const vertexKey = this._getVertexKey(vertexOrKey);
1034
1036
  return this._vertices.get(vertexKey) || null;
1035
1037
  }
1036
1038
 
1037
- protected _getVertexKey(vertexOrKey: V | VertexKey): VertexKey {
1039
+ protected _getVertexKey(vertexOrKey: VO | VertexKey): VertexKey {
1038
1040
  return vertexOrKey instanceof AbstractVertex ? vertexOrKey.key : vertexOrKey;
1039
1041
  }
1040
1042
 
1041
- protected _setVertices(value: Map<VertexKey, V>) {
1043
+ protected _setVertices(value: Map<VertexKey, VO>) {
1042
1044
  this._vertices = value;
1043
1045
  }
1044
1046
  }