data-structure-typed 2.5.3 → 2.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/.github/workflows/ci.yml +7 -2
  2. package/.github/workflows/release-package.yml +9 -2
  3. package/.husky/pre-commit +3 -0
  4. package/CHANGELOG.md +1 -1
  5. package/MIGRATION.md +48 -0
  6. package/README.md +20 -2
  7. package/README_CN.md +20 -2
  8. package/SPECIFICATION.md +24 -0
  9. package/SPECIFICATION.zh-CN.md +24 -0
  10. package/dist/cjs/binary-tree.cjs +1897 -19
  11. package/dist/cjs/graph.cjs +174 -0
  12. package/dist/cjs/hash.cjs +33 -0
  13. package/dist/cjs/heap.cjs +71 -0
  14. package/dist/cjs/index.cjs +2383 -3
  15. package/dist/cjs/linked-list.cjs +224 -2
  16. package/dist/cjs/matrix.cjs +24 -0
  17. package/dist/cjs/priority-queue.cjs +71 -0
  18. package/dist/cjs/queue.cjs +221 -1
  19. package/dist/cjs/stack.cjs +59 -0
  20. package/dist/cjs/trie.cjs +62 -0
  21. package/dist/cjs-legacy/binary-tree.cjs +1897 -19
  22. package/dist/cjs-legacy/graph.cjs +174 -0
  23. package/dist/cjs-legacy/hash.cjs +33 -0
  24. package/dist/cjs-legacy/heap.cjs +71 -0
  25. package/dist/cjs-legacy/index.cjs +2383 -3
  26. package/dist/cjs-legacy/linked-list.cjs +224 -2
  27. package/dist/cjs-legacy/matrix.cjs +24 -0
  28. package/dist/cjs-legacy/priority-queue.cjs +71 -0
  29. package/dist/cjs-legacy/queue.cjs +221 -1
  30. package/dist/cjs-legacy/stack.cjs +59 -0
  31. package/dist/cjs-legacy/trie.cjs +62 -0
  32. package/dist/esm/binary-tree.mjs +1897 -19
  33. package/dist/esm/graph.mjs +174 -0
  34. package/dist/esm/hash.mjs +33 -0
  35. package/dist/esm/heap.mjs +71 -0
  36. package/dist/esm/index.mjs +2383 -3
  37. package/dist/esm/linked-list.mjs +224 -2
  38. package/dist/esm/matrix.mjs +24 -0
  39. package/dist/esm/priority-queue.mjs +71 -0
  40. package/dist/esm/queue.mjs +221 -1
  41. package/dist/esm/stack.mjs +59 -0
  42. package/dist/esm/trie.mjs +62 -0
  43. package/dist/esm-legacy/binary-tree.mjs +1897 -19
  44. package/dist/esm-legacy/graph.mjs +174 -0
  45. package/dist/esm-legacy/hash.mjs +33 -0
  46. package/dist/esm-legacy/heap.mjs +71 -0
  47. package/dist/esm-legacy/index.mjs +2383 -3
  48. package/dist/esm-legacy/linked-list.mjs +224 -2
  49. package/dist/esm-legacy/matrix.mjs +24 -0
  50. package/dist/esm-legacy/priority-queue.mjs +71 -0
  51. package/dist/esm-legacy/queue.mjs +221 -1
  52. package/dist/esm-legacy/stack.mjs +59 -0
  53. package/dist/esm-legacy/trie.mjs +62 -0
  54. package/dist/types/data-structures/base/iterable-element-base.d.ts +17 -0
  55. package/dist/types/data-structures/base/linear-base.d.ts +6 -0
  56. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +36 -0
  57. package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +42 -0
  58. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +75 -0
  59. package/dist/types/data-structures/binary-tree/bst.d.ts +72 -0
  60. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +57 -0
  61. package/dist/types/data-structures/binary-tree/segment-tree.d.ts +18 -0
  62. package/dist/types/data-structures/binary-tree/tree-map.d.ts +375 -0
  63. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +389 -0
  64. package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +330 -0
  65. package/dist/types/data-structures/binary-tree/tree-set.d.ts +438 -0
  66. package/dist/types/data-structures/graph/directed-graph.d.ts +30 -0
  67. package/dist/types/data-structures/graph/undirected-graph.d.ts +27 -0
  68. package/dist/types/data-structures/hash/hash-map.d.ts +33 -0
  69. package/dist/types/data-structures/heap/heap.d.ts +42 -0
  70. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +75 -2
  71. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +45 -0
  72. package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +54 -0
  73. package/dist/types/data-structures/matrix/matrix.d.ts +24 -0
  74. package/dist/types/data-structures/queue/deque.d.ts +90 -1
  75. package/dist/types/data-structures/queue/queue.d.ts +36 -0
  76. package/dist/types/data-structures/stack/stack.d.ts +30 -0
  77. package/dist/types/data-structures/trie/trie.d.ts +36 -0
  78. package/dist/umd/data-structure-typed.js +2383 -3
  79. package/dist/umd/data-structure-typed.min.js +3 -3
  80. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
  81. package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
  82. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
  83. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
  84. package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
  85. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
  86. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
  87. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
  88. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
  89. package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
  90. package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
  91. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
  92. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
  93. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
  94. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +30 -26
  95. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
  96. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
  97. package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
  98. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
  99. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
  100. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
  101. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
  102. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
  103. package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
  104. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
  105. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
  106. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
  107. package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
  108. package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
  109. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
  110. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
  111. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
  112. package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
  113. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
  114. package/jest.integration.config.js +1 -2
  115. package/package.json +51 -50
  116. package/src/common/error.ts +15 -32
  117. package/src/common/index.ts +0 -3
  118. package/src/data-structures/base/iterable-element-base.ts +32 -3
  119. package/src/data-structures/base/linear-base.ts +13 -36
  120. package/src/data-structures/binary-tree/avl-tree.ts +31 -493
  121. package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -530
  122. package/src/data-structures/binary-tree/binary-tree.ts +326 -1236
  123. package/src/data-structures/binary-tree/bst.ts +158 -1010
  124. package/src/data-structures/binary-tree/red-black-tree.ts +451 -1233
  125. package/src/data-structures/binary-tree/segment-tree.ts +73 -333
  126. package/src/data-structures/binary-tree/tree-map.ts +462 -4749
  127. package/src/data-structures/binary-tree/tree-multi-map.ts +310 -4530
  128. package/src/data-structures/binary-tree/tree-multi-set.ts +300 -3652
  129. package/src/data-structures/binary-tree/tree-set.ts +437 -4443
  130. package/src/data-structures/graph/abstract-graph.ts +98 -167
  131. package/src/data-structures/graph/directed-graph.ts +137 -532
  132. package/src/data-structures/graph/map-graph.ts +0 -3
  133. package/src/data-structures/graph/undirected-graph.ts +132 -484
  134. package/src/data-structures/hash/hash-map.ts +154 -549
  135. package/src/data-structures/heap/heap.ts +200 -753
  136. package/src/data-structures/linked-list/doubly-linked-list.ts +153 -809
  137. package/src/data-structures/linked-list/singly-linked-list.ts +122 -749
  138. package/src/data-structures/linked-list/skip-linked-list.ts +211 -864
  139. package/src/data-structures/matrix/matrix.ts +179 -494
  140. package/src/data-structures/matrix/navigator.ts +0 -1
  141. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
  142. package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
  143. package/src/data-structures/priority-queue/priority-queue.ts +1 -2
  144. package/src/data-structures/queue/deque.ts +241 -807
  145. package/src/data-structures/queue/queue.ts +102 -589
  146. package/src/data-structures/stack/stack.ts +76 -475
  147. package/src/data-structures/trie/trie.ts +98 -592
  148. package/src/types/common.ts +0 -10
  149. package/src/types/data-structures/binary-tree/bst.ts +0 -7
  150. package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
  151. package/src/types/data-structures/graph/abstract-graph.ts +0 -2
  152. package/src/types/data-structures/hash/hash-map.ts +0 -3
  153. package/src/types/data-structures/hash/index.ts +0 -1
  154. package/src/types/data-structures/matrix/navigator.ts +0 -2
  155. package/src/types/utils/utils.ts +0 -7
  156. package/src/types/utils/validate-type.ts +0 -7
  157. package/src/utils/number.ts +0 -2
  158. package/src/utils/utils.ts +0 -5
