tree-multimap-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.
- package/dist/cjs/index.cjs +245 -72
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +246 -72
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +245 -72
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +246 -72
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree-counter.d.ts +2 -2
- package/dist/types/data-structures/binary-tree/avl-tree-multi-map.d.ts +5 -5
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +98 -5
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +103 -7
- package/dist/types/data-structures/binary-tree/bst.d.ts +202 -39
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +86 -37
- package/dist/types/data-structures/binary-tree/tree-counter.d.ts +4 -5
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +7 -7
- 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/types/types/data-structures/binary-tree/bst.d.ts +5 -5
- package/dist/umd/tree-multimap-typed.js +246 -72
- package/dist/umd/tree-multimap-typed.js.map +1 -1
- package/dist/umd/tree-multimap-typed.min.js +3 -3
- package/dist/umd/tree-multimap-typed.min.js.map +1 -1
- package/package.json +2 -2
- package/src/data-structures/binary-tree/avl-tree-counter.ts +1 -2
- package/src/data-structures/binary-tree/avl-tree-multi-map.ts +7 -8
- package/src/data-structures/binary-tree/avl-tree.ts +100 -7
- package/src/data-structures/binary-tree/binary-tree.ts +117 -7
- package/src/data-structures/binary-tree/bst.ts +431 -93
- package/src/data-structures/binary-tree/red-black-tree.ts +85 -37
- package/src/data-structures/binary-tree/tree-counter.ts +5 -7
- package/src/data-structures/binary-tree/tree-multi-map.ts +9 -10
- 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
- package/src/types/data-structures/binary-tree/bst.ts +5 -5
|
@@ -29,7 +29,7 @@ import { isWeakKey, rangeCheck } from '../../utils';
|
|
|
29
29
|
* 4. Unordered Collection: HashMap does not guarantee the order of entries, and the order may change over time.
|
|
30
30
|
* @example
|
|
31
31
|
* // should maintain insertion order
|
|
32
|
-
*
|
|
32
|
+
* const linkedHashMap = new LinkedHashMap<number, string>();
|
|
33
33
|
* linkedHashMap.set(1, 'A');
|
|
34
34
|
* linkedHashMap.set(2, 'B');
|
|
35
35
|
* linkedHashMap.set(3, 'C');
|
|
@@ -39,40 +39,123 @@ import { isWeakKey, rangeCheck } from '../../utils';
|
|
|
39
39
|
* // [1, 'A'],
|
|
40
40
|
* // [2, 'B'],
|
|
41
41
|
* // [3, 'C']
|
|
42
|
-
* // ]
|
|
42
|
+
* // ];
|
|
43
43
|
* @example
|
|
44
|
-
* //
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
44
|
+
* // basic HashMap creation and set operation
|
|
45
|
+
* // Create a simple HashMap with key-value pairs
|
|
46
|
+
* const map = new HashMap<number, string>([
|
|
47
|
+
* [1, 'one'],
|
|
48
|
+
* [2, 'two'],
|
|
49
|
+
* [3, 'three']
|
|
50
|
+
* ]);
|
|
49
51
|
*
|
|
50
|
-
*
|
|
51
|
-
* console.log(
|
|
52
|
-
*
|
|
53
|
-
*
|
|
52
|
+
* // Verify size
|
|
53
|
+
* console.log(map.size); // 3;
|
|
54
|
+
*
|
|
55
|
+
* // Set a new key-value pair
|
|
56
|
+
* map.set(4, 'four');
|
|
57
|
+
* console.log(map.size); // 4;
|
|
58
|
+
*
|
|
59
|
+
* // Verify entries
|
|
60
|
+
* console.log([...map.entries()]); // length: 4;
|
|
54
61
|
* @example
|
|
55
|
-
* //
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
62
|
+
* // HashMap get and has operations
|
|
63
|
+
* const map = new HashMap<string, number>([
|
|
64
|
+
* ['apple', 1],
|
|
65
|
+
* ['banana', 2],
|
|
66
|
+
* ['cherry', 3]
|
|
67
|
+
* ]);
|
|
68
|
+
*
|
|
69
|
+
* // Check if key exists
|
|
70
|
+
* console.log(map.has('apple')); // true;
|
|
71
|
+
* console.log(map.has('date')); // false;
|
|
60
72
|
*
|
|
61
|
-
*
|
|
62
|
-
* console.log(
|
|
63
|
-
* console.log(
|
|
73
|
+
* // Get value by key
|
|
74
|
+
* console.log(map.get('banana')); // 2;
|
|
75
|
+
* console.log(map.get('grape')); // undefined;
|
|
76
|
+
*
|
|
77
|
+
* // Get all keys and values
|
|
78
|
+
* const keys = [...map.keys()];
|
|
79
|
+
* const values = [...map.values()];
|
|
80
|
+
* console.log(keys); // contains 'apple';
|
|
81
|
+
* console.log(values); // contains 3;
|
|
64
82
|
* @example
|
|
65
|
-
* //
|
|
66
|
-
*
|
|
83
|
+
* // HashMap iteration and filter operations
|
|
84
|
+
* const map = new HashMap<number, string>([
|
|
85
|
+
* [1, 'Alice'],
|
|
86
|
+
* [2, 'Bob'],
|
|
87
|
+
* [3, 'Charlie'],
|
|
88
|
+
* [4, 'Diana'],
|
|
89
|
+
* [5, 'Eve']
|
|
90
|
+
* ]);
|
|
91
|
+
*
|
|
92
|
+
* // Iterate through entries
|
|
93
|
+
* const entries: [number, string][] = [];
|
|
94
|
+
* for (const [key, value] of map) {
|
|
95
|
+
* entries.push([key, value]);
|
|
96
|
+
* }
|
|
97
|
+
* console.log(entries); // length: 5;
|
|
98
|
+
*
|
|
99
|
+
* // Filter operation (for iteration with collection methods)
|
|
100
|
+
* const filtered = [...map].filter(([key]) => key > 2);
|
|
101
|
+
* console.log(filtered.length); // 3;
|
|
67
102
|
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
103
|
+
* // Map operation
|
|
104
|
+
* const values = [...map.values()].map(v => v.length);
|
|
105
|
+
* console.log(values); // contains 3; // 'Bob', 'Eve'
|
|
106
|
+
* console.log(values); // contains 7;
|
|
107
|
+
* @example
|
|
108
|
+
* // HashMap for user session caching O(1) performance
|
|
109
|
+
* interface UserSession {
|
|
110
|
+
* userId: number;
|
|
111
|
+
* username: string;
|
|
112
|
+
* loginTime: number;
|
|
113
|
+
* lastActivity: number;
|
|
71
114
|
* }
|
|
72
115
|
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
116
|
+
* // HashMap provides O(1) average-case performance for set/get/delete
|
|
117
|
+
* // Perfect for session management with fast lookups
|
|
118
|
+
* const sessionCache = new HashMap<string, UserSession>();
|
|
119
|
+
*
|
|
120
|
+
* // Simulate user sessions
|
|
121
|
+
* const sessions: [string, UserSession][] = [
|
|
122
|
+
* ['session_001', { userId: 1, username: 'alice', loginTime: 1000, lastActivity: 1050 }],
|
|
123
|
+
* ['session_002', { userId: 2, username: 'bob', loginTime: 1100, lastActivity: 1150 }],
|
|
124
|
+
* ['session_003', { userId: 3, username: 'charlie', loginTime: 1200, lastActivity: 1250 }]
|
|
125
|
+
* ];
|
|
126
|
+
*
|
|
127
|
+
* // Store sessions with O(1) insertion
|
|
128
|
+
* for (const [token, session] of sessions) {
|
|
129
|
+
* sessionCache.set(token, session);
|
|
130
|
+
* }
|
|
131
|
+
*
|
|
132
|
+
* console.log(sessionCache.size); // 3;
|
|
133
|
+
*
|
|
134
|
+
* // Retrieve session with O(1) lookup
|
|
135
|
+
* const userSession = sessionCache.get('session_001');
|
|
136
|
+
* console.log(userSession?.username); // 'alice';
|
|
137
|
+
* console.log(userSession?.userId); // 1;
|
|
138
|
+
*
|
|
139
|
+
* // Update session with O(1) operation
|
|
140
|
+
* if (userSession) {
|
|
141
|
+
* userSession.lastActivity = 2000;
|
|
142
|
+
* sessionCache.set('session_001', userSession);
|
|
143
|
+
* }
|
|
144
|
+
*
|
|
145
|
+
* // Check updated value
|
|
146
|
+
* const updated = sessionCache.get('session_001');
|
|
147
|
+
* console.log(updated?.lastActivity); // 2000;
|
|
148
|
+
*
|
|
149
|
+
* // Cleanup: delete expired sessions
|
|
150
|
+
* sessionCache.delete('session_002');
|
|
151
|
+
* console.log(sessionCache.has('session_002')); // false;
|
|
152
|
+
*
|
|
153
|
+
* // Verify remaining sessions
|
|
154
|
+
* console.log(sessionCache.size); // 2;
|
|
155
|
+
*
|
|
156
|
+
* // Get all active sessions
|
|
157
|
+
* const activeCount = [...sessionCache.values()].length;
|
|
158
|
+
* console.log(activeCount); // 2;
|
|
76
159
|
*/
|
|
77
160
|
export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K, V> {
|
|
78
161
|
/**
|
|
@@ -25,21 +25,107 @@ import { IterableElementBase } from '../base';
|
|
|
25
25
|
* 7. Efficient Sorting Algorithms: For example, heap sort. Heap sort uses the properties of a heap to sort elements.
|
|
26
26
|
* 8. Graph Algorithms: Such as Dijkstra's shortest path algorithm and Prime's minimum-spanning tree algorithm, which use heaps to improve performance.
|
|
27
27
|
* @example
|
|
28
|
-
* //
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
28
|
+
* // basic Heap creation and add operation
|
|
29
|
+
* // Create a min heap (default)
|
|
30
|
+
* const minHeap = new Heap([5, 3, 7, 1, 9, 2]);
|
|
31
|
+
*
|
|
32
|
+
* // Verify size
|
|
33
|
+
* console.log(minHeap.size); // 6;
|
|
34
|
+
*
|
|
35
|
+
* // Add new element
|
|
36
|
+
* minHeap.add(4);
|
|
37
|
+
* console.log(minHeap.size); // 7;
|
|
38
|
+
*
|
|
39
|
+
* // Min heap property: smallest element at root
|
|
40
|
+
* const min = minHeap.peek();
|
|
41
|
+
* console.log(min); // 1;
|
|
42
|
+
* @example
|
|
43
|
+
* // Heap with custom comparator (MaxHeap behavior)
|
|
44
|
+
* interface Task {
|
|
45
|
+
* id: number;
|
|
46
|
+
* priority: number;
|
|
47
|
+
* name: string;
|
|
48
|
+
* }
|
|
49
|
+
*
|
|
50
|
+
* // Custom comparator for max heap behavior (higher priority first)
|
|
51
|
+
* const tasks: Task[] = [
|
|
52
|
+
* { id: 1, priority: 5, name: 'Email' },
|
|
53
|
+
* { id: 2, priority: 3, name: 'Chat' },
|
|
54
|
+
* { id: 3, priority: 8, name: 'Alert' }
|
|
55
|
+
* ];
|
|
56
|
+
*
|
|
57
|
+
* const maxHeap = new Heap(tasks, {
|
|
58
|
+
* comparator: (a: Task, b: Task) => b.priority - a.priority
|
|
59
|
+
* });
|
|
60
|
+
*
|
|
61
|
+
* console.log(maxHeap.size); // 3;
|
|
62
|
+
*
|
|
63
|
+
* // Peek returns highest priority task
|
|
64
|
+
* const topTask = maxHeap.peek();
|
|
65
|
+
* console.log(topTask?.priority); // 8;
|
|
66
|
+
* console.log(topTask?.name); // 'Alert';
|
|
67
|
+
* @example
|
|
68
|
+
* // Heap for event processing with priority
|
|
69
|
+
* interface Event {
|
|
70
|
+
* id: number;
|
|
71
|
+
* type: 'critical' | 'warning' | 'info';
|
|
72
|
+
* timestamp: number;
|
|
73
|
+
* message: string;
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* // Custom priority: critical > warning > info
|
|
77
|
+
* const priorityMap = { critical: 3, warning: 2, info: 1 };
|
|
78
|
+
*
|
|
79
|
+
* const eventHeap = new Heap<Event>([], {
|
|
80
|
+
* comparator: (a: Event, b: Event) => {
|
|
81
|
+
* const priorityA = priorityMap[a.type];
|
|
82
|
+
* const priorityB = priorityMap[b.type];
|
|
83
|
+
* return priorityB - priorityA; // Higher priority first
|
|
84
|
+
* }
|
|
85
|
+
* });
|
|
86
|
+
*
|
|
87
|
+
* // Add events in random order
|
|
88
|
+
* eventHeap.add({ id: 1, type: 'info', timestamp: 100, message: 'User logged in' });
|
|
89
|
+
* eventHeap.add({ id: 2, type: 'critical', timestamp: 101, message: 'Server down' });
|
|
90
|
+
* eventHeap.add({ id: 3, type: 'warning', timestamp: 102, message: 'High memory' });
|
|
91
|
+
* eventHeap.add({ id: 4, type: 'info', timestamp: 103, message: 'Cache cleared' });
|
|
92
|
+
* eventHeap.add({ id: 5, type: 'critical', timestamp: 104, message: 'Database error' });
|
|
93
|
+
*
|
|
94
|
+
* console.log(eventHeap.size); // 5;
|
|
95
|
+
*
|
|
96
|
+
* // Process events by priority (critical first)
|
|
97
|
+
* const processedOrder: Event[] = [];
|
|
98
|
+
* while (eventHeap.size > 0) {
|
|
99
|
+
* const event = eventHeap.poll();
|
|
100
|
+
* if (event) {
|
|
101
|
+
* processedOrder.push(event);
|
|
34
102
|
* }
|
|
35
|
-
* return sorted;
|
|
36
103
|
* }
|
|
37
104
|
*
|
|
38
|
-
*
|
|
39
|
-
* console.log(
|
|
105
|
+
* // Verify critical events came first
|
|
106
|
+
* console.log(processedOrder[0].type); // 'critical';
|
|
107
|
+
* console.log(processedOrder[1].type); // 'critical';
|
|
108
|
+
* console.log(processedOrder[2].type); // 'warning';
|
|
109
|
+
* console.log(processedOrder[3].type); // 'info';
|
|
110
|
+
* console.log(processedOrder[4].type); // 'info';
|
|
111
|
+
*
|
|
112
|
+
* // Verify O(log n) operations
|
|
113
|
+
* const newHeap = new Heap<number>([5, 3, 7, 1]);
|
|
114
|
+
*
|
|
115
|
+
* // Add - O(log n)
|
|
116
|
+
* newHeap.add(2);
|
|
117
|
+
* console.log(newHeap.size); // 5;
|
|
118
|
+
*
|
|
119
|
+
* // Poll - O(log n)
|
|
120
|
+
* const removed = newHeap.poll();
|
|
121
|
+
* console.log(removed); // 1;
|
|
122
|
+
*
|
|
123
|
+
* // Peek - O(1)
|
|
124
|
+
* const top = newHeap.peek();
|
|
125
|
+
* console.log(top); // 2;
|
|
40
126
|
* @example
|
|
41
127
|
* // Use Heap to solve top k problems
|
|
42
|
-
*
|
|
128
|
+
* function topKElements(arr: number[], k: number): number[] {
|
|
43
129
|
* const heap = new Heap<number>([], { comparator: (a, b) => b - a }); // Max heap
|
|
44
130
|
* arr.forEach(num => {
|
|
45
131
|
* heap.add(num);
|
|
@@ -49,47 +135,10 @@ import { IterableElementBase } from '../base';
|
|
|
49
135
|
* }
|
|
50
136
|
*
|
|
51
137
|
* const numbers = [10, 30, 20, 5, 15, 25];
|
|
52
|
-
* console.log(topKElements(numbers, 3)); // [15, 10, 5]
|
|
53
|
-
* @example
|
|
54
|
-
* // Use Heap to merge sorted sequences
|
|
55
|
-
* function mergeSortedSequences(sequences: number[][]): number[] {
|
|
56
|
-
* const heap = new Heap<{ value: number; seqIndex: number; itemIndex: number }>([], {
|
|
57
|
-
* comparator: (a, b) => a.value - b.value // Min heap
|
|
58
|
-
* });
|
|
59
|
-
*
|
|
60
|
-
* // Initialize heap
|
|
61
|
-
* sequences.forEach((seq, seqIndex) => {
|
|
62
|
-
* if (seq.length) {
|
|
63
|
-
* heap.add({ value: seq[0], seqIndex, itemIndex: 0 });
|
|
64
|
-
* }
|
|
65
|
-
* });
|
|
66
|
-
*
|
|
67
|
-
* const merged: number[] = [];
|
|
68
|
-
* while (!heap.isEmpty()) {
|
|
69
|
-
* const { value, seqIndex, itemIndex } = heap.poll()!;
|
|
70
|
-
* merged.push(value);
|
|
71
|
-
*
|
|
72
|
-
* if (itemIndex + 1 < sequences[seqIndex].length) {
|
|
73
|
-
* heap.add({
|
|
74
|
-
* value: sequences[seqIndex][itemIndex + 1],
|
|
75
|
-
* seqIndex,
|
|
76
|
-
* itemIndex: itemIndex + 1
|
|
77
|
-
* });
|
|
78
|
-
* }
|
|
79
|
-
* }
|
|
80
|
-
*
|
|
81
|
-
* return merged;
|
|
82
|
-
* }
|
|
83
|
-
*
|
|
84
|
-
* const sequences = [
|
|
85
|
-
* [1, 4, 7],
|
|
86
|
-
* [2, 5, 8],
|
|
87
|
-
* [3, 6, 9]
|
|
88
|
-
* ];
|
|
89
|
-
* console.log(mergeSortedSequences(sequences)); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
138
|
+
* console.log(topKElements(numbers, 3)); // [15, 10, 5];
|
|
90
139
|
* @example
|
|
91
140
|
* // Use Heap to dynamically maintain the median
|
|
92
|
-
*
|
|
141
|
+
* class MedianFinder {
|
|
93
142
|
* private low: MaxHeap<number>; // Max heap, stores the smaller half
|
|
94
143
|
* private high: MinHeap<number>; // Min heap, stores the larger half
|
|
95
144
|
*
|
|
@@ -115,18 +164,18 @@ import { IterableElementBase } from '../base';
|
|
|
115
164
|
*
|
|
116
165
|
* const medianFinder = new MedianFinder();
|
|
117
166
|
* medianFinder.addNum(10);
|
|
118
|
-
* console.log(medianFinder.findMedian()); // 10
|
|
167
|
+
* console.log(medianFinder.findMedian()); // 10;
|
|
119
168
|
* medianFinder.addNum(20);
|
|
120
|
-
* console.log(medianFinder.findMedian()); // 15
|
|
169
|
+
* console.log(medianFinder.findMedian()); // 15;
|
|
121
170
|
* medianFinder.addNum(30);
|
|
122
|
-
* console.log(medianFinder.findMedian()); // 20
|
|
171
|
+
* console.log(medianFinder.findMedian()); // 20;
|
|
123
172
|
* medianFinder.addNum(40);
|
|
124
|
-
* console.log(medianFinder.findMedian()); // 25
|
|
173
|
+
* console.log(medianFinder.findMedian()); // 25;
|
|
125
174
|
* medianFinder.addNum(50);
|
|
126
|
-
* console.log(medianFinder.findMedian()); // 30
|
|
175
|
+
* console.log(medianFinder.findMedian()); // 30;
|
|
127
176
|
* @example
|
|
128
177
|
* // Use Heap for load balancing
|
|
129
|
-
*
|
|
178
|
+
* function loadBalance(requests: number[], servers: number): number[] {
|
|
130
179
|
* const serverHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // min heap
|
|
131
180
|
* const serverLoads = new Array(servers).fill(0);
|
|
132
181
|
*
|
|
@@ -145,10 +194,10 @@ import { IterableElementBase } from '../base';
|
|
|
145
194
|
* }
|
|
146
195
|
*
|
|
147
196
|
* const requests = [5, 2, 8, 3, 7];
|
|
148
|
-
* console.log(loadBalance(requests, 3)); // [12, 8, 5]
|
|
197
|
+
* console.log(loadBalance(requests, 3)); // [12, 8, 5];
|
|
149
198
|
* @example
|
|
150
199
|
* // Use Heap to schedule tasks
|
|
151
|
-
*
|
|
200
|
+
* type Task = [string, number];
|
|
152
201
|
*
|
|
153
202
|
* function scheduleTasks(tasks: Task[], machines: number): Map<number, Task[]> {
|
|
154
203
|
* const machineHeap = new Heap<{ id: number; load: number }>([], { comparator: (a, b) => a.load - b.load }); // Min heap
|
|
@@ -188,7 +237,7 @@ import { IterableElementBase } from '../base';
|
|
|
188
237
|
* ['Task3', 2],
|
|
189
238
|
* ['Task5', 4]
|
|
190
239
|
* ]);
|
|
191
|
-
* console.log(scheduleTasks(tasks, 2)); // expectedMap
|
|
240
|
+
* console.log(scheduleTasks(tasks, 2)); // expectedMap;
|
|
192
241
|
*/
|
|
193
242
|
export class Heap<E = any, R = any> extends IterableElementBase<E, R> {
|
|
194
243
|
protected _equals: (a: E, b: E) => boolean = Object.is;
|