data-structure-typed 2.6.0 → 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 (80) hide show
  1. package/.github/workflows/ci.yml +7 -2
  2. package/.github/workflows/release-package.yml +9 -2
  3. package/docs-site-docusaurus/docs/api/classes/AVLTree.md +108 -108
  4. package/docs-site-docusaurus/docs/api/classes/BST.md +101 -101
  5. package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +13 -13
  6. package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +66 -66
  7. package/docs-site-docusaurus/docs/api/classes/Deque.md +235 -51
  8. package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +21 -21
  9. package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +231 -67
  10. package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +9 -9
  11. package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
  12. package/docs-site-docusaurus/docs/api/classes/HashMap.md +14 -14
  13. package/docs-site-docusaurus/docs/api/classes/Heap.md +117 -34
  14. package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +83 -13
  15. package/docs-site-docusaurus/docs/api/classes/LinearBase.md +124 -20
  16. package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +140 -32
  17. package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +23 -23
  18. package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +159 -51
  19. package/docs-site-docusaurus/docs/api/classes/MapGraph.md +20 -20
  20. package/docs-site-docusaurus/docs/api/classes/Matrix.md +23 -23
  21. package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +117 -34
  22. package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +117 -34
  23. package/docs-site-docusaurus/docs/api/classes/MinHeap.md +117 -34
  24. package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +117 -34
  25. package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +117 -34
  26. package/docs-site-docusaurus/docs/api/classes/Queue.md +142 -34
  27. package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +117 -117
  28. package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +8 -8
  29. package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +158 -50
  30. package/docs-site-docusaurus/docs/api/classes/SkipList.md +21 -21
  31. package/docs-site-docusaurus/docs/api/classes/Stack.md +108 -26
  32. package/docs-site-docusaurus/docs/api/classes/TreeMap.md +33 -33
  33. package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +75 -39
  34. package/docs-site-docusaurus/docs/api/classes/TreeSet.md +301 -39
  35. package/docs-site-docusaurus/docs/api/classes/Trie.md +110 -28
  36. package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +20 -20
  37. package/package.json +45 -46
  38. package/src/common/error.ts +15 -32
  39. package/src/common/index.ts +0 -3
  40. package/src/data-structures/base/iterable-element-base.ts +0 -3
  41. package/src/data-structures/base/linear-base.ts +2 -36
  42. package/src/data-structures/binary-tree/avl-tree.ts +31 -529
  43. package/src/data-structures/binary-tree/binary-indexed-tree.ts +47 -572
  44. package/src/data-structures/binary-tree/binary-tree.ts +326 -1311
  45. package/src/data-structures/binary-tree/bst.ts +158 -1082
  46. package/src/data-structures/binary-tree/red-black-tree.ts +451 -1290
  47. package/src/data-structures/binary-tree/segment-tree.ts +73 -351
  48. package/src/data-structures/binary-tree/tree-map.ts +462 -5124
  49. package/src/data-structures/binary-tree/tree-multi-map.ts +302 -4914
  50. package/src/data-structures/binary-tree/tree-multi-set.ts +284 -3972
  51. package/src/data-structures/binary-tree/tree-set.ts +338 -4836
  52. package/src/data-structures/graph/abstract-graph.ts +98 -167
  53. package/src/data-structures/graph/directed-graph.ts +137 -562
  54. package/src/data-structures/graph/map-graph.ts +0 -3
  55. package/src/data-structures/graph/undirected-graph.ts +132 -511
  56. package/src/data-structures/hash/hash-map.ts +154 -582
  57. package/src/data-structures/heap/heap.ts +200 -795
  58. package/src/data-structures/linked-list/doubly-linked-list.ts +121 -865
  59. package/src/data-structures/linked-list/singly-linked-list.ts +122 -794
  60. package/src/data-structures/linked-list/skip-linked-list.ts +211 -918
  61. package/src/data-structures/matrix/matrix.ts +179 -518
  62. package/src/data-structures/matrix/navigator.ts +0 -1
  63. package/src/data-structures/priority-queue/max-priority-queue.ts +1 -6
  64. package/src/data-structures/priority-queue/min-priority-queue.ts +6 -11
  65. package/src/data-structures/priority-queue/priority-queue.ts +1 -2
  66. package/src/data-structures/queue/deque.ts +214 -882
  67. package/src/data-structures/queue/queue.ts +102 -625
  68. package/src/data-structures/stack/stack.ts +76 -505
  69. package/src/data-structures/trie/trie.ts +98 -628
  70. package/src/types/common.ts +0 -10
  71. package/src/types/data-structures/binary-tree/bst.ts +0 -7
  72. package/src/types/data-structures/binary-tree/red-black-tree.ts +0 -1
  73. package/src/types/data-structures/graph/abstract-graph.ts +0 -2
  74. package/src/types/data-structures/hash/hash-map.ts +0 -3
  75. package/src/types/data-structures/hash/index.ts +0 -1
  76. package/src/types/data-structures/matrix/navigator.ts +0 -2
  77. package/src/types/utils/utils.ts +0 -7
  78. package/src/types/utils/validate-type.ts +0 -7
  79. package/src/utils/number.ts +0 -2
  80. 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,61 +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