@@ -5,7 +5,6 @@
5
5
  * @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
6
6
  * @license MIT License
7
7
  */
8
-
9
8
  import type { GraphOptions, TopologicalStatus, VertexKey } from '../../types';
10
9
  import { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';
11
10
  import { IGraph } from '../../interfaces';
@@ -133,10 +132,6 @@ export class DirectedGraph<
133
132
  super(options);
134
133
  }
135
134
 
136
- protected override get _edgeConnector(): string {
137
- return '->';
138
- }
139
-
140
135
  protected _outEdgeMap: Map<VO, EO[]> = new Map<VO, EO[]>();
141
136
 
142
137
  get outEdgeMap(): Map<VO, EO[]> {
@@ -157,6 +152,10 @@ export class DirectedGraph<
157
152
  this._inEdgeMap = v;
158
153
  }
159
154
 
155
+ protected override get _edgeConnector(): string {
156
+ return '->';
157
+ }
158
+
160
159
  /**
161
160
  * Construct a directed graph from keys with value initializer `v => v`.
162
161
  * @template K - Vertex key type.
@@ -164,7 +163,9 @@ export class DirectedGraph<
164
163
  * @returns DirectedGraph with all keys added.
165
164
  * @remarks Time O(V), Space O(V)
166
165
  */
