binary-tree-typed 2.4.5 → 2.5.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.
- package/README.md +0 -84
- package/dist/cjs/index.cjs +1476 -404
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +1473 -401
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1476 -404
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +1473 -401
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +1 -1
- package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
- package/dist/types/data-structures/base/linear-base.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +380 -51
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +487 -147
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +956 -80
- package/dist/types/data-structures/binary-tree/bst.d.ts +816 -29
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +610 -31
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +326 -135
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +3781 -6
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3607 -201
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2874 -65
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +3528 -6
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +429 -47
- package/dist/types/data-structures/graph/map-graph.d.ts +59 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +393 -59
- package/dist/types/data-structures/hash/hash-map.d.ts +473 -89
- package/dist/types/data-structures/heap/heap.d.ts +581 -99
- package/dist/types/data-structures/heap/max-heap.d.ts +46 -0
- package/dist/types/data-structures/heap/min-heap.d.ts +59 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +646 -47
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +596 -68
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +793 -12
- package/dist/types/data-structures/matrix/matrix.d.ts +499 -0
- package/dist/types/data-structures/priority-queue/max-priority-queue.d.ts +57 -0
- package/dist/types/data-structures/priority-queue/min-priority-queue.d.ts +60 -0
- package/dist/types/data-structures/priority-queue/priority-queue.d.ts +60 -0
- package/dist/types/data-structures/queue/deque.d.ts +593 -71
- package/dist/types/data-structures/queue/queue.d.ts +463 -42
- package/dist/types/data-structures/stack/stack.d.ts +384 -32
- package/dist/types/data-structures/trie/trie.d.ts +470 -48
- package/dist/types/interfaces/graph.d.ts +1 -1
- package/dist/types/types/common.d.ts +2 -2
- package/dist/types/types/data-structures/binary-tree/segment-tree.d.ts +1 -1
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/linked-list/skip-linked-list.d.ts +1 -4
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
- package/dist/types/types/utils/validate-type.d.ts +4 -4
- package/dist/umd/binary-tree-typed.js +1469 -397
- package/dist/umd/binary-tree-typed.js.map +1 -1
- package/dist/umd/binary-tree-typed.min.js +5 -5
- package/dist/umd/binary-tree-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-element-base.ts +4 -5
- package/src/data-structures/base/iterable-entry-base.ts +8 -8
- package/src/data-structures/base/linear-base.ts +3 -3
- package/src/data-structures/binary-tree/avl-tree.ts +386 -51
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +596 -247
- package/src/data-structures/binary-tree/binary-tree.ts +956 -81
- package/src/data-structures/binary-tree/bst.ts +840 -35
- package/src/data-structures/binary-tree/red-black-tree.ts +689 -97
- package/src/data-structures/binary-tree/segment-tree.ts +498 -249
- package/src/data-structures/binary-tree/tree-map.ts +3784 -7
- package/src/data-structures/binary-tree/tree-multi-map.ts +3614 -211
- package/src/data-structures/binary-tree/tree-multi-set.ts +2874 -65
- package/src/data-structures/binary-tree/tree-set.ts +3531 -10
- package/src/data-structures/graph/abstract-graph.ts +4 -4
- package/src/data-structures/graph/directed-graph.ts +429 -47
- package/src/data-structures/graph/map-graph.ts +59 -1
- package/src/data-structures/graph/undirected-graph.ts +393 -59
- package/src/data-structures/hash/hash-map.ts +476 -92
- package/src/data-structures/heap/heap.ts +581 -99
- package/src/data-structures/heap/max-heap.ts +46 -0
- package/src/data-structures/heap/min-heap.ts +59 -0
- package/src/data-structures/linked-list/doubly-linked-list.ts +646 -47
- package/src/data-structures/linked-list/singly-linked-list.ts +596 -68
- package/src/data-structures/linked-list/skip-linked-list.ts +1067 -90
- package/src/data-structures/matrix/matrix.ts +584 -12
- package/src/data-structures/priority-queue/max-priority-queue.ts +57 -0
- package/src/data-structures/priority-queue/min-priority-queue.ts +60 -0
- package/src/data-structures/priority-queue/priority-queue.ts +60 -0
- package/src/data-structures/queue/deque.ts +592 -70
- package/src/data-structures/queue/queue.ts +463 -42
- package/src/data-structures/stack/stack.ts +384 -32
- package/src/data-structures/trie/trie.ts +470 -48
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/binary-tree/segment-tree.ts +1 -1
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/linked-list/skip-linked-list.ts +2 -1
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
|
@@ -212,7 +212,7 @@ export abstract class AbstractGraph<
|
|
|
212
212
|
* @returns `true` if string/number; else `false`.
|
|
213
213
|
* @remarks Time O(1), Space O(1)
|
|
214
214
|
*/
|
|
215
|
-
isVertexKey(potentialKey:
|
|
215
|
+
isVertexKey(potentialKey: unknown): potentialKey is VertexKey {
|
|
216
216
|
const potentialKeyType = typeof potentialKey;
|
|
217
217
|
return potentialKeyType === 'string' || potentialKeyType === 'number';
|
|
218
218
|
}
|
|
@@ -894,7 +894,7 @@ export abstract class AbstractGraph<
|
|
|
894
894
|
* @returns A new graph of the same concrete class (`this` type).
|
|
895
895
|
* @remarks Time O(V + E), Space O(V + E)
|
|
896
896
|
*/
|
|
897
|
-
filter(predicate: EntryCallback<VertexKey, V | undefined, boolean>, thisArg?:
|
|
897
|
+
filter(predicate: EntryCallback<VertexKey, V | undefined, boolean>, thisArg?: unknown): this {
|
|
898
898
|
const filtered: [VertexKey, V | undefined][] = [];
|
|
899
899
|
let index = 0;
|
|
900
900
|
for (const [key, value] of this) {
|
|
@@ -912,7 +912,7 @@ export abstract class AbstractGraph<
|
|
|
912
912
|
*/
|
|
913
913
|
filterEntries(
|
|
914
914
|
predicate: EntryCallback<VertexKey, V | undefined, boolean>,
|
|
915
|
-
thisArg?:
|
|
915
|
+
thisArg?: unknown
|
|
916
916
|
): [VertexKey, V | undefined][] {
|
|
917
917
|
const filtered: [VertexKey, V | undefined][] = [];
|
|
918
918
|
let index = 0;
|
|
@@ -925,7 +925,7 @@ export abstract class AbstractGraph<
|
|
|
925
925
|
return filtered;
|
|
926
926
|
}
|
|
927
927
|
|
|
928
|
-
map<T>(callback: EntryCallback<VertexKey, V | undefined, T>, thisArg?:
|
|
928
|
+
map<T>(callback: EntryCallback<VertexKey, V | undefined, T>, thisArg?: unknown): T[] {
|
|
929
929
|
const mapped: T[] = [];
|
|
930
930
|
let index = 0;
|
|
931
931
|
for (const [key, value] of this) {
|
|
@@ -77,53 +77,6 @@ export class DirectedEdge<E = any> extends AbstractEdge<E> {
|
|
|
77
77
|
* console.log(neighborsA[0].key); // 'B';
|
|
78
78
|
* console.log(neighborsA[1].key); // 'C';
|
|
79
79
|
* @example
|
|
80
|
-
* // DirectedGraph deleteEdge and vertex operations
|
|
81
|
-
* const graph = new DirectedGraph<string>();
|
|
82
|
-
*
|
|
83
|
-
* // Build a small graph
|
|
84
|
-
* graph.addVertex('X');
|
|
85
|
-
* graph.addVertex('Y');
|
|
86
|
-
* graph.addVertex('Z');
|
|
87
|
-
* graph.addEdge('X', 'Y', 1);
|
|
88
|
-
* graph.addEdge('Y', 'Z', 2);
|
|
89
|
-
*
|
|
90
|
-
* // Delete an edge
|
|
91
|
-
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
92
|
-
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
93
|
-
*
|
|
94
|
-
* // Edge in other direction should not exist
|
|
95
|
-
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
96
|
-
*
|
|
97
|
-
* // Other edges should remain
|
|
98
|
-
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
99
|
-
*
|
|
100
|
-
* // Delete a vertex
|
|
101
|
-
* graph.deleteVertex('Y');
|
|
102
|
-
* console.log(graph.hasVertex('Y')); // false;
|
|
103
|
-
* console.log(graph.size); // 2;
|
|
104
|
-
* @example
|
|
105
|
-
* // DirectedGraph topologicalSort for task scheduling
|
|
106
|
-
* const graph = new DirectedGraph<string>();
|
|
107
|
-
*
|
|
108
|
-
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
109
|
-
* graph.addVertex('Design');
|
|
110
|
-
* graph.addVertex('Implement');
|
|
111
|
-
* graph.addVertex('Test');
|
|
112
|
-
* graph.addVertex('Deploy');
|
|
113
|
-
*
|
|
114
|
-
* // Add dependency edges
|
|
115
|
-
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
116
|
-
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
117
|
-
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
118
|
-
*
|
|
119
|
-
* // Topological sort gives valid execution order
|
|
120
|
-
* const executionOrder = graph.topologicalSort();
|
|
121
|
-
* console.log(executionOrder); // defined;
|
|
122
|
-
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
123
|
-
*
|
|
124
|
-
* // All vertices should be included
|
|
125
|
-
* console.log(executionOrder?.length); // 4;
|
|
126
|
-
* @example
|
|
127
80
|
* // DirectedGraph dijkstra shortest path for network routing
|
|
128
81
|
* // Build a weighted directed graph representing network nodes and costs
|
|
129
82
|
* const network = new DirectedGraph<string>();
|
|
@@ -264,6 +217,43 @@ export class DirectedGraph<
|
|
|
264
217
|
* @param destOrKey - Destination vertex or key.
|
|
265
218
|
* @returns Edge instance or `undefined`.
|
|
266
219
|
* @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
|
+
* @example
|
|
250
|
+
* // Get edge between vertices
|
|
251
|
+
* const g = new DirectedGraph();
|
|
252
|
+
* g.addVertex('A');
|
|
253
|
+
* g.addVertex('B');
|
|
254
|
+
* g.addEdge('A', 'B', 5);
|
|
255
|
+
* const edge = g.getEdge('A', 'B');
|
|
256
|
+
* console.log(edge?.weight); // 5;
|
|
267
257
|
*/
|
|
268
258
|
getEdge(srcOrKey: VO | VertexKey | undefined, destOrKey: VO | VertexKey | undefined): EO | undefined {
|
|
269
259
|
let edgeMap: EO[] = [];
|
|
@@ -316,6 +306,63 @@ export class DirectedGraph<
|
|
|
316
306
|
* @param destVertexKey - Optional destination vertex/key when deleting by pair.
|
|
317
307
|
* @returns Removed edge or `undefined`.
|
|
318
308
|
* @remarks Time O(1) avg, Space O(1)
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
|
|
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
|
+
* @example
|
|
342
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
343
|
+
* const graph = new DirectedGraph<string>();
|
|
344
|
+
*
|
|
345
|
+
* // Build a small graph
|
|
346
|
+
* graph.addVertex('X');
|
|
347
|
+
* graph.addVertex('Y');
|
|
348
|
+
* graph.addVertex('Z');
|
|
349
|
+
* graph.addEdge('X', 'Y', 1);
|
|
350
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
351
|
+
*
|
|
352
|
+
* // Delete an edge
|
|
353
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
354
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
355
|
+
*
|
|
356
|
+
* // Edge in other direction should not exist
|
|
357
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
358
|
+
*
|
|
359
|
+
* // Other edges should remain
|
|
360
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
361
|
+
*
|
|
362
|
+
* // Delete a vertex
|
|
363
|
+
* graph.deleteVertex('Y');
|
|
364
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
365
|
+
* console.log(graph.size); // 2;
|
|
319
366
|
*/
|
|
320
367
|
deleteEdge(edgeOrSrcVertexKey: EO | VertexKey, destVertexKey?: VertexKey): EO | undefined {
|
|
321
368
|
let removed: EO | undefined = undefined;
|
|
@@ -347,6 +394,47 @@ export class DirectedGraph<
|
|
|
347
394
|
return removed;
|
|
348
395
|
}
|
|
349
396
|
|
|
397
|
+
/**
|
|
398
|
+
* Remove a vertex
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
* @example
|
|
429
|
+
* // Remove a vertex
|
|
430
|
+
* const g = new DirectedGraph();
|
|
431
|
+
* g.addVertex('A');
|
|
432
|
+
* g.addVertex('B');
|
|
433
|
+
* g.addEdge('A', 'B');
|
|
434
|
+
* g.deleteVertex('A');
|
|
435
|
+
* console.log(g.hasVertex('A')); // false;
|
|
436
|
+
* console.log(g.hasEdge('A', 'B')); // false;
|
|
437
|
+
*/
|
|
350
438
|
deleteVertex(vertexOrKey: VO | VertexKey): boolean {
|
|
351
439
|
let vertexKey: VertexKey;
|
|
352
440
|
let vertex: VO | undefined;
|
|
@@ -395,6 +483,44 @@ export class DirectedGraph<
|
|
|
395
483
|
* @param vertexOrKey - Vertex or key.
|
|
396
484
|
* @returns Array of incoming edges.
|
|
397
485
|
* @remarks Time O(deg_in), Space O(deg_in)
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
* @example
|
|
516
|
+
* // Get incoming edges
|
|
517
|
+
* const g = new DirectedGraph();
|
|
518
|
+
* g.addVertex('A');
|
|
519
|
+
* g.addVertex('B');
|
|
520
|
+
* g.addVertex('C');
|
|
521
|
+
* g.addEdge('A', 'C');
|
|
522
|
+
* g.addEdge('B', 'C');
|
|
523
|
+
* console.log(g.incomingEdgesOf('C').length); // 2;
|
|
398
524
|
*/
|
|
399
525
|
incomingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
|
|
400
526
|
const target = this._getVertex(vertexOrKey);
|
|
@@ -409,6 +535,44 @@ export class DirectedGraph<
|
|
|
409
535
|
* @param vertexOrKey - Vertex or key.
|
|
410
536
|
* @returns Array of outgoing edges.
|
|
411
537
|
* @remarks Time O(deg_out), Space O(deg_out)
|
|
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
|
+
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
* @example
|
|
568
|
+
* // Get outgoing edges
|
|
569
|
+
* const g = new DirectedGraph();
|
|
570
|
+
* g.addVertex('A');
|
|
571
|
+
* g.addVertex('B');
|
|
572
|
+
* g.addVertex('C');
|
|
573
|
+
* g.addEdge('A', 'B');
|
|
574
|
+
* g.addEdge('A', 'C');
|
|
575
|
+
* console.log(g.outgoingEdgesOf('A').length); // 2;
|
|
412
576
|
*/
|
|
413
577
|
outgoingEdgesOf(vertexOrKey: VO | VertexKey): EO[] {
|
|
414
578
|
const target = this._getVertex(vertexOrKey);
|
|
@@ -492,6 +656,60 @@ export class DirectedGraph<
|
|
|
492
656
|
* @param propertyName - `'key'` to map to keys; `'vertex'` to keep instances.
|
|
493
657
|
* @returns Array of keys/vertices, or `undefined` when cycle is found.
|
|
494
658
|
* @remarks Time O(V + E), Space O(V)
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
|
|
691
|
+
* @example
|
|
692
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
693
|
+
* const graph = new DirectedGraph<string>();
|
|
694
|
+
*
|
|
695
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
696
|
+
* graph.addVertex('Design');
|
|
697
|
+
* graph.addVertex('Implement');
|
|
698
|
+
* graph.addVertex('Test');
|
|
699
|
+
* graph.addVertex('Deploy');
|
|
700
|
+
*
|
|
701
|
+
* // Add dependency edges
|
|
702
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
703
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
704
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
705
|
+
*
|
|
706
|
+
* // Topological sort gives valid execution order
|
|
707
|
+
* const executionOrder = graph.topologicalSort();
|
|
708
|
+
* console.log(executionOrder); // defined;
|
|
709
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
710
|
+
*
|
|
711
|
+
* // All vertices should be included
|
|
712
|
+
* console.log(executionOrder?.length); // 4;
|
|
495
713
|
*/
|
|
496
714
|
topologicalSort(propertyName?: 'vertex' | 'key'): Array<VO | VertexKey> | undefined {
|
|
497
715
|
propertyName = propertyName ?? 'key';
|
|
@@ -530,6 +748,45 @@ export class DirectedGraph<
|
|
|
530
748
|
return sorted.reverse();
|
|
531
749
|
}
|
|
532
750
|
|
|
751
|
+
/**
|
|
752
|
+
* Get all edges
|
|
753
|
+
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
|
|
775
|
+
|
|
776
|
+
|
|
777
|
+
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
* @example
|
|
783
|
+
* // Get all edges
|
|
784
|
+
* const g = new DirectedGraph();
|
|
785
|
+
* g.addVertex('A');
|
|
786
|
+
* g.addVertex('B');
|
|
787
|
+
* g.addEdge('A', 'B', 3);
|
|
788
|
+
* console.log(g.edgeSet().length); // 1;
|
|
789
|
+
*/
|
|
533
790
|
edgeSet(): EO[] {
|
|
534
791
|
let edgeMap: EO[] = [];
|
|
535
792
|
this._outEdgeMap.forEach(outEdges => {
|
|
@@ -538,6 +795,49 @@ export class DirectedGraph<
|
|
|
538
795
|
return edgeMap;
|
|
539
796
|
}
|
|
540
797
|
|
|
798
|
+
/**
|
|
799
|
+
* Get outgoing neighbors
|
|
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
|
+
* @example
|
|
831
|
+
* // Get outgoing neighbors
|
|
832
|
+
* const g = new DirectedGraph();
|
|
833
|
+
* g.addVertex('A');
|
|
834
|
+
* g.addVertex('B');
|
|
835
|
+
* g.addVertex('C');
|
|
836
|
+
* g.addEdge('A', 'B');
|
|
837
|
+
* g.addEdge('A', 'C');
|
|
838
|
+
* const neighbors = g.getNeighbors('A');
|
|
839
|
+
* console.log(neighbors.map(v => v.key).sort()); // ['B', 'C'];
|
|
840
|
+
*/
|
|
541
841
|
getNeighbors(vertexOrKey: VO | VertexKey): VO[] {
|
|
542
842
|
const neighbors: VO[] = [];
|
|
543
843
|
const vertex = this._getVertex(vertexOrKey);
|
|
@@ -604,6 +904,48 @@ export class DirectedGraph<
|
|
|
604
904
|
* Tarjan's algorithm for strongly connected components.
|
|
605
905
|
* @returns `{ dfnMap, lowMap, SCCs }`.
|
|
606
906
|
* @remarks Time O(V + E), Space O(V + E)
|
|
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
|
+
|
|
934
|
+
|
|
935
|
+
|
|
936
|
+
* @example
|
|
937
|
+
* // Find strongly connected components
|
|
938
|
+
* const g = new DirectedGraph();
|
|
939
|
+
* g.addVertex('A');
|
|
940
|
+
* g.addVertex('B');
|
|
941
|
+
* g.addVertex('C');
|
|
942
|
+
* g.addEdge('A', 'B');
|
|
943
|
+
* g.addEdge('B', 'C');
|
|
944
|
+
* g.addEdge('C', 'A');
|
|
945
|
+
* const { SCCs } = g.tarjan();
|
|
946
|
+
* // A→B→C→A forms one SCC with 3 members
|
|
947
|
+
* const sccArrays = [...SCCs.values()];
|
|
948
|
+
* console.log(sccArrays.some(scc => scc.length === 3)); // true;
|
|
607
949
|
*/
|
|
608
950
|
tarjan(): { dfnMap: Map<VO, number>; lowMap: Map<VO, number>; SCCs: Map<number, VO[]> } {
|
|
609
951
|
const dfnMap = new Map<VO, number>();
|
|
@@ -678,6 +1020,46 @@ export class DirectedGraph<
|
|
|
678
1020
|
* Strongly connected components computed by `tarjan()`.
|
|
679
1021
|
* @returns Map from SCC id to vertices.
|
|
680
1022
|
* @remarks Time O(#SCC + V), Space O(V)
|
|
1023
|
+
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
|
|
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
|
+
* @example
|
|
1053
|
+
* // Get strongly connected components
|
|
1054
|
+
* const g = new DirectedGraph();
|
|
1055
|
+
* g.addVertex(1);
|
|
1056
|
+
* g.addVertex(2);
|
|
1057
|
+
* g.addVertex(3);
|
|
1058
|
+
* g.addEdge(1, 2);
|
|
1059
|
+
* g.addEdge(2, 3);
|
|
1060
|
+
* g.addEdge(3, 1);
|
|
1061
|
+
* const sccs = g.getSCCs(); // Map<number, VO[]>
|
|
1062
|
+
* console.log(sccs.size); // >= 1;
|
|
681
1063
|
*/
|
|
682
1064
|
getSCCs(): Map<number, VO[]> {
|
|
683
1065
|
return this.tarjan().SCCs;
|
|
@@ -33,7 +33,65 @@ export class MapEdge<E = any> extends DirectedEdge<E> {
|
|
|
33
33
|
* @template VO - Concrete vertex class (MapVertex<V>).
|
|
34
34
|
* @template EO - Concrete edge class (MapEdge<E>).
|
|
35
35
|
* @remarks Time O(1), Space O(1)
|
|
36
|
-
* @example
|
|
36
|
+
* @example
|
|
37
|
+
* // City navigation with shortest path
|
|
38
|
+
* const map = new MapGraph([0, 0], [10, 10]);
|
|
39
|
+
*
|
|
40
|
+
* map.addVertex(new MapVertex('Home', '', 0, 0));
|
|
41
|
+
* map.addVertex(new MapVertex('Office', '', 3, 4));
|
|
42
|
+
* map.addVertex(new MapVertex('Cafe', '', 1, 2));
|
|
43
|
+
* map.addVertex(new MapVertex('Park', '', 2, 1));
|
|
44
|
+
*
|
|
45
|
+
* map.addEdge('Home', 'Cafe', 2.2);
|
|
46
|
+
* map.addEdge('Cafe', 'Office', 3.5);
|
|
47
|
+
* map.addEdge('Home', 'Park', 2.0);
|
|
48
|
+
* map.addEdge('Park', 'Office', 4.0);
|
|
49
|
+
* map.addEdge('Home', 'Office', 7.0);
|
|
50
|
+
*
|
|
51
|
+
* // Find shortest path
|
|
52
|
+
* const result = map.dijkstra('Home', 'Office', true, true);
|
|
53
|
+
* console.log(result?.minDist); // 5.7; // Home → Cafe → Office
|
|
54
|
+
* console.log(result?.minPath.map(v => v.key)); // ['Home', 'Cafe', 'Office'];
|
|
55
|
+
* @example
|
|
56
|
+
* // Delivery route optimization
|
|
57
|
+
* const routes = new MapGraph([0, 0], [10, 10]);
|
|
58
|
+
*
|
|
59
|
+
* routes.addVertex(new MapVertex('Warehouse', '', 0, 0));
|
|
60
|
+
* routes.addVertex(new MapVertex('Customer A', '', 2, 3));
|
|
61
|
+
* routes.addVertex(new MapVertex('Customer B', '', 5, 1));
|
|
62
|
+
* routes.addVertex(new MapVertex('Customer C', '', 3, 5));
|
|
63
|
+
*
|
|
64
|
+
* routes.addEdge('Warehouse', 'Customer A', 3.6);
|
|
65
|
+
* routes.addEdge('Warehouse', 'Customer B', 5.1);
|
|
66
|
+
* routes.addEdge('Customer A', 'Customer C', 2.2);
|
|
67
|
+
* routes.addEdge('Customer A', 'Customer B', 3.6);
|
|
68
|
+
* routes.addEdge('Customer B', 'Customer C', 4.5);
|
|
69
|
+
*
|
|
70
|
+
* // Check outgoing neighbors of Customer A
|
|
71
|
+
* const neighbors = routes.getNeighbors('Customer A');
|
|
72
|
+
* console.log(neighbors.map(n => n.key).sort()); // ['Customer B', 'Customer C'];
|
|
73
|
+
*
|
|
74
|
+
* // Shortest path from Warehouse to Customer C
|
|
75
|
+
* const path = routes.getMinPathBetween('Warehouse', 'Customer C', true);
|
|
76
|
+
* console.log(path?.map(v => v.key)); // ['Warehouse', 'Customer A', 'Customer C'];
|
|
77
|
+
* @example
|
|
78
|
+
* // Campus map with building connections
|
|
79
|
+
* const campus = new MapGraph([0, 0], [5, 5]);
|
|
80
|
+
*
|
|
81
|
+
* campus.addVertex(new MapVertex('Library', '', 0, 0));
|
|
82
|
+
* campus.addVertex(new MapVertex('Lab', '', 1, 1));
|
|
83
|
+
* campus.addVertex(new MapVertex('Cafeteria', '', 2, 0));
|
|
84
|
+
*
|
|
85
|
+
* campus.addEdge('Library', 'Lab', 5);
|
|
86
|
+
* campus.addEdge('Lab', 'Cafeteria', 3);
|
|
87
|
+
* campus.addEdge('Library', 'Cafeteria', 10);
|
|
88
|
+
*
|
|
89
|
+
* console.log(campus.hasVertex('Library')); // true;
|
|
90
|
+
* console.log(campus.hasVertex('Gym')); // false;
|
|
91
|
+
*
|
|
92
|
+
* // Direct distance vs shortest path
|
|
93
|
+
* const direct = campus.dijkstra('Library', 'Cafeteria', true, true);
|
|
94
|
+
* console.log(direct?.minDist); // 8;
|
|
37
95
|
*/
|
|
38
96
|
export class MapGraph<
|
|
39
97
|
V = any,
|