-
257
-
258
-
259
- * @example
260
- * // Get edge between vertices
261
- * const g = new DirectedGraph();
262
- * g.addVertex('A');
263
- * g.addVertex('B');
264
- * g.addEdge('A', 'B', 5);
265
- * const edge = g.getEdge('A', 'B');
266
- * 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;
267
232
  */
268
233
  getEdge(srcOrKey: VO | VertexKey | undefined, destOrKey: VO | VertexKey | undefined): EO | undefined {
269
234
  let edgeMap: EO[] = [];
270
-
271
235
  if (srcOrKey !== undefined && destOrKey !== undefined) {
272
236
  const src: VO | undefined = this._getVertex(srcOrKey);
273
237
  const dest: VO | undefined = this._getVertex(destOrKey);
274
-
275
238
  if (src && dest) {
276
239
  const srcOutEdges = this._outEdgeMap.get(src);
277
240
  if (srcOutEdges) {
@@ -279,7 +242,6 @@ export class DirectedGraph<
279
242
  }
280
243
  }
281
244
  }
282
-
283
245
  return edgeMap[0] || undefined;
284
246
  }
285
247
 
@@ -297,12 +259,10 @@ export class DirectedGraph<
297
259
  if (!src || !dest) {
298
260
  return undefined;
299
261
  }
300
-
301
262
  const srcOutEdges = this._outEdgeMap.get(src);
302
263
  if (srcOutEdges) {
303
264
  arrayRemove<EO>(srcOutEdges, (edge: EO) => edge.dest === dest.key);
304
265
  }
305
-
306
266
  const destInEdges = this._inEdgeMap.get(dest);
307
267
  if (destInEdges) {
308
268
  removed = arrayRemove<EO>(destInEdges, (edge: EO) => edge.src === src.key)[0] || undefined;
@@ -316,73 +276,31 @@ export class DirectedGraph<
316
276
  * @param destVertexKey - Optional destination vertex/key when deleting by pair.
317
277
  * @returns Removed edge or `undefined`.
318
278
  * @remarks Time O(1) avg, Space O(1)
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
-
356
-
357
-
358
-
359
-
360
-
361
- * @example
362
- * // DirectedGraph deleteEdge and vertex operations
363
- * const graph = new DirectedGraph<string>();
364
- *
365
- * // Build a small graph
366
- * graph.addVertex('X');
367
- * graph.addVertex('Y');
368
- * graph.addVertex('Z');
369
- * graph.addEdge('X', 'Y', 1);
370
- * graph.addEdge('Y', 'Z', 2);
371
- *
372
- * // Delete an edge
373
- * graph.deleteEdgeSrcToDest('X', 'Y');
374
- * console.log(graph.hasEdge('X', 'Y')); // false;
375
- *
376
- * // Edge in other direction should not exist
377
- * console.log(graph.hasEdge('Y', 'X')); // false;
378
- *
379
- * // Other edges should remain
380
- * console.log(graph.hasEdge('Y', 'Z')); // true;
381
- *
382
- * // Delete a vertex
383
- * graph.deleteVertex('Y');
384
- * console.log(graph.hasVertex('Y')); // false;
385
- * 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;
386
304
  */
387
305
  deleteEdge(edgeOrSrcVertexKey: EO | VertexKey, destVertexKey?: VertexKey): EO | undefined {
388
306
  let removed: EO | undefined = undefined;
@@ -398,72 +316,30 @@ export class DirectedGraph<
398
316
  src = this._getVertex(edgeOrSrcVertexKey.src);
399
317
  dest = this._getVertex(edgeOrSrcVertexKey.dest);
400
318
  }
401
-
402
319
  if (src && dest) {
403
320
  const srcOutEdges = this._outEdgeMap.get(src);
404
321
  if (srcOutEdges && srcOutEdges.length > 0) {
405
322
  arrayRemove(srcOutEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest?.key);
406
323
  }
407
-
408
324
  const destInEdges = this._inEdgeMap.get(dest);
409
325
  if (destInEdges && destInEdges.length > 0) {
410
326
  removed = arrayRemove(destInEdges, (edge: EO) => edge.src === src!.key && edge.dest === dest!.key)[0];
411
327
  }
412
328
  }
413
-
414
329
  return removed;
415
330
  }
