red-black-tree-typed 2.2.2 → 2.2.3
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 +92 -37
- package/dist/cjs/index.cjs +163 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +164 -0
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +163 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +164 -0
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +96 -2
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +103 -7
- package/dist/types/data-structures/binary-tree/bst.d.ts +156 -13
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +84 -35
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
- package/dist/types/data-structures/graph/directed-graph.d.ts +126 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +160 -1
- package/dist/types/data-structures/hash/hash-map.d.ts +110 -27
- package/dist/types/data-structures/heap/heap.d.ts +107 -58
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +72 -404
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +121 -5
- package/dist/types/data-structures/queue/deque.d.ts +95 -67
- package/dist/types/data-structures/queue/queue.d.ts +90 -34
- package/dist/types/data-structures/stack/stack.d.ts +58 -40
- package/dist/types/data-structures/trie/trie.d.ts +109 -47
- package/dist/types/interfaces/binary-tree.d.ts +1 -0
- package/dist/umd/red-black-tree-typed.js +164 -0
- package/dist/umd/red-black-tree-typed.js.map +1 -1
- package/dist/umd/red-black-tree-typed.min.js +3 -3
- package/dist/umd/red-black-tree-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree.ts +96 -2
- package/src/data-structures/binary-tree/binary-tree.ts +117 -7
- package/src/data-structures/binary-tree/bst.ts +322 -13
- package/src/data-structures/binary-tree/red-black-tree.ts +84 -35
- package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
- package/src/data-structures/graph/directed-graph.ts +126 -1
- package/src/data-structures/graph/undirected-graph.ts +160 -1
- package/src/data-structures/hash/hash-map.ts +110 -27
- package/src/data-structures/heap/heap.ts +107 -58
- package/src/data-structures/linked-list/doubly-linked-list.ts +72 -404
- package/src/data-structures/linked-list/singly-linked-list.ts +121 -5
- package/src/data-structures/queue/deque.ts +95 -67
- package/src/data-structures/queue/queue.ts +90 -34
- package/src/data-structures/stack/stack.ts +58 -40
- package/src/data-structures/trie/trie.ts +109 -47
- package/src/interfaces/binary-tree.ts +2 -0
|
@@ -23,7 +23,132 @@ export declare class DirectedEdge<E = any> extends AbstractEdge<E> {
|
|
|
23
23
|
* @template VO - Concrete vertex class (extends AbstractVertex<V>).
|
|
24
24
|
* @template EO - Concrete edge class (extends AbstractEdge<E>).
|
|
25
25
|
* @remarks Time O(1), Space O(1)
|
|
26
|
-
* @example
|
|
26
|
+
* @example
|
|
27
|
+
* // basic DirectedGraph vertex and edge creation
|
|
28
|
+
* // Create a simple directed graph
|
|
29
|
+
* const graph = new DirectedGraph<string>();
|
|
30
|
+
*
|
|
31
|
+
* // Add vertices
|
|
32
|
+
* graph.addVertex('A');
|
|
33
|
+
* graph.addVertex('B');
|
|
34
|
+
* graph.addVertex('C');
|
|
35
|
+
*
|
|
36
|
+
* // Verify vertices exist
|
|
37
|
+
* console.log(graph.hasVertex('A')); // true;
|
|
38
|
+
* console.log(graph.hasVertex('B')); // true;
|
|
39
|
+
* console.log(graph.hasVertex('C')); // true;
|
|
40
|
+
* console.log(graph.hasVertex('D')); // false;
|
|
41
|
+
*
|
|
42
|
+
* // Check vertex count
|
|
43
|
+
* console.log(graph.size); // 3;
|
|
44
|
+
* @example
|
|
45
|
+
* // DirectedGraph edge operations
|
|
46
|
+
* const graph = new DirectedGraph<string>();
|
|
47
|
+
*
|
|
48
|
+
* // Add vertices
|
|
49
|
+
* graph.addVertex('A');
|
|
50
|
+
* graph.addVertex('B');
|
|
51
|
+
* graph.addVertex('C');
|
|
52
|
+
*
|
|
53
|
+
* // Add directed edges
|
|
54
|
+
* graph.addEdge('A', 'B', 1);
|
|
55
|
+
* graph.addEdge('B', 'C', 2);
|
|
56
|
+
* graph.addEdge('A', 'C', 3);
|
|
57
|
+
*
|
|
58
|
+
* // Verify edges exist
|
|
59
|
+
* console.log(graph.hasEdge('A', 'B')); // true;
|
|
60
|
+
* console.log(graph.hasEdge('B', 'C')); // true;
|
|
61
|
+
* console.log(graph.hasEdge('C', 'B')); // false; // Graph is directed
|
|
62
|
+
*
|
|
63
|
+
* // Get neighbors of A
|
|
64
|
+
* const neighborsA = graph.getNeighbors('A');
|
|
65
|
+
* console.log(neighborsA[0].key); // 'B';
|
|
66
|
+
* console.log(neighborsA[1].key); // 'C';
|
|
67
|
+
* @example
|
|
68
|
+
* // DirectedGraph deleteEdge and vertex operations
|
|
69
|
+
* const graph = new DirectedGraph<string>();
|
|
70
|
+
*
|
|
71
|
+
* // Build a small graph
|
|
72
|
+
* graph.addVertex('X');
|
|
73
|
+
* graph.addVertex('Y');
|
|
74
|
+
* graph.addVertex('Z');
|
|
75
|
+
* graph.addEdge('X', 'Y', 1);
|
|
76
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
77
|
+
*
|
|
78
|
+
* // Delete an edge
|
|
79
|
+
* graph.deleteEdgeSrcToDest('X', 'Y');
|
|
80
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
81
|
+
*
|
|
82
|
+
* // Edge in other direction should not exist
|
|
83
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
84
|
+
*
|
|
85
|
+
* // Other edges should remain
|
|
86
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
87
|
+
*
|
|
88
|
+
* // Delete a vertex
|
|
89
|
+
* graph.deleteVertex('Y');
|
|
90
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
91
|
+
* console.log(graph.size); // 2;
|
|
92
|
+
* @example
|
|
93
|
+
* // DirectedGraph topologicalSort for task scheduling
|
|
94
|
+
* const graph = new DirectedGraph<string>();
|
|
95
|
+
*
|
|
96
|
+
* // Build a DAG (Directed Acyclic Graph) for task dependencies
|
|
97
|
+
* graph.addVertex('Design');
|
|
98
|
+
* graph.addVertex('Implement');
|
|
99
|
+
* graph.addVertex('Test');
|
|
100
|
+
* graph.addVertex('Deploy');
|
|
101
|
+
*
|
|
102
|
+
* // Add dependency edges
|
|
103
|
+
* graph.addEdge('Design', 'Implement', 1); // Design must come before Implement
|
|
104
|
+
* graph.addEdge('Implement', 'Test', 1); // Implement must come before Test
|
|
105
|
+
* graph.addEdge('Test', 'Deploy', 1); // Test must come before Deploy
|
|
106
|
+
*
|
|
107
|
+
* // Topological sort gives valid execution order
|
|
108
|
+
* const executionOrder = graph.topologicalSort();
|
|
109
|
+
* console.log(executionOrder); // defined;
|
|
110
|
+
* console.log(executionOrder); // ['Design', 'Implement', 'Test', 'Deploy'];
|
|
111
|
+
*
|
|
112
|
+
* // All vertices should be included
|
|
113
|
+
* console.log(executionOrder?.length); // 4;
|
|
114
|
+
* @example
|
|
115
|
+
* // DirectedGraph dijkstra shortest path for network routing
|
|
116
|
+
* // Build a weighted directed graph representing network nodes and costs
|
|
117
|
+
* const network = new DirectedGraph<string>();
|
|
118
|
+
*
|
|
119
|
+
* // Add network nodes
|
|
120
|
+
* network.addVertex('Router-A');
|
|
121
|
+
* network.addVertex('Router-B');
|
|
122
|
+
* network.addVertex('Router-C');
|
|
123
|
+
* network.addVertex('Router-D');
|
|
124
|
+
* network.addVertex('Router-E');
|
|
125
|
+
*
|
|
126
|
+
* // Add weighted edges (network latency costs)
|
|
127
|
+
* network.addEdge('Router-A', 'Router-B', 5);
|
|
128
|
+
* network.addEdge('Router-A', 'Router-C', 10);
|
|
129
|
+
* network.addEdge('Router-B', 'Router-D', 3);
|
|
130
|
+
* network.addEdge('Router-C', 'Router-D', 2);
|
|
131
|
+
* network.addEdge('Router-D', 'Router-E', 4);
|
|
132
|
+
* network.addEdge('Router-B', 'Router-E', 12);
|
|
133
|
+
*
|
|
134
|
+
* // Find shortest path from Router-A to Router-E
|
|
135
|
+
* const { minDist, minPath } = network.dijkstra('Router-A', 'Router-E', true, true) || {
|
|
136
|
+
* minDist: undefined,
|
|
137
|
+
* minPath: undefined
|
|
138
|
+
* };
|
|
139
|
+
*
|
|
140
|
+
* // Verify shortest path is found
|
|
141
|
+
* console.log(minDist); // defined;
|
|
142
|
+
* console.log(minPath); // defined;
|
|
143
|
+
*
|
|
144
|
+
* // Shortest path should be A -> B -> D -> E with cost 5+3+4=12
|
|
145
|
+
* // Or A -> C -> D -> E with cost 10+2+4=16
|
|
146
|
+
* // So the minimum is 12
|
|
147
|
+
* console.log(minDist); // <= 16;
|
|
148
|
+
*
|
|
149
|
+
* // Verify path is valid (includes start and end)
|
|
150
|
+
* console.log(minPath?.[0].key); // 'Router-A';
|
|
151
|
+
* console.log(minPath?.[minPath.length - 1].key); // 'Router-E';
|
|
27
152
|
*/
|
|
28
153
|
export declare class DirectedGraph<V = any, E = any, VO extends DirectedVertex<V> = DirectedVertex<V>, EO extends DirectedEdge<E> = DirectedEdge<E>> extends AbstractGraph<V, E, VO, EO> implements IGraph<V, E, VO, EO> {
|
|
29
154
|
/**
|
|
@@ -22,7 +22,166 @@ export declare class UndirectedEdge<E = number> extends AbstractEdge<E> {
|
|
|
22
22
|
* @template VO - Concrete vertex class (extends AbstractVertex<V>).
|
|
23
23
|
* @template EO - Concrete edge class (extends AbstractEdge<E>).
|
|
24
24
|
* @remarks Time O(1), Space O(1)
|
|
25
|
-
* @example
|
|
25
|
+
* @example
|
|
26
|
+
* // basic UndirectedGraph vertex and edge creation
|
|
27
|
+
* // Create a simple undirected graph
|
|
28
|
+
* const graph = new UndirectedGraph<string>();
|
|
29
|
+
*
|
|
30
|
+
* // Add vertices
|
|
31
|
+
* graph.addVertex('A');
|
|
32
|
+
* graph.addVertex('B');
|
|
33
|
+
* graph.addVertex('C');
|
|
34
|
+
* graph.addVertex('D');
|
|
35
|
+
*
|
|
36
|
+
* // Verify vertices exist
|
|
37
|
+
* console.log(graph.hasVertex('A')); // true;
|
|
38
|
+
* console.log(graph.hasVertex('B')); // true;
|
|
39
|
+
* console.log(graph.hasVertex('E')); // false;
|
|
40
|
+
*
|
|
41
|
+
* // Check vertex count
|
|
42
|
+
* console.log(graph.size); // 4;
|
|
43
|
+
* @example
|
|
44
|
+
* // UndirectedGraph edge operations (bidirectional)
|
|
45
|
+
* const graph = new UndirectedGraph<string>();
|
|
46
|
+
*
|
|
47
|
+
* // Add vertices
|
|
48
|
+
* graph.addVertex('A');
|
|
49
|
+
* graph.addVertex('B');
|
|
50
|
+
* graph.addVertex('C');
|
|
51
|
+
*
|
|
52
|
+
* // Add undirected edges (both directions automatically)
|
|
53
|
+
* graph.addEdge('A', 'B', 1);
|
|
54
|
+
* graph.addEdge('B', 'C', 2);
|
|
55
|
+
* graph.addEdge('A', 'C', 3);
|
|
56
|
+
*
|
|
57
|
+
* // Verify edges exist in both directions
|
|
58
|
+
* console.log(graph.hasEdge('A', 'B')); // true;
|
|
59
|
+
* console.log(graph.hasEdge('B', 'A')); // true; // Bidirectional!
|
|
60
|
+
*
|
|
61
|
+
* console.log(graph.hasEdge('C', 'B')); // true;
|
|
62
|
+
* console.log(graph.hasEdge('B', 'C')); // true; // Bidirectional!
|
|
63
|
+
*
|
|
64
|
+
* // Get neighbors of A
|
|
65
|
+
* const neighborsA = graph.getNeighbors('A');
|
|
66
|
+
* console.log(neighborsA[0].key); // 'B';
|
|
67
|
+
* console.log(neighborsA[1].key); // 'C';
|
|
68
|
+
* @example
|
|
69
|
+
* // UndirectedGraph deleteEdge and vertex operations
|
|
70
|
+
* const graph = new UndirectedGraph<string>();
|
|
71
|
+
*
|
|
72
|
+
* // Build a simple undirected graph
|
|
73
|
+
* graph.addVertex('X');
|
|
74
|
+
* graph.addVertex('Y');
|
|
75
|
+
* graph.addVertex('Z');
|
|
76
|
+
* graph.addEdge('X', 'Y', 1);
|
|
77
|
+
* graph.addEdge('Y', 'Z', 2);
|
|
78
|
+
* graph.addEdge('X', 'Z', 3);
|
|
79
|
+
*
|
|
80
|
+
* // Delete an edge
|
|
81
|
+
* graph.deleteEdge('X', 'Y');
|
|
82
|
+
* console.log(graph.hasEdge('X', 'Y')); // false;
|
|
83
|
+
*
|
|
84
|
+
* // Bidirectional deletion confirmed
|
|
85
|
+
* console.log(graph.hasEdge('Y', 'X')); // false;
|
|
86
|
+
*
|
|
87
|
+
* // Other edges should remain
|
|
88
|
+
* console.log(graph.hasEdge('Y', 'Z')); // true;
|
|
89
|
+
* console.log(graph.hasEdge('Z', 'Y')); // true;
|
|
90
|
+
*
|
|
91
|
+
* // Delete a vertex
|
|
92
|
+
* graph.deleteVertex('Y');
|
|
93
|
+
* console.log(graph.hasVertex('Y')); // false;
|
|
94
|
+
* console.log(graph.size); // 2;
|
|
95
|
+
* @example
|
|
96
|
+
* // UndirectedGraph connectivity and neighbors
|
|
97
|
+
* const graph = new UndirectedGraph<string>();
|
|
98
|
+
*
|
|
99
|
+
* // Build a friendship network
|
|
100
|
+
* const people = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'];
|
|
101
|
+
* for (const person of people) {
|
|
102
|
+
* graph.addVertex(person);
|
|
103
|
+
* }
|
|
104
|
+
*
|
|
105
|
+
* // Add friendships (undirected edges)
|
|
106
|
+
* graph.addEdge('Alice', 'Bob', 1);
|
|
107
|
+
* graph.addEdge('Alice', 'Charlie', 1);
|
|
108
|
+
* graph.addEdge('Bob', 'Diana', 1);
|
|
109
|
+
* graph.addEdge('Charlie', 'Eve', 1);
|
|
110
|
+
* graph.addEdge('Diana', 'Eve', 1);
|
|
111
|
+
*
|
|
112
|
+
* // Get friends of each person
|
|
113
|
+
* const aliceFriends = graph.getNeighbors('Alice');
|
|
114
|
+
* console.log(aliceFriends[0].key); // 'Bob';
|
|
115
|
+
* console.log(aliceFriends[1].key); // 'Charlie';
|
|
116
|
+
* console.log(aliceFriends.length); // 2;
|
|
117
|
+
*
|
|
118
|
+
* const dianaFriends = graph.getNeighbors('Diana');
|
|
119
|
+
* console.log(dianaFriends[0].key); // 'Bob';
|
|
120
|
+
* console.log(dianaFriends[1].key); // 'Eve';
|
|
121
|
+
* console.log(dianaFriends.length); // 2;
|
|
122
|
+
*
|
|
123
|
+
* // Verify bidirectional friendship
|
|
124
|
+
* const bobFriends = graph.getNeighbors('Bob');
|
|
125
|
+
* console.log(bobFriends[0].key); // 'Alice'; // Alice -> Bob -> Alice ✓
|
|
126
|
+
* console.log(bobFriends[1].key); // 'Diana';
|
|
127
|
+
* @example
|
|
128
|
+
* // UndirectedGraph for social network connectivity analysis
|
|
129
|
+
* interface Person {
|
|
130
|
+
* id: number;
|
|
131
|
+
* name: string;
|
|
132
|
+
* location: string;
|
|
133
|
+
* }
|
|
134
|
+
*
|
|
135
|
+
* // UndirectedGraph is perfect for modeling symmetric relationships
|
|
136
|
+
* // (friendships, collaborations, partnerships)
|
|
137
|
+
* const socialNetwork = new UndirectedGraph<number, Person>();
|
|
138
|
+
*
|
|
139
|
+
* // Add people as vertices
|
|
140
|
+
* const people: [number, Person][] = [
|
|
141
|
+
* [1, { id: 1, name: 'Alice', location: 'New York' }],
|
|
142
|
+
* [2, { id: 2, name: 'Bob', location: 'San Francisco' }],
|
|
143
|
+
* [3, { id: 3, name: 'Charlie', location: 'Boston' }],
|
|
144
|
+
* [4, { id: 4, name: 'Diana', location: 'New York' }],
|
|
145
|
+
* [5, { id: 5, name: 'Eve', location: 'Seattle' }]
|
|
146
|
+
* ];
|
|
147
|
+
*
|
|
148
|
+
* for (const [id] of people) {
|
|
149
|
+
* socialNetwork.addVertex(id);
|
|
150
|
+
* }
|
|
151
|
+
*
|
|
152
|
+
* // Add friendships (automatically bidirectional)
|
|
153
|
+
* socialNetwork.addEdge(1, 2, 1); // Alice <-> Bob
|
|
154
|
+
* socialNetwork.addEdge(1, 3, 1); // Alice <-> Charlie
|
|
155
|
+
* socialNetwork.addEdge(2, 4, 1); // Bob <-> Diana
|
|
156
|
+
* socialNetwork.addEdge(3, 5, 1); // Charlie <-> Eve
|
|
157
|
+
* socialNetwork.addEdge(4, 5, 1); // Diana <-> Eve
|
|
158
|
+
*
|
|
159
|
+
* console.log(socialNetwork.size); // 5;
|
|
160
|
+
*
|
|
161
|
+
* // Find direct connections for Alice
|
|
162
|
+
* const aliceConnections = socialNetwork.getNeighbors(1);
|
|
163
|
+
* console.log(aliceConnections[0].key); // 2;
|
|
164
|
+
* console.log(aliceConnections[1].key); // 3;
|
|
165
|
+
* console.log(aliceConnections.length); // 2;
|
|
166
|
+
*
|
|
167
|
+
* // Verify bidirectional connections
|
|
168
|
+
* console.log(socialNetwork.hasEdge(1, 2)); // true;
|
|
169
|
+
* console.log(socialNetwork.hasEdge(2, 1)); // true; // Friendship works both ways!
|
|
170
|
+
*
|
|
171
|
+
* // Remove a person from network
|
|
172
|
+
* socialNetwork.deleteVertex(2); // Bob leaves
|
|
173
|
+
* console.log(socialNetwork.hasVertex(2)); // false;
|
|
174
|
+
* console.log(socialNetwork.size); // 4;
|
|
175
|
+
*
|
|
176
|
+
* // Alice loses Bob as a friend
|
|
177
|
+
* const updatedAliceConnections = socialNetwork.getNeighbors(1);
|
|
178
|
+
* console.log(updatedAliceConnections[0].key); // 3;
|
|
179
|
+
* console.log(updatedAliceConnections[1]); // undefined;
|
|
180
|
+
*
|
|
181
|
+
* // Diana loses Bob as a friend
|
|
182
|
+
* const dianaConnections = socialNetwork.getNeighbors(4);
|
|
183
|
+
* console.log(dianaConnections[0].key); // 5;
|
|
184
|
+
* console.log(dianaConnections[1]); // undefined;
|
|
26
185
|
*/
|
|
27
186
|
export declare class UndirectedGraph<V = any, E = any, VO extends UndirectedVertex<V> = UndirectedVertex<V>, EO extends UndirectedEdge<E> = UndirectedEdge<E>> extends AbstractGraph<V, E, VO, EO> implements IGraph<V, E, VO, EO> {
|
|
28
187
|
/**
|
|
@@ -20,7 +20,7 @@ import { IterableEntryBase } from '../base';
|
|
|
20
20
|
* 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.
|
|
21
21
|
* @example
|
|
22
22
|
* // should maintain insertion order
|
|
23
|
-
*
|
|
23
|
+
* const linkedHashMap = new LinkedHashMap<number, string>();
|
|
24
24
|
* linkedHashMap.set(1, 'A');
|
|
25
25
|
* linkedHashMap.set(2, 'B');
|
|
26
26
|
* linkedHashMap.set(3, 'C');
|
|
@@ -30,40 +30,123 @@ import { IterableEntryBase } from '../base';
|
|
|
30
30
|
* // [1, 'A'],
|
|
31
31
|
* // [2, 'B'],
|
|
32
32
|
* // [3, 'C']
|
|
33
|
-
* // ]
|
|
33
|
+
* // ];
|
|
34
34
|
* @example
|
|
35
|
-
* //
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
35
|
+
* // basic HashMap creation and set operation
|
|
36
|
+
* // Create a simple HashMap with key-value pairs
|
|
37
|
+
* const map = new HashMap<number, string>([
|
|
38
|
+
* [1, 'one'],
|
|
39
|
+
* [2, 'two'],
|
|
40
|
+
* [3, 'three']
|
|
41
|
+
* ]);
|
|
40
42
|
*
|
|
41
|
-
*
|
|
42
|
-
* console.log(
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* // Verify size
|
|
44
|
+
* console.log(map.size); // 3;
|
|
45
|
+
*
|
|
46
|
+
* // Set a new key-value pair
|
|
47
|
+
* map.set(4, 'four');
|
|
48
|
+
* console.log(map.size); // 4;
|
|
49
|
+
*
|
|
50
|
+
* // Verify entries
|
|
51
|
+
* console.log([...map.entries()]); // length: 4;
|
|
45
52
|
* @example
|
|
46
|
-
* //
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
53
|
+
* // HashMap get and has operations
|
|
54
|
+
* const map = new HashMap<string, number>([
|
|
55
|
+
* ['apple', 1],
|
|
56
|
+
* ['banana', 2],
|
|
57
|
+
* ['cherry', 3]
|
|
58
|
+
* ]);
|
|
59
|
+
*
|
|
60
|
+
* // Check if key exists
|
|
61
|
+
* console.log(map.has('apple')); // true;
|
|
62
|
+
* console.log(map.has('date')); // false;
|
|
51
63
|
*
|
|
52
|
-
*
|
|
53
|
-
* console.log(
|
|
54
|
-
* console.log(
|
|
64
|
+
* // Get value by key
|
|
65
|
+
* console.log(map.get('banana')); // 2;
|
|
66
|
+
* console.log(map.get('grape')); // undefined;
|
|
67
|
+
*
|
|
68
|
+
* // Get all keys and values
|
|
69
|
+
* const keys = [...map.keys()];
|
|
70
|
+
* const values = [...map.values()];
|
|
71
|
+
* console.log(keys); // contains 'apple';
|
|
72
|
+
* console.log(values); // contains 3;
|
|
55
73
|
* @example
|
|
56
|
-
* //
|
|
57
|
-
*
|
|
74
|
+
* // HashMap iteration and filter operations
|
|
75
|
+
* const map = new HashMap<number, string>([
|
|
76
|
+
* [1, 'Alice'],
|
|
77
|
+
* [2, 'Bob'],
|
|
78
|
+
* [3, 'Charlie'],
|
|
79
|
+
* [4, 'Diana'],
|
|
80
|
+
* [5, 'Eve']
|
|
81
|
+
* ]);
|
|
82
|
+
*
|
|
83
|
+
* // Iterate through entries
|
|
84
|
+
* const entries: [number, string][] = [];
|
|
85
|
+
* for (const [key, value] of map) {
|
|
86
|
+
* entries.push([key, value]);
|
|
87
|
+
* }
|
|
88
|
+
* console.log(entries); // length: 5;
|
|
89
|
+
*
|
|
90
|
+
* // Filter operation (for iteration with collection methods)
|
|
91
|
+
* const filtered = [...map].filter(([key]) => key > 2);
|
|
92
|
+
* console.log(filtered.length); // 3;
|
|
58
93
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
94
|
+
* // Map operation
|
|
95
|
+
* const values = [...map.values()].map(v => v.length);
|
|
96
|
+
* console.log(values); // contains 3; // 'Bob', 'Eve'
|
|
97
|
+
* console.log(values); // contains 7;
|
|
98
|
+
* @example
|
|
99
|
+
* // HashMap for user session caching O(1) performance
|
|
100
|
+
* interface UserSession {
|
|
101
|
+
* userId: number;
|
|
102
|
+
* username: string;
|
|
103
|
+
* loginTime: number;
|
|
104
|
+
* lastActivity: number;
|
|
62
105
|
* }
|
|
63
106
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
107
|
+
* // HashMap provides O(1) average-case performance for set/get/delete
|
|
108
|
+
* // Perfect for session management with fast lookups
|
|
109
|
+
* const sessionCache = new HashMap<string, UserSession>();
|
|
110
|
+
*
|
|
111
|
+
* // Simulate user sessions
|
|
112
|
+
* const sessions: [string, UserSession][] = [
|
|
113
|
+
* ['session_001', { userId: 1, username: 'alice', loginTime: 1000, lastActivity: 1050 }],
|
|
114
|
+
* ['session_002', { userId: 2, username: 'bob', loginTime: 1100, lastActivity: 1150 }],
|
|
115
|
+
* ['session_003', { userId: 3, username: 'charlie', loginTime: 1200, lastActivity: 1250 }]
|
|
116
|
+
* ];
|
|
117
|
+
*
|
|
118
|
+
* // Store sessions with O(1) insertion
|
|
119
|
+
* for (const [token, session] of sessions) {
|
|
120
|
+
* sessionCache.set(token, session);
|
|
121
|
+
* }
|
|
122
|
+
*
|
|
123
|
+
* console.log(sessionCache.size); // 3;
|
|
124
|
+
*
|
|
125
|
+
* // Retrieve session with O(1) lookup
|
|
126
|
+
* const userSession = sessionCache.get('session_001');
|
|
127
|
+
* console.log(userSession?.username); // 'alice';
|
|
128
|
+
* console.log(userSession?.userId); // 1;
|
|
129
|
+
*
|
|
130
|
+
* // Update session with O(1) operation
|
|
131
|
+
* if (userSession) {
|
|
132
|
+
* userSession.lastActivity = 2000;
|
|
133
|
+
* sessionCache.set('session_001', userSession);
|
|
134
|
+
* }
|
|
135
|
+
*
|
|
136
|
+
* // Check updated value
|
|
137
|
+
* const updated = sessionCache.get('session_001');
|
|
138
|
+
* console.log(updated?.lastActivity); // 2000;
|
|
139
|
+
*
|
|
140
|
+
* // Cleanup: delete expired sessions
|
|
141
|
+
* sessionCache.delete('session_002');
|
|
142
|
+
* console.log(sessionCache.has('session_002')); // false;
|
|
143
|
+
*
|
|
144
|
+
* // Verify remaining sessions
|
|
145
|
+
* console.log(sessionCache.size); // 2;
|
|
146
|
+
*
|
|
147
|
+
* // Get all active sessions
|
|
148
|
+
* const activeCount = [...sessionCache.values()].length;
|
|
149
|
+
* console.log(activeCount); // 2;
|
|
67
150
|
*/
|
|
68
151
|
export declare class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
|
|
69
152
|
/**
|
|
@@ -23,21 +23,107 @@ import { IterableElementBase } from '../base';
|
|
|
23
23
|
* 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.
|
|
24
24
|
* 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prime's minimum-spanning tree algorithm, which use heaps to improve performance.
|
|
25
25
|
* @example
|
|
26
|
-
* //
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
26
|
+
* // basic Heap creation and add operation
|
|
27
|
+
* // Create a min heap (default)
|
|
28
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
29
|
+
*
|
|
30
|
+
* // Verify size
|
|
31
|
+
* console.log(minHeap.size); // 6;
|
|
32
|
+
*
|
|
33
|
+
* // Add new element
|
|
34
|
+
* minHeap.add(4);
|
|
35
|
+
* console.log(minHeap.size); // 7;
|
|
36
|
+
*
|
|
37
|
+
* // Min heap property: smallest element at root
|
|
38
|
+
* const min = minHeap.peek();
|
|
39
|
+
* console.log(min); // 1;
|
|
40
|
+
* @example
|
|
41
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
42
|
+
* interface Task {
|
|
43
|
+
* id: number;
|
|
44
|
+
* priority: number;
|
|
45
|
+
* name: string;
|
|
46
|
+
* }
|
|
47
|
+
*
|
|
48
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
49
|
+
* const tasks: Task[] = [
|
|
50
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
51
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
52
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
53
|
+
* ];
|
|
54
|
+
*
|
|
55
|
+
* const maxHeap = new Heap(tasks, {
|
|
56
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* console.log(maxHeap.size); // 3;
|
|
60
|
+
*
|
|
61
|
+
* // Peek returns highest priority task
|
|
62
|
+
* const topTask = maxHeap.peek();
|
|
63
|
+
* console.log(topTask?.priority); // 8;
|
|
64
|
+
* console.log(topTask?.name); // 'Alert';
|
|
65
|
+
* @example
|
|
66
|
+
* // Heap for event processing with priority
|
|
67
|
+
* interface Event {
|
|
68
|
+
* id: number;
|
|
69
|
+
* type: 'critical' | 'warning' | 'info';
|
|
70
|
+
* timestamp: number;
|
|
71
|
+
* message: string;
|
|
72
|
+
* }
|
|
73
|
+
*
|
|
74
|
+
* // Custom priority: critical > warning > info
|
|
75
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
76
|
+
*
|
|
77
|
+
* const eventHeap = new Heap<Event>([], {
|
|
78
|
+
* comparator: (a: Event, b: Event) => {
|
|
79
|
+
* const priorityA = priorityMap[a.type];
|
|
80
|
+
* const priorityB = priorityMap[b.type];
|
|
81
|
+
* return priorityB - priorityA; // Higher priority first
|
|
82
|
+
* }
|
|
83
|
+
* });
|
|
84
|
+
*
|
|
85
|
+
* // Add events in random order
|
|
86
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
87
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
88
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
89
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
90
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
91
|
+
*
|
|
92
|
+
* console.log(eventHeap.size); // 5;
|
|
93
|
+
*
|
|
94
|
+
* // Process events by priority (critical first)
|
|
95
|
+
* const processedOrder: Event[] = [];
|
|
96
|
+
* while (eventHeap.size > 0) {
|
|
97
|
+
* const event = eventHeap.poll();
|
|
98
|
+
* if (event) {
|
|
99
|
+
* processedOrder.push(event);
|
|
32
100
|
* }
|
|
33
|
-
* return sorted;
|
|
34
101
|
* }
|
|
35
102
|
*
|
|
36
|
-
*
|
|
37
|
-
* console.log(
|
|
103
|
+
* // Verify critical events came first
|
|
104
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
105
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
106
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
107
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
108
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
109
|
+
*
|
|
110
|
+
* // Verify O(log n) operations
|
|
111
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
112
|
+
*
|
|
113
|
+
* // Add - O(log n)
|
|
114
|
+
* newHeap.add(2);
|
|
115
|
+
* console.log(newHeap.size); // 5;
|
|
116
|
+
*
|
|
117
|
+
* // Poll - O(log n)
|
|
118
|
+
* const removed = newHeap.poll();
|
|
119
|
+
* console.log(removed); // 1;
|
|
120
|
+
*
|
|
121
|
+
* // Peek - O(1)
|
|
122
|
+
* const top = newHeap.peek();
|
|
123
|
+
* console.log(top); // 2;
|
|
38
124
|
* @example
|
|
39
125
|
* // Use Heap to solve top k problems
|
|
40
|
-
*
|
|
126
|
+
* function topKElements(arr: number[], k: number): number[] {
|
|
41
127
|
* const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
|
|
42
128
|
* arr.forEach(num => {
|
|
43
129
|
* heap.add(num);
|
|
@@ -47,47 +133,10 @@ import { IterableElementBase } from '../base';
|
|
|
47
133
|
* }
|
|
48
134
|
*
|
|
49
135
|
* const numbers = [10, 30, 20, 5, 15, 25];
|
|
50
|
-
* console.log(topKElements(numbers, 3)); // [15, 10, 5]
|
|
51
|
-
* @example
|
|
52
|
-
* // Use Heap to merge sorted sequences
|
|
53
|
-
* function mergeSortedSequences(sequences: number[][]): number[] {
|
|
54
|
-
* const heap = new Heap<{ value: number; seqIndex: number; itemIndex: number }>([], {
|
|
55
|
-
* comparator: (a, b) => a.value - b.value // Min heap
|
|
56
|
-
* });
|
|
57
|
-
*
|
|
58
|
-
* // Initialize heap
|
|
59
|
-
* sequences.forEach((seq, seqIndex) => {
|
|
60
|
-
* if (seq.length) {
|
|
61
|
-
* heap.add({ value: seq[0], seqIndex, itemIndex: 0 });
|
|
62
|
-
* }
|
|
63
|
-
* });
|
|
64
|
-
*
|
|
65
|
-
* const merged: number[] = [];
|
|
66
|
-
* while (!heap.isEmpty()) {
|
|
67
|
-
* const { value, seqIndex, itemIndex } = heap.poll()!;
|
|
68
|
-
* merged.push(value);
|
|
69
|
-
*
|
|
70
|
-
* if (itemIndex + 1 < sequences[seqIndex].length) {
|
|
71
|
-
* heap.add({
|
|
72
|
-
* value: sequences[seqIndex][itemIndex + 1],
|
|
73
|
-
* seqIndex,
|
|
74
|
-
* itemIndex: itemIndex + 1
|
|
75
|
-
* });
|
|
76
|
-
* }
|
|
77
|
-
* }
|
|
78
|
-
*
|
|
79
|
-
* return merged;
|
|
80
|
-
* }
|
|
81
|
-
*
|
|
82
|
-
* const sequences = [
|
|
83
|
-
* [1, 4, 7],
|
|
84
|
-
* [2, 5, 8],
|
|
85
|
-
* [3, 6, 9]
|
|
86
|
-
* ];
|
|
87
|
-
* console.log(mergeSortedSequences(sequences)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
136
|
+
* console.log(topKElements(numbers, 3)); // [15, 10, 5];
|
|
88
137
|
* @example
|
|
89
138
|
* // Use Heap to dynamically maintain the median
|
|
90
|
-
*
|
|
139
|
+
* class MedianFinder {
|
|
91
140
|
* private low: MaxHeap<number>; // Max heap, stores the smaller half
|
|
92
141
|
* private high: MinHeap<number>; // Min heap, stores the larger half
|
|
93
142
|
*
|
|
@@ -113,18 +162,18 @@ import { IterableElementBase } from '../base';
|
|
|
113
162
|
*
|
|
114
163
|
* const medianFinder = new MedianFinder();
|
|
115
164
|
* medianFinder.addNum(10);
|
|
116
|
-
* console.log(medianFinder.findMedian()); // 10
|
|
165
|
+
* console.log(medianFinder.findMedian()); // 10;
|
|
117
166
|
* medianFinder.addNum(20);
|
|
118
|
-
* console.log(medianFinder.findMedian()); // 15
|
|
167
|
+
* console.log(medianFinder.findMedian()); // 15;
|
|
119
168
|
* medianFinder.addNum(30);
|
|
120
|
-
* console.log(medianFinder.findMedian()); // 20
|
|
169
|
+
* console.log(medianFinder.findMedian()); // 20;
|
|
121
170
|
* medianFinder.addNum(40);
|
|
122
|
-
* console.log(medianFinder.findMedian()); // 25
|
|
171
|
+
* console.log(medianFinder.findMedian()); // 25;
|
|
123
172
|
* medianFinder.addNum(50);
|
|
124
|
-
* console.log(medianFinder.findMedian()); // 30
|
|
173
|
+
* console.log(medianFinder.findMedian()); // 30;
|
|
125
174
|
* @example
|
|
126
175
|
* // Use Heap for load balancing
|
|
127
|
-
*
|
|
176
|
+
* function loadBalance(requests: number[], servers: number): number[] {
|
|
128
177
|
* const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
|
|
129
178
|
* const serverLoads = new Array(servers).fill(0);
|
|
130
179
|
*
|
|
@@ -143,10 +192,10 @@ import { IterableElementBase } from '../base';
|
|
|
143
192
|
* }
|
|
144
193
|
*
|
|
145
194
|
* const requests = [5, 2, 8, 3, 7];
|
|
146
|
-
* console.log(loadBalance(requests, 3)); // [12, 8, 5]
|
|
195
|
+
* console.log(loadBalance(requests, 3)); // [12, 8, 5];
|
|
147
196
|
* @example
|
|
148
197
|
* // Use Heap to schedule tasks
|
|
149
|
-
*
|
|
198
|
+
* type Task = [string, number];
|
|
150
199
|
*
|
|
151
200
|
* function scheduleTasks(tasks: Task[], machines: number): Map<number, Task[]> {
|
|
152
201
|
* const machineHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // Min heap
|
|
@@ -186,7 +235,7 @@ import { IterableElementBase } from '../base';
|
|
|
186
235
|
* ['Task3', 2],
|
|
187
236
|
* ['Task5', 4]
|
|
188
237
|
* ]);
|
|
189
|
-
* console.log(scheduleTasks(tasks, 2)); // expectedMap
|
|
238
|
+
* console.log(scheduleTasks(tasks, 2)); // expectedMap;
|
|
190
239
|
*/
|
|
191
240
|
export declare class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
192
241
|
protected _equals: (a: E, b: E) => boolean;
|