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, VertexKey } from '../../types';
10
9
  import { IGraph } from '../../interfaces';
11
10
  import { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';
@@ -155,7 +154,6 @@ export class UndirectedGraph<
155
154
  }
156
155
 
157
156
  protected _edgeMap: Map<VO, EO[]>;
158
-
159
157
  get edgeMap(): Map<VO, EO[]> {
160
158
  return this._edgeMap;
161
159
  }
@@ -174,7 +172,10 @@ export class UndirectedGraph<
174
172
  static fromKeys<K extends VertexKey>(
175
173
  keys: Iterable<K>
176
174
  ): UndirectedGraph<K, undefined, UndirectedVertex<K>, UndirectedEdge<undefined>> {
177
- const g: UndirectedGraph<K, undefined, UndirectedVertex<K>, UndirectedEdge<undefined>> = new UndirectedGraph<K, undefined>({
175
+ const g: UndirectedGraph<K, undefined, UndirectedVertex<K>, UndirectedEdge<undefined>> = new UndirectedGraph<
176
+ K,
177
+ undefined
178
+ >({
178
179
  vertexValueInitializer: (k: VertexKey) => k as K
179
180
  });
180
181
  for (const k of keys) g.addVertex(k);
@@ -191,7 +192,10 @@ export class UndirectedGraph<
191
192
  static fromEntries<V>(
192
193
  entries: Iterable<[VertexKey, V]>
193
194
  ): UndirectedGraph<V, undefined, UndirectedVertex<V>, UndirectedEdge<undefined>> {
194
- const g: UndirectedGraph<V, undefined, UndirectedVertex<V>, UndirectedEdge<undefined>> = new UndirectedGraph<V, undefined>();
195
+ const g: UndirectedGraph<V, undefined, UndirectedVertex<V>, UndirectedEdge<undefined>> = new UndirectedGraph<
196
+ V,
197
+ undefined
198
+ >();
195
199
  for (const [k, v] of entries) g.addVertex(k, v);
196
200
  return g;
197
201
  }
@@ -226,62 +230,23 @@ export class UndirectedGraph<
226
230
  * @param v2 - The other vertex or key.
227
231
  * @returns Edge instance or `undefined`.
228
232
  * @remarks Time O(1) avg, Space O(1)
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
-
260
-
261
-
262
-
263
-
264
-
265
- * @example
266
- * // Get edge between vertices
267
- * const g = new UndirectedGraph();
268
- * g.addVertex('A');
269
- * g.addVertex('B');
270
- * g.addEdge('A', 'B', 7);
271
- * console.log(g.getEdge('A', 'B')?.weight); // 7;
233
+ * @example
234
+ * // Get edge between vertices
235
+ * const g = new UndirectedGraph();
236
+ * g.addVertex('A');
237
+ * g.addVertex('B');
238
+ * g.addEdge('A', 'B', 7);
239
+ * console.log(g.getEdge('A', 'B')?.weight); // 7;
272
240
  */
273
241
  getEdge(v1: VO | VertexKey | undefined, v2: VO | VertexKey | undefined): EO | undefined {
274
242
  let edgeMap: EO[] | undefined = [];
275
-
276
243
  if (v1 !== undefined && v2 !== undefined) {
277
244
  const vertex1: VO | undefined = this._getVertex(v1);
278
245
  const vertex2: VO | undefined = this._getVertex(v2);
279
-
280
246
  if (vertex1 && vertex2) {
281
247
  edgeMap = this._edgeMap.get(vertex1)?.filter(e => e.endpoints.includes(vertex2.key));
282
248
  }
283
249
  }
284
-
285
250
  return edgeMap ? edgeMap[0] || undefined : undefined;
286
251
  }
287
252
 
@@ -295,11 +260,9 @@ export class UndirectedGraph<
295
260
  deleteEdgeBetween(v1: VO | VertexKey, v2: VO | VertexKey): EO | undefined {
296
261
  const vertex1: VO | undefined = this._getVertex(v1);
297
262
  const vertex2: VO | undefined = this._getVertex(v2);
298
-
299
263
  if (!vertex1 || !vertex2) {
300
264
  return undefined;
301
265
  }
302
-
303
266
  const v1Edges = this._edgeMap.get(vertex1);
304
267
  let removed: EO | undefined = undefined;
305
268
  if (v1Edges) {
@@ -318,72 +281,33 @@ export class UndirectedGraph<
318
281
  * @param otherSideVertexKey - Required second endpoint when deleting by pair.
319
282
  * @returns Removed edge or `undefined`.
320
283
  * @remarks Time O(1) avg, Space O(1)
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
- * @example
361
- * // UndirectedGraph deleteEdge and vertex operations
362
- * const graph = new UndirectedGraph<string>();
363
- *
364
- * // Build a simple undirected graph
365
- * graph.addVertex('X');
366
- * graph.addVertex('Y');
367
- * graph.addVertex('Z');
368
- * graph.addEdge('X', 'Y', 1);
369
- * graph.addEdge('Y', 'Z', 2);
370
- * graph.addEdge('X', 'Z', 3);
371
- *
372
- * // Delete an edge
373
- * graph.deleteEdge('X', 'Y');
374
- * console.log(graph.hasEdge('X', 'Y')); // false;
375
- *
376
- * // Bidirectional deletion confirmed
377
- * console.log(graph.hasEdge('Y', 'X')); // false;
378
- *
379
- * // Other edges should remain
380
- * console.log(graph.hasEdge('Y', 'Z')); // true;
381
- * console.log(graph.hasEdge('Z', 'Y')); // true;
382
- *
383
- * // Delete a vertex
384
- * graph.deleteVertex('Y');
385
- * console.log(graph.hasVertex('Y')); // false;
386
- * console.log(graph.size); // 2;
284
+ * @example
285
+ * // UndirectedGraph deleteEdge and vertex operations
286
+ * const graph = new UndirectedGraph<string>();
287
+ *
288
+ * // Build a simple undirected graph
289
+ * graph.addVertex('X');
290
+ * graph.addVertex('Y');
291
+ * graph.addVertex('Z');
292
+ * graph.addEdge('X', 'Y', 1);
293
+ * graph.addEdge('Y', 'Z', 2);
294
+ * graph.addEdge('X', 'Z', 3);
295
+ *
296
+ * // Delete an edge
297
+ * graph.deleteEdge('X', 'Y');
298
+ * console.log(graph.hasEdge('X', 'Y')); // false;
299
+ *
300
+ * // Bidirectional deletion confirmed
301
+ * console.log(graph.hasEdge('Y', 'X')); // false;
302
+ *
303
+ * // Other edges should remain
304
+ * console.log(graph.hasEdge('Y', 'Z')); // true;
305
+ * console.log(graph.hasEdge('Z', 'Y')); // true;
306
+ *
307
+ * // Delete a vertex
308
+ * graph.deleteVertex('Y');
309
+ * console.log(graph.hasVertex('Y')); // false;
310
+ * console.log(graph.size); // 2;
387
311
  */
388
312
  deleteEdge(edgeOrOneSideVertexKey: EO | VertexKey, otherSideVertexKey?: VertexKey): EO | undefined {
389
313
  let oneSide: VO | undefined, otherSide: VO | undefined;
@@ -398,7 +322,6 @@ export class UndirectedGraph<
398
322
  oneSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[0]);
399
323
  otherSide = this._getVertex(edgeOrOneSideVertexKey.endpoints[1]);
400
324
  }
401
-
402
325
  if (oneSide && otherSide) {
403
326
  return this.deleteEdgeBetween(oneSide, otherSide);
404
327
  } else {
@@ -411,50 +334,14 @@ export class UndirectedGraph<
411
334
  * @param vertexOrKey - Vertex or key.
412
335
  * @returns `true` if removed; otherwise `false`.
413
336
  * @remarks Time O(deg), Space O(1)
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
-
450
- * @example
451
- * // Remove vertex and edges
452
- * const g = new UndirectedGraph();
453
- * g.addVertex('A');
454
- * g.addVertex('B');
455
- * g.addEdge('A', 'B');
456
- * g.deleteVertex('A');
457
- * console.log(g.hasVertex('A')); // false;
337
+ * @example
338
+ * // Remove vertex and edges
339
+ * const g = new UndirectedGraph();
340
+ * g.addVertex('A');
341
+ * g.addVertex('B');
342
+ * g.addEdge('A', 'B');
343
+ * g.deleteVertex('A');
344
+ * console.log(g.hasVertex('A')); // false;
458
345
  */
459
346
  deleteVertex(vertexOrKey: VO | VertexKey): boolean {
460
347
  let vertexKey: VertexKey;
@@ -474,7 +361,6 @@ export class UndirectedGraph<
474
361
  * @remarks Time O(deg), Space O(deg)
475
362
  */
476
363
  const neighbors = this.getNeighbors(vertexOrKey);
477
-
478
364
  if (vertex) {
479
365
  neighbors.forEach(neighbor => {
480
366
  const neighborEdges = this._edgeMap.get(neighbor);
@@ -487,7 +373,6 @@ export class UndirectedGraph<
487
373
  });
488
374
  this._edgeMap.delete(vertex);
489
375
  }
490
-
491
376
  return this._vertexMap.delete(vertexKey);
492
377
  }
493
378
 
@@ -525,49 +410,13 @@ export class UndirectedGraph<
525
410
  * Unique set of undirected edges across endpoints.
526
411
  * @returns Array of edges.
527
412
  * @remarks Time O(E), Space O(E)
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
-
556
-
557
-
558
-
559
-
560
-
561
-
562
-
563
-
564
- * @example
565
- * // Get all edges
566
- * const g = new UndirectedGraph();
567
- * g.addVertex('A');
568
- * g.addVertex('B');
569
- * g.addEdge('A', 'B');
570
- * console.log(g.edgeSet().length); // 1;
413
+ * @example
414
+ * // Get all edges
415
+ * const g = new UndirectedGraph();
416
+ * g.addVertex('A');
417
+ * g.addVertex('B');
418
+ * g.addEdge('A', 'B');
419
+ * console.log(g.edgeSet().length); // 1;
571
420
  */
572
421
  edgeSet(): EO[] {
573
422
  const edgeSet: Set<EO> = new Set();
@@ -579,79 +428,40 @@ export class UndirectedGraph<
579
428
  return [...edgeSet];
580
429
  }
581
430
 
582
- /**
431
+ /**
583
432
  * UndirectedGraph connectivity and neighbors
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
-
618
-
619
-
620
-
621
-
622
-
623
- * @example
624
- * // UndirectedGraph connectivity and neighbors
625
- * const graph = new UndirectedGraph<string>();
626
- *
627
- * // Build a friendship network
628
- * const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
629
- * for (const person of people) {
630
- * graph.addVertex(person);
631
- * }
632
- *
633
- * // Add friendships (undirected edges)
634
- * graph.addEdge('Alice', 'Bob', 1);
635
- * graph.addEdge('Alice', 'Charlie', 1);
636
- * graph.addEdge('Bob', 'Diana', 1);
637
- * graph.addEdge('Charlie', 'Eve', 1);
638
- * graph.addEdge('Diana', 'Eve', 1);
639
- *
640
- * // Get friends of each person
641
- * const aliceFriends = graph.getNeighbors('Alice');
642
- * console.log(aliceFriends[0].key); // 'Bob';
643
- * console.log(aliceFriends[1].key); // 'Charlie';
644
- * console.log(aliceFriends.length); // 2;
645
- *
646
- * const dianaFriends = graph.getNeighbors('Diana');
647
- * console.log(dianaFriends[0].key); // 'Bob';
648
- * console.log(dianaFriends[1].key); // 'Eve';
649
- * console.log(dianaFriends.length); // 2;
650
- *
651
- * // Verify bidirectional friendship
652
- * const bobFriends = graph.getNeighbors('Bob');
653
- * console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
654
- * console.log(bobFriends[1].key); // 'Diana';
433
+ * @example
434
+ * // UndirectedGraph connectivity and neighbors
435
+ * const graph = new UndirectedGraph<string>();
436
+ *
437
+ * // Build a friendship network
438
+ * const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
439
+ * for (const person of people) {
440
+ * graph.addVertex(person);
441
+ * }
442
+ *
443
+ * // Add friendships (undirected edges)
444
+ * graph.addEdge('Alice', 'Bob', 1);
445
+ * graph.addEdge('Alice', 'Charlie', 1);
446
+ * graph.addEdge('Bob', 'Diana', 1);
447
+ * graph.addEdge('Charlie', 'Eve', 1);
448
+ * graph.addEdge('Diana', 'Eve', 1);
449
+ *
450
+ * // Get friends of each person
451
+ * const aliceFriends = graph.getNeighbors('Alice');
452
+ * console.log(aliceFriends[0].key); // 'Bob';
453
+ * console.log(aliceFriends[1].key); // 'Charlie';
454
+ * console.log(aliceFriends.length); // 2;
455
+ *
456
+ * const dianaFriends = graph.getNeighbors('Diana');
457
+ * console.log(dianaFriends[0].key); // 'Bob';
458
+ * console.log(dianaFriends[1].key); // 'Eve';
459
+ * console.log(dianaFriends.length); // 2;
460
+ *
461
+ * // Verify bidirectional friendship
462
+ * const bobFriends = graph.getNeighbors('Bob');
463
+ * console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
464
+ * console.log(bobFriends[1].key); // 'Diana';
655
465
  */
656
466
  getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
657
467
  const neighbors: VO[] = [];
@@ -717,75 +527,34 @@ export class UndirectedGraph<
717
527
  * Tarjan-based bridge and articulation point detection.
718
528
  * @returns `{ dfnMap, lowMap, bridges, cutVertices }`.
719
529
  * @remarks Time O(V + E), Space O(V + E)
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
-
752
-
753
-
754
-
755
-
756
- * @example
757
- * // Find articulation points and bridges
758
- * const g = new UndirectedGraph();
759
- * g.addVertex('A');
760
- * g.addVertex('B');
761
- * g.addVertex('C');
762
- * g.addEdge('A', 'B');
763
- * g.addEdge('B', 'C');
764
- * const result = g.tarjan();
765
- * console.log(result); // defined;
530
+ * @example
531
+ * // Find articulation points and bridges
532
+ * const g = new UndirectedGraph();
533
+ * g.addVertex('A');
534
+ * g.addVertex('B');
535
+ * g.addVertex('C');
536
+ * g.addEdge('A', 'B');
537
+ * g.addEdge('B', 'C');
538
+ * const result = g.tarjan();
539
+ * console.log(result); // defined;
766
540
  */
767
541
  tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; bridges: EO[]; cutVertices: VO[] } {
768
542
  const dfnMap = new Map<VO, number>();
769
543
  const lowMap = new Map<VO, number>();
770
544
  const bridges: EO[] = [];
771
545
  const cutVertices: VO[] = [];
772
-
773
546
  let time = 0;
774
-
775
547
  const dfs = (vertex: VO, parent: VO | undefined) => {
776
548
  dfnMap.set(vertex, time);
777
549
  lowMap.set(vertex, time);
778
550
  time++;
779
-
780
551
  const neighbors = this.getNeighbors(vertex);
781
552
  let childCount = 0;
782
-
783
553
  for (const neighbor of neighbors) {
784
554
  if (!dfnMap.has(neighbor)) {
785
555
  childCount++;
786
556
  dfs(neighbor, vertex);
787
557
  lowMap.set(vertex, Math.min(lowMap.get(vertex)!, lowMap.get(neighbor)!));
788
-
789
558
  if (lowMap.get(neighbor)! > dfnMap.get(vertex)!) {
790
559
  // Found a bridge
791
560
  const edge = this.getEdge(vertex, neighbor);
@@ -793,7 +562,6 @@ export class UndirectedGraph<
793
562
  bridges.push(edge);
794
563
  }
795
564
  }
796
-
797
565
  if (parent !== undefined && lowMap.get(neighbor)! >= dfnMap.get(vertex)!) {
798
566
  // Found an articulation point
799
567
  cutVertices.push(vertex);
@@ -802,19 +570,16 @@ export class UndirectedGraph<
802
570
  lowMap.set(vertex, Math.min(lowMap.get(vertex)!, dfnMap.get(neighbor)!));
803
571
  }
804
572
  }
805
-
806
573
  if (parent === undefined && childCount > 1) {
807
574
  // Special case for root in DFS tree
808
575
  cutVertices.push(vertex);
809
576
  }
810
577
  };
811
-
812
578
  for (const vertex of this.vertexMap.values()) {
813
579
  if (!dfnMap.has(vertex)) {
814
580
  dfs(vertex, undefined);
815
581
  }
816
582
  }
817
-
818
583
  return {
819
584
  dfnMap,
820
585
  lowMap,
@@ -835,25 +600,20 @@ export class UndirectedGraph<
835
600
  const edgeStack: EO[] = [];
836
601
  const components: EO[][] = [];
837
602
  let time = 0;
838
-
839
603
  const dfs = (vertex: VO, parent: VO | undefined) => {
840
604
  dfn.set(vertex, time);
841
605
  low.set(vertex, time);
842
606
  time++;
843
-
844
607
  const neighbors = this.getNeighbors(vertex);
845
608
  let childCount = 0;
846
-
847
609
  for (const neighbor of neighbors) {
848
610
  const edge = this.getEdge(vertex, neighbor);
849
611
  if (!edge) continue;
850
-
851
612
  if (!dfn.has(neighbor)) {
852
613
  childCount++;
853
614
  edgeStack.push(edge);
854
615
  dfs(neighbor, vertex);
855
616
  low.set(vertex, Math.min(low.get(vertex)!, low.get(neighbor)!));
856
-
857
617
  // Articulation point found — pop edges to form a component
858
618
  if (
859
619
  (parent === undefined && childCount > 1) ||
@@ -874,7 +634,6 @@ export class UndirectedGraph<
874
634
  }
875
635
  }
876
636
  };
877
-
878
637
  for (const vertex of this.vertexMap.values()) {
879
638
  if (!dfn.has(vertex)) {
880
639
  dfs(vertex, undefined);
@@ -885,7 +644,6 @@ export class UndirectedGraph<
885
644
  }
886
645
  }
887
646
  }
888
-
889
647
  return components;
890
648
  }
891
649
 
@@ -894,57 +652,20 @@ export class UndirectedGraph<
894
652
  * Uses DFS with parent tracking.
895
653
  * @returns `true` if a cycle exists, `false` otherwise.
896
654
  * @remarks Time O(V + E), Space O(V)
897
-
898
-
899
-
900
-
901
-
902
-
903
-
904
-
905
-
906
-
907
-
908
-
909
-
910
-
911
-
912
-
913
-
914
-
915
-
916
-
917
-
918
-
919
-
920
-
921
-
922
-
923
-
924
-
925
-
926
-
927
-
928
-
929
-
930
-
931
-
932
-
933
- * @example
934
- * // Detect cycle
935
- * const g = new UndirectedGraph();
936
- * g.addVertex('A');
937
- * g.addVertex('B');
938
- * g.addVertex('C');
939
- * g.addEdge('A', 'B');
940
- * g.addEdge('B', 'C');
941
- * console.log(g.hasCycle()); // false;
942
- * g.addEdge('C', 'A');
943
- * console.log(g.hasCycle()); // true;
655
+ * @example
656
+ * // Detect cycle
657
+ * const g = new UndirectedGraph();
658
+ * g.addVertex('A');
659
+ * g.addVertex('B');
660
+ * g.addVertex('C');
661
+ * g.addEdge('A', 'B');
662
+ * g.addEdge('B', 'C');
663
+ * console.log(g.hasCycle()); // false;
664
+ * g.addEdge('C', 'A');
665
+ * console.log(g.hasCycle()); // true;
944
666
  */
945
667
  hasCycle(): boolean {
946
668
  const visited = new Set<VO>();
947
-
948
669
  const dfs = (vertex: VO, parent: VO | undefined): boolean => {
949
670
  visited.add(vertex);
950
671
  for (const neighbor of this.getNeighbors(vertex)) {
@@ -956,7 +677,6 @@ export class UndirectedGraph<
956
677
  }
957
678
  return false;
958
679
  };
959
-
960
680
  for (const vertex of this.vertexMap.values()) {
961
681
  if (!visited.has(vertex)) {
962
682
  if (dfs(vertex, undefined)) return true;
@@ -969,52 +689,16 @@ export class UndirectedGraph<
969
689
  * Get bridges discovered by `tarjan()`.
970
690
  * @returns Array of edges that are bridges.
971
691
  * @remarks Time O(B), Space O(1)
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
-
1000
-
1001
-
1002
-
1003
-
1004
-
1005
-
1006
-
1007
-
1008
- * @example
1009
- * // Find bridge edges
1010
- * const g = new UndirectedGraph();
1011
- * g.addVertex('A');
1012
- * g.addVertex('B');
1013
- * g.addVertex('C');
1014
- * g.addEdge('A', 'B');
1015
- * g.addEdge('B', 'C');
1016
- * const bridges = g.getBridges();
1017
- * console.log(bridges.length); // 2;
692
+ * @example
693
+ * // Find bridge edges
694
+ * const g = new UndirectedGraph();
695
+ * g.addVertex('A');
696
+ * g.addVertex('B');
697
+ * g.addVertex('C');
698
+ * g.addEdge('A', 'B');
699
+ * g.addEdge('B', 'C');
700
+ * const bridges = g.getBridges();
701
+ * console.log(bridges.length); // 2;
1018
702
  */
1019
703
  getBridges() {
1020
704
  return this.tarjan().bridges;
@@ -1024,53 +708,17 @@ export class UndirectedGraph<
1024
708
  * Get articulation points discovered by `tarjan()`.
1025
709
  * @returns Array of cut vertices.
1026
710
  * @remarks Time O(C), Space O(1)
1027
-
1028
-
1029
-
1030
-
1031
-
1032
-
1033
-
1034
-
1035
-
1036
-
1037
-
1038
-
1039
-
1040
-
1041
-
1042
-
1043
-
1044
-
1045
-
1046
-
1047
-
1048
-
1049
-
1050
-
1051
-
1052
-
1053
-
1054
-
1055
-
1056
-
1057
-
1058
-
1059
-
1060
-
1061
-
1062
-
1063
- * @example
1064
- * // Find articulation points
1065
- * const g = new UndirectedGraph();
1066
- * g.addVertex('A');
1067
- * g.addVertex('B');
1068
- * g.addVertex('C');
1069
- * g.addEdge('A', 'B');
1070
- * g.addEdge('B', 'C');
1071
- * const cuts = g.getCutVertices();
1072
- * console.log(cuts.length); // 1;
1073
- * console.log(cuts[0].key); // 'B';
711
+ * @example
712
+ * // Find articulation points
713
+ * const g = new UndirectedGraph();
714
+ * g.addVertex('A');
715
+ * g.addVertex('B');
716
+ * g.addVertex('C');
717
+ * g.addEdge('A', 'B');
718
+ * g.addEdge('B', 'C');
719
+ * const cuts = g.getCutVertices();
720
+ * console.log(cuts.length); // 1;
721
+ * console.log(cuts[0].key); // 'B';
1074
722
  */
1075
723
  getCutVertices() {
1076
724
  return this.tarjan().cutVertices;