416
331
 
417
- /**
332
+ /**
418
333
  * Remove a vertex
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
-
450
-
451
-
452
-
453
-
454
-
455
-
456
-
457
-
458
- * @example
459
- * // Remove a vertex
460
- * const g = new DirectedGraph();
461
- * g.addVertex('A');
462
- * g.addVertex('B');
463
- * g.addEdge('A', 'B');
464
- * g.deleteVertex('A');
465
- * console.log(g.hasVertex('A')); // false;
466
- * 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;
467
343
  */
468
344
  deleteVertex(vertexOrKey: VO | VertexKey): boolean {
469
345
  let vertexKey: VertexKey;
@@ -475,7 +351,6 @@ export class DirectedGraph<
475
351
  vertex = vertexOrKey;
476
352
  vertexKey = this._getVertexKey(vertexOrKey);
477
353
  }
478
-
479
354
  if (vertex) {
480
355
  /**
481
356
  * One-step neighbors following outgoing edges.
@@ -490,21 +365,17 @@ export class DirectedGraph<
490
365
  this._outEdgeMap.delete(vertex);
491
366
  this._inEdgeMap.delete(vertex);
492
367
  }
493
-
494
368
  return this._vertexMap.delete(vertexKey);
495
369
  }
496
370
 
497
371
  deleteEdgesBetween(v1: VertexKey | VO, v2: VertexKey | VO): EO[] {
498
372
  const removed: EO[] = [];
499
-
500
373
  if (v1 && v2) {
501
374
  const v1ToV2 = this.deleteEdgeSrcToDest(v1, v2);
502
375
  const v2ToV1 = this.deleteEdgeSrcToDest(v2, v1);
503
-
504
376
  if (v1ToV2) removed.push(v1ToV2);
505
377
  if (v2ToV1) removed.push(v2ToV1);
506
378
  }
507
-
508
379
  return removed;
509
380
  }
510
381
 
@@ -513,54 +384,15 @@ export class DirectedGraph<
513
384
  * @param vertexOrKey - Vertex or key.
514
385
  * @returns Array of incoming edges.
515
386
  * @remarks Time O(deg_in), Space O(deg_in)
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
-
544
-
545
-
546
-
547
-
548
-
549
-
550
-
551
-
552
-
553
-
554
-
555
- * @example
556
- * // Get incoming edges
557
- * const g = new DirectedGraph();
558
- * g.addVertex('A');
559
- * g.addVertex('B');
560
- * g.addVertex('C');
561
- * g.addEdge('A', 'C');
562
- * g.addEdge('B', 'C');
563
- * 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;
564
396
  */
565
397
  incomingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
566
398
  const target = this._getVertex(vertexOrKey);
@@ -575,54 +407,15 @@ export class DirectedGraph<
575
407
  * @param vertexOrKey - Vertex or key.
576
408
  * @returns Array of outgoing edges.
577
409
  * @remarks Time O(deg_out), Space O(deg_out)
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
-
603
-
604
-
605
-
606
-
607
-
608
-
609
-
610
-
611
-
612
-
613
-
614
-
615
-
616
-
617
- * @example
618
- * // Get outgoing edges
619
- * const g = new DirectedGraph();
620
- * g.addVertex('A');
621
- * g.addVertex('B');
622
- * g.addVertex('C');
623
- * g.addEdge('A', 'B');
624
- * g.addEdge('A', 'C');
625
- * 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;
626
419
  */
627
420
  outgoingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
628
421
  const target = this._getVertex(vertexOrKey);
@@ -706,79 +499,35 @@ export class DirectedGraph<
706
499
  * @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
707
500
  * @returns Array of keys/vertices, or `undefined` when cycle is found.
708
501
  * @remarks Time O(V + E), Space O(V)
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
-
734
-
735
-
736
-
737
-
738
-
739
-
740
-
741
-
742
-
743
-
744
-
745
-
746
-
747
-
748
-
749
-
750
-
751
- * @example
752
- * // DirectedGraph topologicalSort for task scheduling
753
- * const graph = new DirectedGraph<string>();
754
- *
755
- * // Build a DAG (Directed Acyclic Graph) for task dependencies
756
- * graph.addVertex('Design');
757
- * graph.addVertex('Implement');
758
- * graph.addVertex('Test');
759
- * graph.addVertex('Deploy');
760
- *
761
- * // Add dependency edges
762
- * graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
763
- * graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
764
- * graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
765
- *
766
- * // Topological sort gives valid execution order
767
- * const executionOrder = graph.topologicalSort();
768
- * console.log(executionOrder); // defined;
769
- * console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
770
- *
771
- * // All vertices should be included
772
- * 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;
773
524
  */
774
525
  topologicalSort(propertyName?: 'vertex' | 'key'): Array<VO | VertexKey> | undefined {
775
526
  propertyName = propertyName ?? 'key';
776
-
777
527
  const statusMap: Map<VO | VertexKey, TopologicalStatus> = new Map<VO | VertexKey, TopologicalStatus>();
778
528
  for (const entry of this.vertexMap) {
779
529
  statusMap.set(entry[1], 0);
780
530
  }
781
-
782
531
  let sorted: (VO | VertexKey)[] = [];
783
532
  let hasCycle = false;
784
533
  const dfs = (cur: VO | VertexKey) => {
@@ -795,67 +544,25 @@ export class DirectedGraph<
795
544
  statusMap.set(cur, 2);
796
545
  sorted.push(cur);
797
546
  };
798
-
799
547
  for (const entry of this.vertexMap) {
800
548
  if (statusMap.get(entry[1]) === 0) {
801
549
  dfs(entry[1]);
802
550
  }
803
551
  }
804
-
805
552
  if (hasCycle) return undefined;
806
-
807
553
  if (propertyName === 'key') sorted = sorted.map(vertex => (vertex instanceof DirectedVertex ? vertex.key : vertex));
808
554
  return sorted.reverse();
809
555
  }
810
556
 
811
- /**
557
+ /**
812
558
  * Get all edges
813
-
814
-
815
-
816
-
817
-
818
-
819
-
820
-
821
-
822
-
823
-
824
-
825
-
826
-
827
-
828
-
829
-
830
-
831
-
832
-
833
-
834
-
835
-
836
-
837
-
838
-
839
-
840
-
841
-
842
-
843
-
844
-
845
-
846
-
847
-
848
-
849
-
850
-
851
-
852
- * @example
853
- * // Get all edges
854
- * const g = new DirectedGraph();
855
- * g.addVertex('A');
856
- * g.addVertex('B');
857
- * g.addEdge('A', 'B', 3);
858
- * 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;
859
566
  */
860
567
  edgeSet(): EO[] {
861
568
  let edgeMap: EO[] = [];
@@ -865,58 +572,18 @@ export class DirectedGraph<
865
572
  return edgeMap;
866
573
  }
867
574
 
868
- /**
575
+ /**
869
576
  * Get outgoing neighbors
870
-
871
-
872
-
873
-
874
-
875
-
876
-
877
-
878
-
879
-
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
-
889
-
890
-
891
-
892
-
893
-
894
-
895
-
896
-
897
-
898
-
899
-
900
-
901
-
902
-
903
-
904
-
905
-
906
-
907
-
908
-
909
-
910
- * @example
911
- * // Get outgoing neighbors
912
- * const g = new DirectedGraph();
913
- * g.addVertex('A');
914
- * g.addVertex('B');
915
- * g.addVertex('C');
916
- * g.addEdge('A', 'B');
917
- * g.addEdge('A', 'C');
918
- * const neighbors = g.getNeighbors('A');
919
- * 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'];
920
587
  */
921
588
  getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
922
589
  const neighbors: VO[] = [];
@@ -925,7 +592,6 @@ export class DirectedGraph<
925
592
  const outEdges = this.outgoingEdgesOf(vertex);
926
593
  for (const outEdge of outEdges) {
927
594
  const neighbor = this._getVertex(outEdge.dest);
928
-
929
595
  if (neighbor) {
930
596
  neighbors.push(neighbor);
931
597
  }
@@ -984,77 +650,33 @@ export class DirectedGraph<
984
650
  * Tarjan's algorithm for strongly connected components.
985
651
  * @returns `{ dfnMap, lowMap, SCCs }`.
986
652
  * @remarks Time O(V + E), Space O(V + E)
987
-
988
-
989
-
990
-
991
-
992
-
993
-
994
-
995
-
996
-
997
-
998
-
999
-
1000
-
1001
-
1002
-
1003
-
1004
-
1005
-
1006
-
1007
-
1008
-
1009
-
1010
-
1011
-
1012
-
1013
-
1014
-
1015
-
1016
-
1017
-
1018
-
1019
-
1020
-
1021
-
1022
-
1023
-
1024
-
1025
-
1026
- * @example
1027
- * // Find strongly connected components
1028
- * const g = new DirectedGraph();
1029
- * g.addVertex('A');
1030
- * g.addVertex('B');
1031
- * g.addVertex('C');
1032
- * g.addEdge('A', 'B');
1033
- * g.addEdge('B', 'C');
1034
- * g.addEdge('C', 'A');
1035
- * const { SCCs } = g.tarjan();
1036
- * // A→B→C→A forms one SCC with 3 members
1037
- * const sccArrays = [...SCCs.values()];
1038
- * 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;
1039
666
  */
1040
667
  tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; SCCs: Map<number, VO[]> } {
1041
668
  const dfnMap = new Map<VO, number>();
1042
669
  const lowMap = new Map<VO, number>();
1043
670
  const SCCs = new Map<number, VO[]>();
1044
-
1045
671
  let time = 0;
1046
-
1047
672
  const stack: VO[] = [];
1048
673
  const inStack: Set<VO> = new Set();
1049
-
1050
674
  const dfs = (vertex: VO) => {
1051
675
  dfnMap.set(vertex, time);
1052
676
  lowMap.set(vertex, time);
1053
677
  time++;
1054
-
1055
678
  stack.push(vertex);
1056
679
  inStack.add(vertex);
1057
-
1058
680
  const neighbors = this.getNeighbors(vertex);
1059
681
  for (const neighbor of neighbors) {
1060
682
  if (!dfnMap.has(neighbor)) {
@@ -1064,27 +686,22 @@ export class DirectedGraph<
1064
686
  lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));
1065
687
  }
1066
688
  }
1067
-
1068
689
  if (dfnMap.get(vertex) === lowMap.get(vertex)) {
1069
690
  const SCC: VO[] = [];
1070
691
  let poppedVertex: VO | undefined;
1071
-
1072
692
  do {
1073
693
  poppedVertex = stack.pop();
1074
694
  inStack.delete(poppedVertex!);
1075
695
  SCC.push(poppedVertex!);
1076
696
  } while (poppedVertex !== vertex);
1077
-
1078
697
  SCCs.set(SCCs.size, SCC);
1079
698
  }
1080
699
  };