167
- static fromKeys<K extends VertexKey>(keys: Iterable<K>): DirectedGraph<K, undefined, DirectedVertex<K>, DirectedEdge<undefined>> {
166
+ static fromKeys<K extends VertexKey>(
167
+ keys: Iterable<K>
168
+ ): DirectedGraph<K, undefined, DirectedVertex<K>, DirectedEdge<undefined>> {
168
169
  const g: DirectedGraph<K, undefined, DirectedVertex<K>, DirectedEdge<undefined>> = new DirectedGraph<K, undefined>({
169
170
  vertexValueInitializer: (k: VertexKey) => k as K
170
171
  });
@@ -182,7 +183,10 @@ export class DirectedGraph<
182
183
  static fromEntries<V>(
183
184
  entries: Iterable<[VertexKey, V]>
184
185
  ): DirectedGraph<V, undefined, DirectedVertex<V>, DirectedEdge<undefined>> {
185
- const g: DirectedGraph<V, undefined, DirectedVertex<V>, DirectedEdge<undefined>> = new DirectedGraph<V, undefined>();
186
+ const g: DirectedGraph<V, undefined, DirectedVertex<V>, DirectedEdge<undefined>> = new DirectedGraph<
187
+ V,
188
+ undefined
189
+ >();
186
190
  for (const [k, v] of entries) g.addVertex(k, v);
187
191
  return g;
188
192
  }
@@ -217,58 +221,20 @@ export class DirectedGraph<
217
221
  * @param destOrKey - Destination vertex or key.
218
222
  * @returns Edge instance or `undefined`.
219
223
  * @remarks Time O(1) avg, Space O(1)
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
-
235
-
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
-
244
-
245
-
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
- * @example
257
- * // Get edge between vertices
258
- * const g = new DirectedGraph();
259
- * g.addVertex('A');
260
- * g.addVertex('B');
261
- * g.addEdge('A', 'B', 5);
262
- * const edge = g.getEdge('A', 'B');
263
- * console.log(edge?.weight); // 5;
224
+ * @example
225
+ * // Get edge between vertices
226
+ * const g = new DirectedGraph();
227
+ * g.addVertex('A');
228
+ * g.addVertex('B');
229
+ * g.addEdge('A', 'B', 5);
230
+ * const edge = g.getEdge('A', 'B');
231
+ * console.log(edge?.weight); // 5;
264
232
  */
265
233
  getEdge(srcOrKey: VO | VertexKey | undefined, destOrKey: VO | VertexKey | undefined): EO | undefined {
266
234
  let edgeMap: EO[] = [];
267
-
268
235
  if (srcOrKey !== undefined && destOrKey !== undefined) {
269
236
  const src: VO | undefined = this._getVertex(srcOrKey);
270
237
  const dest: VO | undefined = this._getVertex(destOrKey);
271
-
272
238
  if (src && dest) {
273
239
  const srcOutEdges = this._outEdgeMap.get(src);
274
240
  if (srcOutEdges) {
@@ -276,7 +242,6 @@ export class DirectedGraph<
276
242
  }
277
243
  }
278
244
  }
279
-
280
245
  return edgeMap[0] || undefined;
281
246
  }
282
247
 
@@ -294,12 +259,10 @@ export class DirectedGraph<
294
259
  if (!src || !dest) {
295
260
  return undefined;
296
261
  }
297
-
298
262
  const srcOutEdges = this._outEdgeMap.get(src);
299
263
  if (srcOutEdges) {
300
264
  arrayRemove<EO>(srcOutEdges, (edge: EO) => edge.dest === dest.key);
301
265
  }
302
-
303
266
  const destInEdges = this._inEdgeMap.get(dest);
304
267
  if (destInEdges) {
305
268
  removed = arrayRemove<EO>(destInEdges, (edge: EO) => edge.src === src.key)[0] || undefined;
@@ -313,70 +276,31 @@ export class DirectedGraph<
313
276
  * @param destVertexKey - Optional destination vertex/key when deleting by pair.
314
277
  * @returns Removed edge or `undefined`.
315
278
  * @remarks Time O(1) avg, Space O(1)
316
-
317
-
318
-
319
-
320
-
321
-
322
-
323
-
324
-
325
-
326
-
327
-
328
-
329
-
330
-
331
-
332
-
333
-
334
-
335
-
336
-
337
-
338
-
339
-
340
-
341
-
342
-
343
-
344
-
345
-
346
-
347
-
348
-
349
-
350
-
351
-
352
-
353
-
354
-
355
- * @example
356
- * // DirectedGraph deleteEdge and vertex operations
357
- * const graph = new DirectedGraph<string>();
358
- *
359
- * // Build a small graph
360
- * graph.addVertex('X');
361
- * graph.addVertex('Y');
362
- * graph.addVertex('Z');
363
- * graph.addEdge('X', 'Y', 1);
364
- * graph.addEdge('Y', 'Z', 2);
365
- *
366
- * // Delete an edge
367
- * graph.deleteEdgeSrcToDest('X', 'Y');
368
- * console.log(graph.hasEdge('X', 'Y')); // false;
369
- *
370
- * // Edge in other direction should not exist
371
- * console.log(graph.hasEdge('Y', 'X')); // false;
372
- *
373
- * // Other edges should remain
374
- * console.log(graph.hasEdge('Y', 'Z')); // true;
375
- *
376
- * // Delete a vertex
377
- * graph.deleteVertex('Y');
378
- * console.log(graph.hasVertex('Y')); // false;
379
- * console.log(graph.size); // 2;
279
+ * @example
280
+ * // DirectedGraph deleteEdge and vertex operations
281
+ * const graph = new DirectedGraph<string>();
282
+ *
283
+ * // Build a small graph
284
+ * graph.addVertex('X');
285
+ * graph.addVertex('Y');
286
+ * graph.addVertex('Z');
287
+ * graph.addEdge('X', 'Y', 1);
288
+ * graph.addEdge('Y', 'Z', 2);
289
+ *
290
+ * // Delete an edge
291
+ * graph.deleteEdgeSrcToDest('X', 'Y');
292
+ * console.log(graph.hasEdge('X', 'Y')); // false;
293
+ *
294
+ * // Edge in other direction should not exist
295
+ * console.log(graph.hasEdge('Y', 'X')); // false;
296
+ *
297
+ * // Other edges should remain
298
+ * console.log(graph.hasEdge('Y', 'Z')); // true;
299
+ *
300
+ * // Delete a vertex
301
+ * graph.deleteVertex('Y');
302
+ * console.log(graph.hasVertex('Y')); // false;
303
+ * console.log(graph.size); // 2;
380
304
  */
381
305
  deleteEdge(edgeOrSrcVertexKey: EO | VertexKey, destVertexKey?: VertexKey): EO | undefined {
382
306
  let removed: EO | undefined = undefined;
@@ -392,69 +316,30 @@ export class DirectedGraph<
392
316
  src = this._getVertex(edgeOrSrcVertexKey.src);
393
317
  dest = this._getVertex(edgeOrSrcVertexKey.dest);
394
318
  }
395
-
396
319
  if (src && dest) {
397
320
  const srcOutEdges = this._outEdgeMap.get(src);
398
321
  if (srcOutEdges && srcOutEdges.length > 0) {
399
322
  arrayRemove(srcOutEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest?.key);
400
323
  }
401
-
402
324
  const destInEdges = this._inEdgeMap.get(dest);
403
325
  if (destInEdges && destInEdges.length > 0) {
404
326
  removed = arrayRemove(destInEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest!.key)[0];
405
327
  }
406
328
  }
407
-
408
329
  return removed;
409
330
  }
410
331
 
411
- /**
332
+ /**
412
333
  * Remove a vertex
413
-
414
-
415
-
416
-
417
-
418
-
419
-
420
-
421
-
422
-
423
-
424
-
425
-
426
-
427
-
428
-
429
-
430
-
431
-
432
-
433
-
434
-
435
-
436
-
437
-
438
-
439
-
440
-
441
-
442
-
443
-
444
-
445
-
446
-
447
-
448
-
449
- * @example
450
- * // Remove a vertex
451
- * const g = new DirectedGraph();
452
- * g.addVertex('A');
453
- * g.addVertex('B');
454
- * g.addEdge('A', 'B');
455
- * g.deleteVertex('A');
456
- * console.log(g.hasVertex('A')); // false;
457
- * console.log(g.hasEdge('A', 'B')); // false;
334
+ * @example
335
+ * // Remove a vertex
336
+ * const g = new DirectedGraph();
337
+ * g.addVertex('A');
338
+ * g.addVertex('B');
339
+ * g.addEdge('A', 'B');
340
+ * g.deleteVertex('A');
341
+ * console.log(g.hasVertex('A')); // false;
342
+ * console.log(g.hasEdge('A', 'B')); // false;
458
343
  */
459
344
  deleteVertex(vertexOrKey: VO | VertexKey): boolean {
460
345
  let vertexKey: VertexKey;
@@ -466,7 +351,6 @@ export class DirectedGraph<
466
351
  vertex = vertexOrKey;
467
352
  vertexKey = this._getVertexKey(vertexOrKey);
468
353
  }
469
-
470
354
  if (vertex) {
471
355
  /**
472
356
  * One-step neighbors following outgoing edges.
@@ -481,21 +365,17 @@ export class DirectedGraph<
481
365
  this._outEdgeMap.delete(vertex);
482
366
  this._inEdgeMap.delete(vertex);
483
367
  }
484
-
485
368
  return this._vertexMap.delete(vertexKey);
486
369
  }
487
370
 
488
371
  deleteEdgesBetween(v1: VertexKey | VO, v2: VertexKey | VO): EO[] {
489
372
  const removed: EO[] = [];
490
-
491
373
  if (v1 && v2) {
492
374
  const v1ToV2 = this.deleteEdgeSrcToDest(v1, v2);
493
375
  const v2ToV1 = this.deleteEdgeSrcToDest(v2, v1);
494
-
495
376
  if (v1ToV2) removed.push(v1ToV2);
496
377
  if (v2ToV1) removed.push(v2ToV1);
497
378
  }
498
-
499
379
  return removed;
500
380
  }
501
381
 
@@ -504,51 +384,15 @@ export class DirectedGraph<
504
384
  * @param vertexOrKey - Vertex or key.
505
385
  * @returns Array of incoming edges.
506
386
  * @remarks Time O(deg_in), Space O(deg_in)
507
-
508
-
509
-
510
-
511
-
512
-
513
-
514
-
515
-
516
-
517
-
518
-
519
-
520
-
521
-
522
-
523
-
524
-
525
-
526
-
527
-
528
-
529
-
530
-
531
-
532
-
533
-
534
-
535
-
536
-
537
-
538
-
539
-
540
-
541
-
542
-
543
- * @example
544
- * // Get incoming edges
545
- * const g = new DirectedGraph();
546
- * g.addVertex('A');
547
- * g.addVertex('B');
548
- * g.addVertex('C');
549
- * g.addEdge('A', 'C');
550
- * g.addEdge('B', 'C');
551
- * console.log(g.incomingEdgesOf('C').length); // 2;
387
+ * @example
388
+ * // Get incoming edges
389
+ * const g = new DirectedGraph();
390
+ * g.addVertex('A');
391
+ * g.addVertex('B');
392
+ * g.addVertex('C');
393
+ * g.addEdge('A', 'C');
394
+ * g.addEdge('B', 'C');
395
+ * console.log(g.incomingEdgesOf('C').length); // 2;
552
396
  */
553
397
  incomingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
554
398
  const target = this._getVertex(vertexOrKey);
@@ -563,51 +407,15 @@ export class DirectedGraph<
563
407
  * @param vertexOrKey - Vertex or key.
564
408
  * @returns Array of outgoing edges.
565
409
  * @remarks Time O(deg_out), Space O(deg_out)
566
-
567
-
568
-
569
-
570
-
571
-
572
-
573
-
574
-
575
-
576
-
577
-
578
-
579
-
580
-
581
-
582
-
583
-
584
-
585
-
586
-
587
-
588
-
589
-
590
-
591
-
592
-
593
-
594
-
595
-
596
-
597
-
598
-
599
-
600
-
601
-
602
- * @example
603
- * // Get outgoing edges
604
- * const g = new DirectedGraph();
605
- * g.addVertex('A');
606
- * g.addVertex('B');
607
- * g.addVertex('C');
608
- * g.addEdge('A', 'B');
609
- * g.addEdge('A', 'C');
610
- * console.log(g.outgoingEdgesOf('A').length); // 2;
410
+ * @example
411
+ * // Get outgoing edges
412
+ * const g = new DirectedGraph();
413
+ * g.addVertex('A');
414
+ * g.addVertex('B');
415
+ * g.addVertex('C');
416
+ * g.addEdge('A', 'B');
417
+ * g.addEdge('A', 'C');
418
+ * console.log(g.outgoingEdgesOf('A').length); // 2;
611
419
  */
612
420
  outgoingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
613
421
  const target = this._getVertex(vertexOrKey);
@@ -691,76 +499,35 @@ export class DirectedGraph<
691
499
  * @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
692
500
  * @returns Array of keys/vertices, or `undefined` when cycle is found.
693
501
  * @remarks Time O(V + E), Space O(V)
694
-
695
-
696
-
697
-
698
-
699
-
700
-
701
-
702
-
703
-
704
-
705
-
706
-
707
-
708
-
709
-
710
-
711
-
712
-
713
-
714
-
715
-
716
-
717
-
718
-
719
-
720
-
721
-
722
-
723
-
724
-
725
-
726
-
727
-
728
-
729
-
730
-
731
-
732
-
733
- * @example
734
- * // DirectedGraph topologicalSort for task scheduling
735
- * const graph = new DirectedGraph<string>();
736
- *
737
- * // Build a DAG (Directed Acyclic Graph) for task dependencies
738
- * graph.addVertex('Design');
739
- * graph.addVertex('Implement');
740
- * graph.addVertex('Test');
741
- * graph.addVertex('Deploy');
742
- *
743
- * // Add dependency edges
744
- * graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
745
- * graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
746
- * graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
747
- *
748
- * // Topological sort gives valid execution order
749
- * const executionOrder = graph.topologicalSort();
750
- * console.log(executionOrder); // defined;
751
- * console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
752
- *
753
- * // All vertices should be included
754
- * console.log(executionOrder?.length); // 4;
502
+ * @example
503
+ * // DirectedGraph topologicalSort for task scheduling
504
+ * const graph = new DirectedGraph<string>();
505
+ *
506
+ * // Build a DAG (Directed Acyclic Graph) for task dependencies
507
+ * graph.addVertex('Design');
508
+ * graph.addVertex('Implement');
509
+ * graph.addVertex('Test');
510
+ * graph.addVertex('Deploy');
511
+ *
512
+ * // Add dependency edges
513
+ * graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
514
+ * graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
515
+ * graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
516
+ *
517
+ * // Topological sort gives valid execution order
518
+ * const executionOrder = graph.topologicalSort();
519
+ * console.log(executionOrder); // defined;
520
+ * console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
521
+ *
522
+ * // All vertices should be included
523
+ * console.log(executionOrder?.length); // 4;
755
524
  */
756
525
  topologicalSort(propertyName?: 'vertex' | 'key'): Array<VO | VertexKey> | undefined {
757
526
  propertyName = propertyName ?? 'key';
758
-
759
527
  const statusMap: Map<VO | VertexKey, TopologicalStatus> = new Map<VO | VertexKey, TopologicalStatus>();
760
528
  for (const entry of this.vertexMap) {
761
529
  statusMap.set(entry[1], 0);
762
530
  }
763
-
764
531
  let sorted: (VO | VertexKey)[] = [];
765
532
  let hasCycle = false;
766
533
  const dfs = (cur: VO | VertexKey) => {
@@ -777,64 +544,25 @@ export class DirectedGraph<
777
544
  statusMap.set(cur, 2);
778
545
  sorted.push(cur);
779
546
  };
780
-
781
547
  for (const entry of this.vertexMap) {
782
548
  if (statusMap.get(entry[1]) === 0) {
783
549
  dfs(entry[1]);
784
550
  }
785
551
  }
786
-
787
552
  if (hasCycle) return undefined;
788
-
789
553
  if (propertyName === 'key') sorted = sorted.map(vertex => (vertex instanceof DirectedVertex ? vertex.key : vertex));
790
554
  return sorted.reverse();
791
555
  }
792
556
 
793
- /**
557
+ /**
794
558
  * Get all edges
795
-
796
-
797
-
798
-
799
-
800
-
801
-
802
-
803
-
804
-
805
-
806
-
807
-
808
-
809
-
810
-
811
-
812
-
813
-
814
-
815
-
816
-
817
-
818
-
819
-
820
-
821
-
822
-
823
-
824
-
825
-
826
-
827
-
828
-
829
-
830
-
831
- * @example
832
- * // Get all edges
833
- * const g = new DirectedGraph();
834
- * g.addVertex('A');
835
- * g.addVertex('B');
836
- * g.addEdge('A', 'B', 3);
837
- * console.log(g.edgeSet().length); // 1;
559
+ * @example
560
+ * // Get all edges
561
+ * const g = new DirectedGraph();
562
+ * g.addVertex('A');
563
+ * g.addVertex('B');
564
+ * g.addEdge('A', 'B', 3);
565
+ * console.log(g.edgeSet().length); // 1;
838
566
  */
839
567
  edgeSet(): EO[] {
840
568
  let edgeMap: EO[] = [];
@@ -844,55 +572,18 @@ export class DirectedGraph<
844
572
  return edgeMap;
845
573
  }
846
574
 
847
- /**
575
+ /**
848
576
  * Get outgoing neighbors
849
-
850
-
851
-
852
-
853
-
854
-
855
-
856
-
857
-
858
-
859
-
860
-
861
-
862
-
863
-
864
-
865
-
866
-
867
-
868
-
869
-
870
-
871
-
872
-
873
-
874
-
875
-
876
-
877
-
878
-
879
-
880
-
881
-
882
-
883
-
884
-
885
-
886
- * @example
887
- * // Get outgoing neighbors
888
- * const g = new DirectedGraph();
889
- * g.addVertex('A');
890
- * g.addVertex('B');
891
- * g.addVertex('C');
892
- * g.addEdge('A', 'B');
893
- * g.addEdge('A', 'C');
894
- * const neighbors = g.getNeighbors('A');
895
- * console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
577
+ * @example
578
+ * // Get outgoing neighbors
579
+ * const g = new DirectedGraph();
580
+ * g.addVertex('A');
581
+ * g.addVertex('B');
582
+ * g.addVertex('C');
583
+ * g.addEdge('A', 'B');
584
+ * g.addEdge('A', 'C');
585
+ * const neighbors = g.getNeighbors('A');
586
+ * console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
896
587
  */
897
588
  getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
898
589
  const neighbors: VO[] = [];
@@ -901,7 +592,6 @@ export class DirectedGraph<
901
592
  const outEdges = this.outgoingEdgesOf(vertex);
902
593
  for (const outEdge of outEdges) {
903
594
  const neighbor = this._getVertex(outEdge.dest);
904
-
905
595
  if (neighbor) {
906
596
  neighbors.push(neighbor);
907
597
  }
@@ -960,74 +650,33 @@ export class DirectedGraph<
960
650
  * Tarjan's algorithm for strongly connected components.
961
651
  * @returns `{ dfnMap, lowMap, SCCs }`.
962
652
  * @remarks Time O(V + E), Space O(V + E)
963
-
964
-
965
-
966
-
967
-
968
-
969
-
970
-
971
-
972
-
973
-
974
-
975
-
976
-
977
-
978
-
979
-
980
-
981
-
982
-
983
-
984
-
985
-
986
-
987
-
988
-
989
-
990
-
991
-
992
-
993
-
994
-
995
-
996
-
997
-
998
-
999
- * @example
1000
- * // Find strongly connected components
1001
- * const g = new DirectedGraph();
1002
- * g.addVertex('A');
1003
- * g.addVertex('B');
1004
- * g.addVertex('C');
1005
- * g.addEdge('A', 'B');
1006
- * g.addEdge('B', 'C');
1007
- * g.addEdge('C', 'A');
1008
- * const { SCCs } = g.tarjan();
1009
- * // A→B→C→A forms one SCC with 3 members
1010
- * const sccArrays = [...SCCs.values()];
1011
- * console.log(sccArrays.some(scc => scc.length === 3)); // true;
653
+ * @example
654
+ * // Find strongly connected components
655
+ * const g = new DirectedGraph();
656
+ * g.addVertex('A');
657
+ * g.addVertex('B');
658
+ * g.addVertex('C');
659
+ * g.addEdge('A', 'B');
660
+ * g.addEdge('B', 'C');
661
+ * g.addEdge('C', 'A');
662
+ * const { SCCs } = g.tarjan();
663
+ * // A→B→C→A forms one SCC with 3 members
664
+ * const sccArrays = [...SCCs.values()];
665
+ * console.log(sccArrays.some(scc => scc.length === 3)); // true;
1012
666
  */
1013
667
  tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; SCCs: Map<number, VO[]> } {
1014
668
  const dfnMap = new Map<VO, number>();
1015
669
  const lowMap = new Map<VO, number>();
1016
670
  const SCCs = new Map<number, VO[]>();
1017
-
1018
671
  let time = 0;
1019
-
1020
672
  const stack: VO[] = [];
1021
673
  const inStack: Set<VO> = new Set();
1022
-
1023
674
  const dfs = (vertex: VO) => {
1024
675
  dfnMap.set(vertex, time);
1025
676
  lowMap.set(vertex, time);
1026
677
  time++;
1027
-
1028
678
  stack.push(vertex);
1029
679
  inStack.add(vertex);
1030
-
1031
680
  const neighbors = this.getNeighbors(vertex);
1032
681
  for (const neighbor of neighbors) {
1033
682
  if (!dfnMap.has(neighbor)) {
@@ -1037,27 +686,22 @@ export class DirectedGraph<
1037
686
  lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));
1038
687
  }
1039
688
  }
1040
-
1041
689
  if (dfnMap.get(vertex) === lowMap.get(vertex)) {
1042
690
  const SCC: VO[] = [];
1043
691
  let poppedVertex: VO | undefined;
1044
-
1045
692
  do {
1046
693
  poppedVertex = stack.pop();
1047
694
  inStack.delete(poppedVertex!);
1048
695
  SCC.push(poppedVertex!);
1049
696
  } while (poppedVertex !== vertex);
1050
-
1051
697
  SCCs.set(SCCs.size, SCC);
1052
698
  }
1053
699
  };
1054
-
1055
700
  for (const vertex of this.vertexMap.values()) {
1056
701
  if (!dfnMap.has(vertex)) {
1057
702
  dfs(vertex);
1058
703
  }
1059
704
  }
1060
-
1061
705
  return { dfnMap, lowMap, SCCs };
1062
706
  }
1063
707
 
@@ -1083,53 +727,17 @@ export class DirectedGraph<
1083
727
  * Strongly connected components computed by `tarjan()`.
1084
728
  * @returns Map from SCC id to vertices.
1085
729
  * @remarks Time O(#SCC + V), Space O(V)
1086
-
1087
-
1088
-
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
-
1096
-
1097
-
1098
-
1099
-
1100
-
1101
-
1102
-
1103
-
1104
-
1105
-
1106
-
1107
-
1108
-
1109
-
1110
-
1111
-
1112
-
1113
-
1114
-
1115
-
1116
-
1117
-
1118
-
1119
-
1120
-
1121
-
1122
- * @example
1123
- * // Get strongly connected components
1124
- * const g = new DirectedGraph();
1125
- * g.addVertex(1);
1126
- * g.addVertex(2);
1127
- * g.addVertex(3);
1128
- * g.addEdge(1, 2);
1129
- * g.addEdge(2, 3);
1130
- * g.addEdge(3, 1);
1131
- * const sccs = g.getSCCs(); // Map<number, VO[]>
1132
- * console.log(sccs.size); // >= 1;
730
+ * @example
731
+ * // Get strongly connected components
732
+ * const g = new DirectedGraph();
733
+ * g.addVertex(1);
734
+ * g.addVertex(2);
735
+ * g.addVertex(3);
736
+ * g.addEdge(1, 2);
737
+ * g.addEdge(2, 3);
738
+ * g.addEdge(3, 1);
739
+ * const sccs = g.getSCCs(); // Map<number, VO[]>
740
+ * console.log(sccs.size); // >= 1;
1133
741
  */
1134
742
  getSCCs(): Map<number, VO[]> {
1135
743
  return this.tarjan().SCCs;
@@ -1145,10 +753,8 @@ export class DirectedGraph<
1145
753
  if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {
1146
754
  return false;
1147
755
  }
1148
-
1149
756
  const srcVertex = this._getVertex(edge.src);
1150
757
  const destVertex = this._getVertex(edge.dest);
1151
-
1152
758
  if (srcVertex && destVertex) {
1153
759
  const srcOutEdges = this._outEdgeMap.get(srcVertex);
1154
760
  if (srcOutEdges) {
@@ -1156,7 +762,6 @@ export class DirectedGraph<
1156
762
  } else {
1157
763
  this._outEdgeMap.set(srcVertex, [edge]);
1158
764
  }
1159
-
1160
765
  const destInEdges = this._inEdgeMap.get(destVertex);
1161
766
  if (destInEdges) {
1162
767
  destInEdges.push(edge);