max-priority-queue-typed 2.2.2 → 2.2.4

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 (47) hide show
  1. package/dist/cjs/index.cjs.map +1 -1
  2. package/dist/cjs-legacy/index.cjs.map +1 -1
  3. package/dist/esm/index.mjs.map +1 -1
  4. package/dist/esm-legacy/index.mjs.map +1 -1
  5. package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -2
  6. package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +5 -5
  7. package/dist/types/data-structures/binary-tree/avl-tree.d.ts +98 -5
  8. package/dist/types/data-structures/binary-tree/binary-tree.d.ts +103 -7
  9. package/dist/types/data-structures/binary-tree/bst.d.ts +202 -39
  10. package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +86 -37
  11. package/dist/types/data-structures/binary-tree/tree-counter.d.ts +4 -5
  12. package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +7 -7
  13. package/dist/types/data-structures/graph/directed-graph.d.ts +126 -1
  14. package/dist/types/data-structures/graph/undirected-graph.d.ts +160 -1
  15. package/dist/types/data-structures/hash/hash-map.d.ts +110 -27
  16. package/dist/types/data-structures/heap/heap.d.ts +107 -58
  17. package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +72 -404
  18. package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +121 -5
  19. package/dist/types/data-structures/queue/deque.d.ts +95 -67
  20. package/dist/types/data-structures/queue/queue.d.ts +90 -34
  21. package/dist/types/data-structures/stack/stack.d.ts +58 -40
  22. package/dist/types/data-structures/trie/trie.d.ts +109 -47
  23. package/dist/types/interfaces/binary-tree.d.ts +1 -0
  24. package/dist/types/types/data-structures/binary-tree/bst.d.ts +5 -5
  25. package/dist/umd/max-priority-queue-typed.js.map +1 -1
  26. package/dist/umd/max-priority-queue-typed.min.js.map +1 -1
  27. package/package.json +2 -2
  28. package/src/data-structures/binary-tree/avl-tree-counter.ts +1 -2
  29. package/src/data-structures/binary-tree/avl-tree-multi-map.ts +7 -8
  30. package/src/data-structures/binary-tree/avl-tree.ts +100 -7
  31. package/src/data-structures/binary-tree/binary-tree.ts +117 -7
  32. package/src/data-structures/binary-tree/bst.ts +431 -93
  33. package/src/data-structures/binary-tree/red-black-tree.ts +85 -37
  34. package/src/data-structures/binary-tree/tree-counter.ts +5 -7
  35. package/src/data-structures/binary-tree/tree-multi-map.ts +9 -10
  36. package/src/data-structures/graph/directed-graph.ts +126 -1
  37. package/src/data-structures/graph/undirected-graph.ts +160 -1
  38. package/src/data-structures/hash/hash-map.ts +110 -27
  39. package/src/data-structures/heap/heap.ts +107 -58
  40. package/src/data-structures/linked-list/doubly-linked-list.ts +72 -404
  41. package/src/data-structures/linked-list/singly-linked-list.ts +121 -5
  42. package/src/data-structures/queue/deque.ts +95 -67
  43. package/src/data-structures/queue/queue.ts +90 -34
  44. package/src/data-structures/stack/stack.ts +58 -40
  45. package/src/data-structures/trie/trie.ts +109 -47
  46. package/src/interfaces/binary-tree.ts +2 -0
  47. package/src/types/data-structures/binary-tree/bst.ts +5 -5
@@ -8,7 +8,6 @@
8
8
 