1081
-
1082
700
  for (const vertex of this.vertexMap.values()) {
1083
701
  if (!dfnMap.has(vertex)) {
1084
702
  dfs(vertex);
1085
703
  }
1086
704
  }
1087
-
1088
705
  return { dfnMap, lowMap, SCCs };
1089
706
  }
1090
707
 
@@ -1110,56 +727,17 @@ export class DirectedGraph<
1110
727
  * Strongly connected components computed by `tarjan()`.
1111
728
  * @returns Map from SCC id to vertices.
1112
729
  * @remarks Time O(#SCC + V), Space O(V)
1113
-
1114
-
1115
-
1116
-
1117
-
1118
-
1119
-
1120
-
1121
-
1122
-
1123
-
1124
-
1125
-
1126
-
1127
-
1128
-
1129
-
1130
-
1131
-
1132
-
1133
-
1134
-
1135
-
1136
-
1137
-
1138
-
1139
-
1140
-
1141
-
1142
-
1143
-
1144
-
1145
-
1146
-
1147
-
1148
-
1149
-
1150
-
1151
-
1152
- * @example
1153
- * // Get strongly connected components
1154
- * const g = new DirectedGraph();
1155
- * g.addVertex(1);
1156
- * g.addVertex(2);
1157
- * g.addVertex(3);
1158
- * g.addEdge(1, 2);
1159
- * g.addEdge(2, 3);
1160
- * g.addEdge(3, 1);
1161
- * const sccs = g.getSCCs(); // Map<number, VO[]>
1162
- * 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;
1163
741
  */
1164
742
  getSCCs(): Map<number, VO[]> {
1165
743
  return this.tarjan().SCCs;
@@ -1175,10 +753,8 @@ export class DirectedGraph<
1175
753
  if (!(this.hasVertex(edge.src) && this.hasVertex(edge.dest))) {
1176
754
  return false;
1177
755
  }
1178
-
1179
756
  const srcVertex = this._getVertex(edge.src);
1180
757
  const destVertex = this._getVertex(edge.dest);
1181
-
1182
758
  if (srcVertex && destVertex) {
1183
759
  const srcOutEdges = this._outEdgeMap.get(srcVertex);
1184
760
  if (srcOutEdges) {
@@ -1186,7 +762,6 @@ export class DirectedGraph<
1186
762
  } else {
1187
763
  this._outEdgeMap.set(srcVertex, [edge]);
1188
764
  }
1189
-
1190
765
  const destInEdges = this._inEdgeMap.get(destVertex);
1191
766
  if (destInEdges) {
1192
767
  destInEdges.push(edge);