9
9
  import type {
10
10
  BinaryTreeDeleteResult,
11
- BinaryTreeOptions,
12
11
  CRUD,
13
12
  EntryCallback,
14
13
  FamilyPosition,
@@ -188,48 +187,97 @@ export class RedBlackTreeNode<K = any, V = any> {
188
187
  * 2. It is BST itself. Compared with Heap which is not completely ordered, RedBlackTree is completely ordered.
189
188
  *
190
189
  * @example
191
- * // using Red-Black Tree as a price-based index for stock data
192
- * // Define the structure of individual stock records
193
- * interface StockRecord {
194
- * price: number; // Stock price (key for indexing)
195
- * symbol: string; // Stock ticker symbol
196
- * volume: number; // Trade volume
190
+ * // basic Red-Black Tree with simple number keys
191
+ * // Create a simple Red-Black Tree with numeric keys
192
+ * const tree = new RedBlackTree([5, 2, 8, 1, 9]);
193
+ *
194
+ * tree.print();
195
+ * // _2___
196
+ * // / \
197
+ * // 1 _8_
198
+ * // / \
199
+ * // 5 9
200
+ *
201
+ * // Verify the tree maintains sorted order
202
+ * console.log([...tree.keys()]); // [1, 2, 5, 8, 9];
203
+ *
204
+ * // Check size
205
+ * console.log(tree.size); // 5;
206
+ * @example
207
+ * // Red-Black Tree with key-value pairs for lookups
208
+ * interface Employee {
209
+ * id: number;
210
+ * name: string;
197
211
  * }
198
212
  *
199
- * // Simulate stock market data as it might come from an external feed
200
- * const marketStockData: StockRecord[] = [
201
- * { price: 142.5, symbol: 'AAPL', volume: 1000000 },
202
- * { price: 335.2, symbol: 'MSFT', volume: 800000 },
203
- * { price: 3285.04, symbol: 'AMZN', volume: 500000 },
204
- * { price: 267.98, symbol: 'META', volume: 750000 },
205
- * { price: 234.57, symbol: 'GOOGL', volume: 900000 }
206
- * ];
213
+ * // Create tree with employee data
214
+ * const employees = new RedBlackTree<number, Employee>([
215
+ * [1, { id: 1, name: 'Alice' }],
216
+ * [3, { id: 3, name: 'Charlie' }],
217
+ * [2, { id: 2, name: 'Bob' }]
218
+ * ]);
219
+ *
220
+ * // Retrieve employee by ID
221
+ * const alice = employees.get(1);
222
+ * console.log(alice?.name); // 'Alice';
223
+ *
224
+ * // Verify sorted order by ID
225
+ * console.log([...employees.keys()]); // [1, 2, 3];
226
+ * @example
227
+ * // Red-Black Tree range search for filtering
228
+ * interface Product {
229
+ * name: string;
230
+ * price: number;
231
+ * }
207
232
  *
208
- * // Extend the stock record type to include metadata for database usage
209
- * type StockTableRecord = StockRecord & { lastUpdated: Date };
233
+ * const products = new RedBlackTree<number, Product>([
234
+ * [10, { name: 'Item A', price: 10 }],
235
+ * [25, { name: 'Item B', price: 25 }],
236
+ * [40, { name: 'Item C', price: 40 }],
237
+ * [50, { name: 'Item D', price: 50 }]
238
+ * ]);
210
239
  *
211
- * // Create a Red-Black Tree to index stock records by price
212
- * // Simulates a database index with stock price as the key for quick lookups
213
- * const priceIndex = new RedBlackTree<number, StockTableRecord, StockRecord>(marketStockData, {
214
- * toEntryFn: stockRecord => [
215
- * stockRecord.price, // Use stock price as the key
216
- * {
217
- * ...stockRecord,
218
- * lastUpdated: new Date() // Add a timestamp for when the record was indexed
219
- * }
220
- * ]
240
+ * // Find products in price range [20, 45]
241
+ * const pricesInRange = products.rangeSearch([20, 45], node => {
242
+ * return products.get(node)?.name;
221
243
  * });
222
244
  *
223
- * // Query the stock with the highest price
224
- * const highestPricedStock = priceIndex.getRightMost();
225
- * console.log(priceIndex.get(highestPricedStock)?.symbol); // 'AMZN' // Amazon has the highest price
245
+ * console.log(pricesInRange); // ['Item B', 'Item C'];
246
+ * @example
247
+ * // Red-Black Tree as database index for stock market data
248
+ * interface StockPrice {
249
+ * symbol: string;
250
+ * volume: number;
251
+ * timestamp: Date;
252
+ * }
253
+ *
254
+ * // Simulate real-time stock price index
255
+ * const priceIndex = new RedBlackTree<number, StockPrice>([
256
+ * [142.5, { symbol: 'AAPL', volume: 1000000, timestamp: new Date() }],
257
+ * [335.2, { symbol: 'MSFT', volume: 800000, timestamp: new Date() }],
258
+ * [3285.04, { symbol: 'AMZN', volume: 500000, timestamp: new Date() }],
259
+ * [267.98, { symbol: 'META', volume: 750000, timestamp: new Date() }],
260
+ * [234.57, { symbol: 'GOOGL', volume: 900000, timestamp: new Date() }]
261
+ * ]);
262
+ *
263
+ * // Find highest-priced stock
264
+ * const maxPrice = priceIndex.getRightMost();
265
+ * console.log(priceIndex.get(maxPrice)?.symbol); // 'AMZN';
266
+ *
267
+ * // Find stocks in price range [200, 400] for portfolio balancing
268
+ * const stocksInRange = priceIndex.rangeSearch([200, 400], node => {
269
+ * const stock = priceIndex.get(node);
270
+ * return {
271
+ * symbol: stock?.symbol,
272
+ * price: node,
273
+ * volume: stock?.volume
274
+ * };
275
+ * });
226
276
  *
227
- * // Query stocks within a specific price range (200 to 400)
228
- * const stocksInRange = priceIndex.rangeSearch(
229
- * [200, 400], // Price range
230
- * node => priceIndex.get(node)?.symbol // Extract stock symbols for the result
231
- * );
232
- * console.log(stocksInRange); // ['GOOGL', 'META', 'MSFT']
277
+ * console.log(stocksInRange.length); // 3;
278
+ * console.log(stocksInRange.some((s: any) => s.symbol === 'GOOGL')); // true;
279
+ * console.log(stocksInRange.some((s: any) => s.symbol === 'META')); // true;
280
+ * console.log(stocksInRange.some((s: any) => s.symbol === 'MSFT')); // true;
233
281
  */
234
282
 
235
283
  export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implements IBinaryTree<K, V, R> {
@@ -414,7 +462,7 @@ export class RedBlackTree<K = any, V = any, R = any> extends BST<K, V, R> implem
414
462
 
415
463
  override map<MK = K, MV = V, MR = any>(
416
464
  callback: EntryCallback<K, V | undefined, [MK, MV]>,
417
- options?: Partial<BinaryTreeOptions<MK, MV, MR>>,
465
+ options?: Partial<RedBlackTreeOptions<MK, MV, MR>>,
418
466
  thisArg?: unknown
419
467
  ): RedBlackTree<MK, MV, MR> {
420
468
  const out = this._createLike<MK, MV, MR>([], options);
@@ -8,7 +8,6 @@
8
8
 
9
9
  import type {
10
10
  BinaryTreeDeleteResult,
11
- BinaryTreeOptions,
12
11
  BSTNOptKeyOrNode,
13
12
  EntryCallback,
14
13
  FamilyPosition,
@@ -17,7 +16,6 @@ import type {
17
16
  RBTNColor,
18
17
  TreeCounterOptions
19
18
  } from '../../types';
20
- import { BSTOptions } from '../../types';
21
19
  import { BSTNode } from './bst';
22
20
  import { IBinaryTree } from '../../interfaces';
23
21
  import { RedBlackTree } from './red-black-tree';
@@ -432,7 +430,7 @@ export class TreeCounter<K = any, V = any, R = any> extends RedBlackTree<K, V, R
432
430
  */
433
431
  override map<MK = K, MV = V, MR = any>(
434
432
  callback: EntryCallback<K, V | undefined, [MK, MV]>,
435
- options?: Partial<BinaryTreeOptions<MK, MV, MR>>,
433
+ options?: Partial<TreeCounterOptions<MK, MV, MR>>,
436
434
  thisArg?: unknown
437
435
  ): TreeCounter<MK, MV, MR> {
438
436
  const out = this._createLike<MK, MV, MR>([], options);
@@ -465,10 +463,10 @@ export class TreeCounter<K = any, V = any, R = any> extends RedBlackTree<K, V, R
465
463
  * @param [options] - Optional constructor options for the like-kind instance.
466
464
  * @returns An empty like-kind instance.
467
465
  */
468
- protected override _createInstance<TK = K, TV = V, TR = R>(options?: Partial<BSTOptions<TK, TV, TR>>): this {
466
+ protected override _createInstance<TK = K, TV = V, TR = R>(options?: Partial<TreeCounterOptions<TK, TV, TR>>): this {
469
467
  const Ctor = this.constructor as unknown as new (
470
468
  iter?: Iterable<TK | BSTNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
471
- opts?: BSTOptions<TK, TV, TR>
469
+ opts?: TreeCounterOptions<TK, TV, TR>
472
470
  ) => this;
473
471
  return new Ctor([], { ...this._snapshotOptions<TK, TV, TR>(), ...(options ?? {}) }) as unknown as this;
474
472
  }
@@ -485,11 +483,11 @@ export class TreeCounter<K = any, V = any, R = any> extends RedBlackTree<K, V, R
485
483
  */
486
484
  protected override _createLike<TK = K, TV = V, TR = R>(
487
485
  iter: Iterable<TK | BSTNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR> = [],
488
- options?: Partial<BSTOptions<TK, TV, TR>>
486
+ options?: Partial<TreeCounterOptions<TK, TV, TR>>
489
487
  ): TreeCounter<TK, TV, TR> {
490
488
  const Ctor = this.constructor as unknown as new (
491
489
  iter?: Iterable<TK | BSTNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
492
- opts?: BSTOptions<TK, TV, TR>
490
+ opts?: TreeCounterOptions<TK, TV, TR>
493
491
  ) => TreeCounter<TK, TV, TR>;
494
492
  return new Ctor(iter as unknown as Iterable<TK | any>, {
495
493
  ...this._snapshotOptions<TK, TV, TR>(),
@@ -12,7 +12,6 @@ import type {
12
12
  EntryCallback,
13
13
  FamilyPosition,
14
14
  RBTNColor,
15
- RedBlackTreeOptions,
16
15
  TreeMultiMapOptions
17
16
  } from '../../types';
18
17
  import { RedBlackTree, RedBlackTreeNode } from './red-black-tree';
@@ -186,7 +185,7 @@ export class TreeMultiMapNode<K = any, V = any> {
186
185
  *
187
186
  * @example
188
187
  * // players ranked by score with their equipment
189
- * type Equipment = {
188
+ * type Equipment = {
190
189
  * name: string; // Equipment name
191
190
  * quality: 'legendary' | 'epic' | 'rare' | 'common';
192
191
  * level: number;
@@ -347,7 +346,7 @@ export class TreeMultiMapNode<K = any, V = any> {
347
346
  * // },
348
347
  * // { name: 'Level 3 Backpack', quality: 'epic', level: 80 }
349
348
  * // ]
350
- * // ]
349
+ * // ];
351
350
  */
352
351
  export class TreeMultiMap<K = any, V = any, R = any> extends RedBlackTree<K, V[], R> implements IBinaryTree<K, V[], R> {
353
352
  /**
@@ -476,13 +475,13 @@ export class TreeMultiMap<K = any, V = any, R = any> extends RedBlackTree<K, V[]
476
475
 
477
476
  override map<MK = K, MVArr extends unknown[] = V[], MR = any>(
478
477
  callback: EntryCallback<K, V[] | undefined, [MK, MVArr]>,
479
- options?: Partial<RedBlackTreeOptions<MK, MVArr, MR>>,
478
+ options?: Partial<TreeMultiMapOptions<MK, MVArr, MR>>,
480
479
  thisArg?: unknown
481
480
  ): TreeMultiMap<MK, ElemOf<MVArr>, MR>;
482
481
 
483
482
  override map<MK = K, MV = V[], MR = any>(
484
483
  callback: EntryCallback<K, V[] | undefined, [MK, MV]>,
485
- options?: Partial<RedBlackTreeOptions<MK, MV, MR>>,
484
+ options?: Partial<TreeMultiMapOptions<MK, MV, MR>>,
486
485
  thisArg?: unknown
487
486
  ): RedBlackTree<MK, MV, MR>;
488
487
 
@@ -499,7 +498,7 @@ export class TreeMultiMap<K = any, V = any, R = any> extends RedBlackTree<K, V[]
499
498
  */
500
499
  override map<MK, MV, MR extends object>(
501
500
  callback: EntryCallback<K, V[] | undefined, [MK, MV]>,
502
- options?: Partial<RedBlackTreeOptions<MK, MV, MR>>,
501
+ options?: Partial<TreeMultiMapOptions<MK, MV, MR>>,
503
502
  thisArg?: unknown
504
503
  ): RedBlackTree<MK, MV, MR> {
505
504
  const out = this._createLike<MK, MV, MR>([], options);
@@ -517,10 +516,10 @@ export class TreeMultiMap<K = any, V = any, R = any> extends RedBlackTree<K, V[]
517
516
  * @param [options] - Optional constructor options for the like-kind instance.
518
517
  * @returns An empty like-kind instance.
519
518
  */
520
- protected override _createInstance<TK = K, TV = V, TR = R>(options?: Partial<RedBlackTreeOptions<TK, TV, TR>>): this {
519
+ protected override _createInstance<TK = K, TV = V, TR = R>(options?: Partial<TreeMultiMapOptions<TK, TV, TR>>): this {
521
520
  const Ctor = this.constructor as unknown as new (
522
521
  iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
523
- opts?: RedBlackTreeOptions<TK, TV, TR>
522
+ opts?: TreeMultiMapOptions<TK, TV, TR>
524
523
  ) => RedBlackTree<TK, TV, TR>;
525
524
  return new Ctor([], { ...(this._snapshotOptions?.<TK, TV, TR>() ?? {}), ...(options ?? {}) }) as unknown as this;
526
525
  }
@@ -539,11 +538,11 @@ export class TreeMultiMap<K = any, V = any, R = any> extends RedBlackTree<K, V[]
539
538
  iter: Iterable<
540
539
  TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR
541
540
  > = [],
542
- options?: Partial<RedBlackTreeOptions<TK, TV, TR>>
541
+ options?: Partial<TreeMultiMapOptions<TK, TV, TR>>
543
542
  ): RedBlackTree<TK, TV, TR> {
544
543
  const Ctor = this.constructor as unknown as new (
545
544
  iter?: Iterable<TK | RedBlackTreeNode<TK, TV> | [TK | null | undefined, TV | undefined] | null | undefined | TR>,
546
- opts?: RedBlackTreeOptions<TK, TV, TR>
545
+ opts?: TreeMultiMapOptions<TK, TV, TR>
547
546
  ) => RedBlackTree<TK, TV, TR>;
548
547
  return new Ctor(iter, { ...(this._snapshotOptions?.<TK, TV, TR>() ?? {}), ...(options ?? {}) });
549
548
  }
@@ -35,7 +35,132 @@ export class DirectedEdge<E = any> extends AbstractEdge<E> {
35
35
  * @template VO - Concrete vertex class (extends AbstractVertex<V>).
36
36
  * @template EO - Concrete edge class (extends AbstractEdge<E>).
37
37
  * @remarks Time O(1), Space O(1)
38
- * @example examples will be generated by unit test
38
+ * @example
39
+ * // basic DirectedGraph vertex and edge creation
40
+ * // Create a simple directed graph
41
+ * const graph = new DirectedGraph<string>();
42
+ *
43
+ * // Add vertices
44
+ * graph.addVertex('A');
45
+ * graph.addVertex('B');
46
+ * graph.addVertex('C');
47
+ *
48
+ * // Verify vertices exist
49
+ * console.log(graph.hasVertex('A')); // true;
50
+ * console.log(graph.hasVertex('B')); // true;
51
+ * console.log(graph.hasVertex('C')); // true;
52
+ * console.log(graph.hasVertex('D')); // false;
53
+ *
54
+ * // Check vertex count
55
+ * console.log(graph.size); // 3;
56
+ * @example
57
+ * // DirectedGraph edge operations
58
+ * const graph = new DirectedGraph<string>();
59
+ *
60
+ * // Add vertices
61
+ * graph.addVertex('A');
62
+ * graph.addVertex('B');
63
+ * graph.addVertex('C');
64
+ *
65
+ * // Add directed edges
66
+ * graph.addEdge('A', 'B', 1);
67
+ * graph.addEdge('B', 'C', 2);
68
+ * graph.addEdge('A', 'C', 3);
69
+ *
70
+ * // Verify edges exist
71
+ * console.log(graph.hasEdge('A', 'B')); // true;
72
+ * console.log(graph.hasEdge('B', 'C')); // true;
73
+ * console.log(graph.hasEdge('C', 'B')); // false; // Graph is directed
74
+ *
75
+ * // Get neighbors of A
76
+ * const neighborsA = graph.getNeighbors('A');
77
+ * console.log(neighborsA[0].key); // 'B';
78
+ * console.log(neighborsA[1].key); // 'C';
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
+ * // DirectedGraph dijkstra shortest path for network routing
128
+ * // Build a weighted directed graph representing network nodes and costs
129
+ * const network = new DirectedGraph<string>();
130
+ *
131
+ * // Add network nodes
132
+ * network.addVertex('Router-A');
133
+ * network.addVertex('Router-B');
134
+ * network.addVertex('Router-C');
135
+ * network.addVertex('Router-D');
136
+ * network.addVertex('Router-E');
137
+ *
138
+ * // Add weighted edges (network latency costs)
139
+ * network.addEdge('Router-A', 'Router-B', 5);
140
+ * network.addEdge('Router-A', 'Router-C', 10);
141
+ * network.addEdge('Router-B', 'Router-D', 3);
142
+ * network.addEdge('Router-C', 'Router-D', 2);
143
+ * network.addEdge('Router-D', 'Router-E', 4);
144
+ * network.addEdge('Router-B', 'Router-E', 12);
145
+ *
146
+ * // Find shortest path from Router-A to Router-E
147
+ * const { minDist, minPath } = network.dijkstra('Router-A', 'Router-E', true, true) || {
148
+ * minDist: undefined,
149
+ * minPath: undefined
150
+ * };
151
+ *
152
+ * // Verify shortest path is found
153
+ * console.log(minDist); // defined;
154
+ * console.log(minPath); // defined;
155
+ *
156
+ * // Shortest path should be A -> B -> D -> E with cost 5+3+4=12
157
+ * // Or A -> C -> D -> E with cost 10+2+4=16
158
+ * // So the minimum is 12
159
+ * console.log(minDist); // <= 16;
160
+ *
161
+ * // Verify path is valid (includes start and end)
162
+ * console.log(minPath?.[0].key); // 'Router-A';
163
+ * console.log(minPath?.[minPath.length - 1].key); // 'Router-E';
39
164
  */
40
165
  export class DirectedGraph<
41
166
  V = any,
@@ -33,7 +33,166 @@ export class UndirectedEdge<E = number> extends AbstractEdge<E> {
33
33
  * @template VO - Concrete vertex class (extends AbstractVertex<V>).
34
34
  * @template EO - Concrete edge class (extends AbstractEdge<E>).
35
35
  * @remarks Time O(1), Space O(1)
36
- * @example examples will be generated by unit test
36
+ * @example
37
+ * // basic UndirectedGraph vertex and edge creation
38
+ * // Create a simple undirected graph
39
+ * const graph = new UndirectedGraph<string>();
40
+ *
41
+ * // Add vertices
42
+ * graph.addVertex('A');
43
+ * graph.addVertex('B');
44
+ * graph.addVertex('C');
45
+ * graph.addVertex('D');
46
+ *
47
+ * // Verify vertices exist
48
+ * console.log(graph.hasVertex('A')); // true;
49
+ * console.log(graph.hasVertex('B')); // true;
50
+ * console.log(graph.hasVertex('E')); // false;
51
+ *
52
+ * // Check vertex count
53
+ * console.log(graph.size); // 4;
54
+ * @example
55
+ * // UndirectedGraph edge operations (bidirectional)
56
+ * const graph = new UndirectedGraph<string>();
57
+ *
58
+ * // Add vertices
59
+ * graph.addVertex('A');
60
+ * graph.addVertex('B');
61
+ * graph.addVertex('C');
62
+ *
63
+ * // Add undirected edges (both directions automatically)
64
+ * graph.addEdge('A', 'B', 1);
65
+ * graph.addEdge('B', 'C', 2);
66
+ * graph.addEdge('A', 'C', 3);
67
+ *
68
+ * // Verify edges exist in both directions
69
+ * console.log(graph.hasEdge('A', 'B')); // true;
70
+ * console.log(graph.hasEdge('B', 'A')); // true; // Bidirectional!
71
+ *
72
+ * console.log(graph.hasEdge('C', 'B')); // true;
73
+ * console.log(graph.hasEdge('B', 'C')); // true; // Bidirectional!
74
+ *
75
+ * // Get neighbors of A
76
+ * const neighborsA = graph.getNeighbors('A');
77
+ * console.log(neighborsA[0].key); // 'B';
78
+ * console.log(neighborsA[1].key); // 'C';
79
+ * @example
80
+ * // UndirectedGraph deleteEdge and vertex operations
81
+ * const graph = new UndirectedGraph<string>();
82
+ *
83
+ * // Build a simple undirected 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
+ * graph.addEdge('X', 'Z', 3);
90
+ *
91
+ * // Delete an edge
92
+ * graph.deleteEdge('X', 'Y');
93
+ * console.log(graph.hasEdge('X', 'Y')); // false;
94
+ *
95
+ * // Bidirectional deletion confirmed
96
+ * console.log(graph.hasEdge('Y', 'X')); // false;
97
+ *
98
+ * // Other edges should remain
99
+ * console.log(graph.hasEdge('Y', 'Z')); // true;
100
+ * console.log(graph.hasEdge('Z', 'Y')); // true;
101
+ *
102
+ * // Delete a vertex
103
+ * graph.deleteVertex('Y');
104
+ * console.log(graph.hasVertex('Y')); // false;
105
+ * console.log(graph.size); // 2;
106
+ * @example
107
+ * // UndirectedGraph connectivity and neighbors
108
+ * const graph = new UndirectedGraph<string>();
109
+ *
110
+ * // Build a friendship network
111
+ * const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
112
+ * for (const person of people) {
113
+ * graph.addVertex(person);
114
+ * }
115
+ *
116
+ * // Add friendships (undirected edges)
117
+ * graph.addEdge('Alice', 'Bob', 1);
118
+ * graph.addEdge('Alice', 'Charlie', 1);
119
+ * graph.addEdge('Bob', 'Diana', 1);
120
+ * graph.addEdge('Charlie', 'Eve', 1);
121
+ * graph.addEdge('Diana', 'Eve', 1);
122
+ *
123
+ * // Get friends of each person
124
+ * const aliceFriends = graph.getNeighbors('Alice');
125
+ * console.log(aliceFriends[0].key); // 'Bob';
126
+ * console.log(aliceFriends[1].key); // 'Charlie';
127
+ * console.log(aliceFriends.length); // 2;
128
+ *
129
+ * const dianaFriends = graph.getNeighbors('Diana');
130
+ * console.log(dianaFriends[0].key); // 'Bob';
131
+ * console.log(dianaFriends[1].key); // 'Eve';
132
+ * console.log(dianaFriends.length); // 2;
133
+ *
134
+ * // Verify bidirectional friendship
135
+ * const bobFriends = graph.getNeighbors('Bob');
136
+ * console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
137
+ * console.log(bobFriends[1].key); // 'Diana';
138
+ * @example
139
+ * // UndirectedGraph for social network connectivity analysis
140
+ * interface Person {
141
+ * id: number;
142
+ * name: string;
143
+ * location: string;
144
+ * }
145
+ *
146
+ * // UndirectedGraph is perfect for modeling symmetric relationships
147
+ * // (friendships, collaborations, partnerships)
148
+ * const socialNetwork = new UndirectedGraph<number, Person>();
149
+ *
150
+ * // Add people as vertices
151
+ * const people: [number, Person][] = [
152
+ * [1, { id: 1, name: 'Alice', location: 'New York' }],
153
+ * [2, { id: 2, name: 'Bob', location: 'San Francisco' }],
154
+ * [3, { id: 3, name: 'Charlie', location: 'Boston' }],
155
+ * [4, { id: 4, name: 'Diana', location: 'New York' }],
156
+ * [5, { id: 5, name: 'Eve', location: 'Seattle' }]
157
+ * ];
158
+ *
159
+ * for (const [id] of people) {
160
+ * socialNetwork.addVertex(id);
161
+ * }
162
+ *
163
+ * // Add friendships (automatically bidirectional)
164
+ * socialNetwork.addEdge(1, 2, 1); // Alice <-> Bob
165
+ * socialNetwork.addEdge(1, 3, 1); // Alice <-> Charlie
166
+ * socialNetwork.addEdge(2, 4, 1); // Bob <-> Diana
167
+ * socialNetwork.addEdge(3, 5, 1); // Charlie <-> Eve
168
+ * socialNetwork.addEdge(4, 5, 1); // Diana <-> Eve
169
+ *
170
+ * console.log(socialNetwork.size); // 5;
171
+ *
172
+ * // Find direct connections for Alice
173
+ * const aliceConnections = socialNetwork.getNeighbors(1);
174
+ * console.log(aliceConnections[0].key); // 2;
175
+ * console.log(aliceConnections[1].key); // 3;
176
+ * console.log(aliceConnections.length); // 2;
177
+ *
178
+ * // Verify bidirectional connections
179
+ * console.log(socialNetwork.hasEdge(1, 2)); // true;
180
+ * console.log(socialNetwork.hasEdge(2, 1)); // true; // Friendship works both ways!
181
+ *
182
+ * // Remove a person from network
183
+ * socialNetwork.deleteVertex(2); // Bob leaves
184
+ * console.log(socialNetwork.hasVertex(2)); // false;
185
+ * console.log(socialNetwork.size); // 4;
186
+ *
187
+ * // Alice loses Bob as a friend
188
+ * const updatedAliceConnections = socialNetwork.getNeighbors(1);
189
+ * console.log(updatedAliceConnections[0].key); // 3;
190
+ * console.log(updatedAliceConnections[1]); // undefined;
191
+ *
192
+ * // Diana loses Bob as a friend
193
+ * const dianaConnections = socialNetwork.getNeighbors(4);
194
+ * console.log(dianaConnections[0].key); // 5;
195
+ * console.log(dianaConnections[1]); // undefined;
37
196
  */
38
197
  export class UndirectedGraph<
39
198
  V = any,