data-structure-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/CHANGELOG.md +3 -1
- package/README.md +355 -1672
- package/README_CN.md +509 -0
- package/SECURITY.md +962 -11
- package/SECURITY.zh-CN.md +966 -0
- package/SPECIFICATION.md +689 -30
- package/SPECIFICATION.zh-CN.md +715 -0
- package/SPONSOR.zh-CN.md +62 -0
- package/SPONSOR_POLISHED.md +62 -0
- package/benchmark/report.html +1 -1
- package/benchmark/report.json +215 -172
- 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/data-structure-typed.js +246 -72
- package/dist/umd/data-structure-typed.js.map +1 -1
- package/dist/umd/data-structure-typed.min.js +3 -3
- package/dist/umd/data-structure-typed.min.js.map +1 -1
- package/package.json +3 -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
- package/test/performance/benchmark-runner.ts +14 -11
- package/test/performance/data-structures/binary-tree/avl-tree.test.ts +8 -8
- package/test/performance/data-structures/binary-tree/binary-tree-overall.test.ts +8 -8
- package/test/performance/data-structures/binary-tree/binary-tree.test.ts +6 -6
- package/test/performance/data-structures/binary-tree/bst.test.ts +5 -5
- package/test/performance/data-structures/binary-tree/red-black-tree.test.ts +10 -10
- package/test/performance/reportor.ts +2 -1
- package/test/performance/single-suite-runner.ts +7 -4
- package/test/unit/data-structures/binary-tree/avl-tree-counter.test.ts +2 -2
- package/test/unit/data-structures/binary-tree/avl-tree.test.ts +117 -0
- package/test/unit/data-structures/binary-tree/binary-tree.test.ts +166 -0
- package/test/unit/data-structures/binary-tree/bst.test.ts +771 -16
- package/test/unit/data-structures/binary-tree/overall.test.ts +2 -2
- package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +90 -38
- package/test/unit/data-structures/binary-tree/tree-multi-map.test.ts +2 -2
- package/test/unit/data-structures/graph/directed-graph.test.ts +133 -0
- package/test/unit/data-structures/graph/undirected-graph.test.ts +167 -0
- package/test/unit/data-structures/hash/hash-map.test.ts +149 -3
- package/test/unit/data-structures/heap/heap.test.ts +182 -47
- package/test/unit/data-structures/linked-list/doubly-linked-list.test.ts +118 -14
- package/test/unit/data-structures/linked-list/singly-linked-list.test.ts +121 -0
- package/test/unit/data-structures/queue/deque.test.ts +98 -67
- package/test/unit/data-structures/queue/queue.test.ts +85 -51
- package/test/unit/data-structures/stack/stack.test.ts +142 -33
- package/test/unit/data-structures/trie/trie.test.ts +135 -39
- package/tsup.leetcode.config.js +99 -0
- package/typedoc.json +2 -1
- package/POSTS_zh-CN.md +0 -54
- package/README_zh-CN.md +0 -1208
- package/SPECIFICATION_zh-CN.md +0 -81
package/README.md
CHANGED
|
@@ -1,1889 +1,572 @@
|
|
|
1
|
-
# data-structure-typed
|
|
1
|
+
# README: data-structure-typed Library
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-

|
|
5
|
-

|
|
6
|
-

|
|
7
|
-

|
|
8
|
-

|
|
9
|
-

|
|
10
|
-

|
|
11
|
-
|
|
12
|
-
### 🏠 Uniform API: Coding feels like home.
|
|
13
|
-
> Don't learn new APIs. Just use `push`, `pop`, `map`, `filter`, and `reduce` everywhere.
|
|
14
|
-
|
|
15
|
-
### ⚡ High Performance: Speed without compromise.
|
|
16
|
-
> Benchmarks prove it. We outperform native implementations in critical scenarios.
|
|
17
|
-
|
|
18
|
-
### 🛡️ Type Safe: TypeScript first, always.
|
|
19
|
-
> No more `any`. Enjoy full generics and strict type checking out of the box.
|
|
20
|
-
|
|
21
|
-
### ✨ Zero Friction: It just plays nice.
|
|
22
|
-
> Works with everything. Spread it `[...]`, loop it `for..of`, or convert it instantly.
|
|
23
|
-
|
|
24
|
-
## Installation and Usage
|
|
25
|
-
|
|
26
|
-
### pnpm
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
pnpm add data-structure-typed
|
|
30
|
-
```
|
|
31
|
-
### Playground
|
|
32
|
-
|
|
33
|
-
[Node.js TypeScript](https://stackblitz.com/edit/stackblitz-starters-e1vdy3zw?file=src%2Findex.ts)
|
|
34
|
-
|
|
35
|
-
[Node.js JavaScript](https://stackblitz.com/edit/stackblitz-starters-dgvchziu?file=src%2Findex.js)
|
|
36
|
-
|
|
37
|
-
[React TypeScript](https://stackblitz.com/edit/vitejs-vite-6xvhtdua?file=src%2FApp.tsx)
|
|
38
|
-
|
|
39
|
-
[NestJS TypeScript](https://stackblitz.com/edit/nestjs-typescript-starter-3cyp7pel?file=src%2Franking%2Franking.service.ts&terminal=start:dev)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
### npm
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
npm i data-structure-typed --save
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### yarn
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
yarn add data-structure-typed
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Individual Data Structure Installation
|
|
55
|
-
|
|
56
|
-
If you only want to use a specific data structure independently:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
npm i heap-typed --save
|
|
60
|
-
npm i bst-typed --save
|
|
61
|
-
npm i red-black-tree-typed --save
|
|
62
|
-
```
|
|
3
|
+
A comprehensive TypeScript data structures library with production-ready implementations.
|
|
63
4
|
|
|
5
|
+
**📚 [Quick Start](#-quick-start-30-seconds) • [Installation](#-installation) • [Full Docs](./docs/CONCEPTS.md) • [API Reference](./docs/REFERENCE.md) • [Playground](#-playground) • [Installation](#-installation) • [Examples](./docs/GUIDES.md)**
|
|
64
6
|
|
|
65
7
|
---
|
|
66
8
|
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
Choose your learning path based on your needs:
|
|
70
|
-
|
|
71
|
-
### 👤 I'm New Here
|
|
72
|
-
|
|
73
|
-
- ⏱️ **3 Minutes to Productivity**: [Quick Start](#quick-start-3-minutes-to-productivity)
|
|
74
|
-
- 🎓 **Full Understanding**: [Why data-structure-typed?](#why-data-structure-typed)
|
|
75
|
-
- 💻 **Show Me Code**: [Code Snippets](#code-snippets-patterns--examples)
|
|
76
|
-
|
|
77
|
-
### 🤔 Not Sure Which Data Structure to Use?
|
|
78
|
-
|
|
79
|
-
- 🎯 **Decision Guide**: [Choose Your Data Structure](#-decision-guide-choose-the-right-data-structure)
|
|
80
|
-
- 📚 **Data Structures Overview**: [Complete List](#-data-structures-available)
|
|
81
|
-
|
|
82
|
-
### 🔄 Migrating from Native JavaScript?
|
|
83
|
-
|
|
84
|
-
- 📋 **Migration Guide**: [From Array to Specialized Structures](#-migration-guide-from-native-js)
|
|
85
|
-
- 🚀 **Integration Examples**: [React, Express, Nest.js](#-integration-examples)
|
|
9
|
+
## Table of Contents
|
|
86
10
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
- 🔗 **Framework Integration**: [React, Vue, Express, Nest.js, Next.js](#-integration-examples)
|
|
95
|
-
- 🛠️ **Multi-Environment**: [CDN/CommonJS/ESModule/TypeScript](#supported-module-system)
|
|
11
|
+
1. [Who Should Use This?](#-who-should-use-this)
|
|
12
|
+
2. [Why Not Just Array or Map?](#-why-not-just-array-or-map)
|
|
13
|
+
3. [Key Features](#-key-features)
|
|
14
|
+
4. [Installation](#-installation)
|
|
15
|
+
5. [Quick Start](#-quick-start-30-seconds)
|
|
16
|
+
6. [Data Structures](#-data-structures-available)
|
|
17
|
+
7. [Documentation](#-documentation)
|
|
96
18
|
|
|
97
19
|
---
|
|
98
20
|
|
|
21
|
+
## 🎯 Who Should Use This?
|
|
99
22
|
|
|
100
|
-
|
|
23
|
+
**If you are building ranked collections, scheduling queues, or sorted data structures in TypeScript,**
|
|
24
|
+
**consider `data-structure-typed` instead of hand-rolled Arrays or Maps.**
|
|
101
25
|
|
|
102
|
-
|
|
103
|
-
import {
|
|
104
|
-
Heap, Graph, Queue, Deque, PriorityQueue, BST, Trie, DoublyLinkedList,
|
|
105
|
-
AVLTree, SinglyLinkedList, DirectedGraph, RedBlackTree, TreeMultiMap,
|
|
106
|
-
DirectedVertex, Stack, AVLTreeNode
|
|
107
|
-
} from 'data-structure-typed';
|
|
26
|
+
### Perfect for:
|
|
108
27
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
28
|
+
- **Leaderboards & Rankings** — Maintain top-K efficiently without repeated sorting
|
|
29
|
+
- **Task Scheduling** — Priority queues, ordered execution, time-based operations
|
|
30
|
+
- **Real-Time Dashboards** — Grafana-style workloads with instant lookups
|
|
31
|
+
- **Time-Series Data** — Sorted insertion + fast range queries
|
|
32
|
+
- **Search & Autocomplete** — Prefix matching at scale
|
|
33
|
+
- **Graph Problems** — Pathfinding, cycle detection, topological sorting
|
|
113
34
|
|
|
114
35
|
---
|
|
115
36
|
|
|
116
|
-
##
|
|
37
|
+
## ⚡ Why Not Just Array or Map?
|
|
117
38
|
|
|
118
|
-
|
|
39
|
+
| Use Case | Array | Map | data-structure-typed |
|
|
40
|
+
|------------------------|----------------------|------------------|:--------------------:|
|
|
41
|
+
| **Sorted Lookup** | ❌ O(n) | ❌ Unordered | ✅ **O(log n)** |
|
|
42
|
+
| **Insert at Position** | ❌ O(n) shift | ❌ No position | ✅ **O(log n)** |
|
|
43
|
+
| **Leaderboard Top-K** | ❌ Re-sort O(n log n) | ❌ Manual sort | ✅ **Instant** |
|
|
44
|
+
| **Remove from Front** | ❌ O(n) | ❌ No dequeue | ✅ **O(1)** |
|
|
45
|
+
| **Prefix Search** | ❌ O(n*m) | ❌ Not applicable | ✅ **O(m + k)** |
|
|
46
|
+
| **Familiar API** | ✅ Yes | ✅ Yes | ✅ **Same** |
|
|
119
47
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
❌ This is slow with Array:
|
|
48
|
+
### Real-World Pain Point
|
|
123
49
|
|
|
124
50
|
```javascript
|
|
125
|
-
|
|
126
|
-
queue
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
✅ This is fast with Deque:
|
|
130
|
-
|
|
131
|
-
```javascript
|
|
132
|
-
import { Deque } from 'data-structure-typed';
|
|
133
|
-
|
|
134
|
-
const deque = new Deque([1, 2, 3, 4, 5]);
|
|
135
|
-
deque.shift(); // O(1) - Just moves a pointer
|
|
136
|
-
deque.print(); // [2, 3, 4, 5]
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
### Scenario 2: Sorted Data with Fast Lookups
|
|
142
|
-
|
|
143
|
-
**Problem**: You need to maintain sorted data and query it efficiently.
|
|
144
|
-
|
|
145
|
-
❌ Array requires manual sorting:
|
|
146
|
-
|
|
147
|
-
```javascript
|
|
148
|
-
const arr = [5, 2, 8, 1, 9];
|
|
149
|
-
arr.includes(3); // O(n) - Must check every element
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
✅ RedBlackTree maintains sorted order automatically:
|
|
153
|
-
|
|
154
|
-
```javascript
|
|
155
|
-
import { RedBlackTree } from 'data-structure-typed';
|
|
156
|
-
|
|
157
|
-
const tree = new RedBlackTree([5, 2, 8, 1, 9]);
|
|
158
|
-
tree.has(3); // O(log n) - Logarithmic search
|
|
159
|
-
|
|
160
|
-
// Iterating tree is already sorted
|
|
161
|
-
for (const [key] of tree) {
|
|
162
|
-
console.log(key); // 1, 2, 5, 8, 9 (automatically sorted!)
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
### Scenario 3: Priority Queue
|
|
169
|
-
|
|
170
|
-
**Problem**: Process items by priority, not insertion order.
|
|
171
|
-
|
|
172
|
-
❌ Array requires re-sorting:
|
|
173
|
-
|
|
174
|
-
```javascript
|
|
175
|
-
const tasks = [];
|
|
176
|
-
|
|
177
|
-
function addTask(task) {
|
|
178
|
-
tasks.push(task);
|
|
179
|
-
tasks.sort((a, b) => b.priority - a.priority); // O(n log n) every time!
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
✅ PriorityQueue maintains priority automatically:
|
|
184
|
-
|
|
185
|
-
```javascript
|
|
186
|
-
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
187
|
-
|
|
188
|
-
const pq = new MaxPriorityQueue([], {
|
|
189
|
-
comparator: (a, b) => b.priority - a.priority,
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
function addTask(task) {
|
|
193
|
-
pq.add(task); // O(log n)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const nextTask = pq.poll(); // Always get highest priority
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
### Scenario 4: Prefix Matching (Autocomplete)
|
|
202
|
-
|
|
203
|
-
**Problem**: Fast prefix searching in large dictionaries.
|
|
204
|
-
|
|
205
|
-
```javascript
|
|
206
|
-
import { Trie } from 'data-structure-typed';
|
|
207
|
-
|
|
208
|
-
const dictionary = new Trie(['apple', 'app', 'apply', 'application']);
|
|
209
|
-
|
|
210
|
-
const suggestions = dictionary.getWords('appl');
|
|
211
|
-
// Returns: ['apple', 'apply', 'application']
|
|
212
|
-
// Time: O(m + k) where m is prefix length, k is results
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
---
|
|
216
|
-
|
|
217
|
-
### Scenario 5: Graph Algorithms
|
|
218
|
-
|
|
219
|
-
**Problem**: Pathfinding or cycle detection.
|
|
220
|
-
|
|
221
|
-
```javascript
|
|
222
|
-
import { DirectedGraph } from 'data-structure-typed';
|
|
223
|
-
|
|
224
|
-
const graph = new DirectedGraph();
|
|
225
|
-
graph.addVertex('A');
|
|
226
|
-
graph.addVertex('B');
|
|
227
|
-
graph.addEdge('A', 'B', 1);
|
|
228
|
-
|
|
229
|
-
const { minDist, minPath } = graph.dijkstra('A', 'B', true, true);
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## Why data-structure-typed?
|
|
235
|
-
|
|
236
|
-
> All data structures in JavaScript should work like native Array.
|
|
237
|
-
> No more API chaos. No more conversions. No more frustration.
|
|
238
|
-
|
|
239
|
-
### Three Pain Points Every Developer Faces
|
|
240
|
-
|
|
241
|
-
#### 1️⃣ Performance Wall: When Operations Become Bottlenecks
|
|
242
|
-
|
|
243
|
-
❌ The Problem: Array.shift() is O(n):
|
|
244
|
-
|
|
245
|
-
```javascript
|
|
246
|
-
const queue = [1, 2, 3, ..., 100000];
|
|
51
|
+
// ❌ WITHOUT data-structure-typed
|
|
52
|
+
const queue = [1, 2, 3, ..., 100000
|
|
53
|
+
]
|
|
54
|
+
;
|
|
247
55
|
for (let i = 0; i < 100000; i++) {
|
|
248
|
-
queue.shift(); // Reindexes
|
|
56
|
+
queue.shift(); // O(n) - Reindexes EVERY element!
|
|
249
57
|
}
|
|
250
|
-
// Time: 2829ms
|
|
251
|
-
// Impact: Timeout, failed test
|
|
58
|
+
// Time: 2829ms ❌
|
|
252
59
|
```
|
|
253
60
|
|
|
254
|
-
✅ The Solution: Use Deque:
|
|
255
|
-
|
|
256
61
|
```javascript
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
62
|
+
// ✅ WITH data-structure-typed (Deque)
|
|
63
|
+
const deque = new Deque([1, 2, 3, ..., 100000])
|
|
64
|
+
;
|
|
260
65
|
for (let i = 0; i < 100000; i++) {
|
|
261
66
|
deque.shift(); // O(1) - Just moves a pointer
|
|
262
67
|
}
|
|
263
|
-
// Time: 5.83ms
|
|
264
|
-
//
|
|
68
|
+
// Time: 5.83ms ✅
|
|
69
|
+
// **484x faster!**
|
|
265
70
|
```
|
|
266
71
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
- Competitive programming: TLE ❌ → AC ✅
|
|
270
|
-
- Real-time systems: P99 latency 500ms ❌ → 5ms ✅
|
|
271
|
-
- Message queues: Throughput 100/sec ❌ → 10,000/sec ✅
|
|
72
|
+
---
|
|
272
73
|
|
|
273
|
-
|
|
74
|
+
## 🚀 Performance (TL;DR)
|
|
274
75
|
|
|
275
|
-
|
|
76
|
+
- **10–40% faster** than common JS implementations in hot paths
|
|
77
|
+
- Array.sort() O(n log n) → TreeSet O(log n) insertion
|
|
78
|
+
- Repeated Array.shift() O(n) → Queue O(1)
|
|
79
|
+
- Manual index tracking → RB-Tree auto-balance
|
|
276
80
|
|
|
277
|
-
|
|
278
|
-
// Library 1: Uses offer/poll (Java-style)
|
|
279
|
-
queue.offer(item);
|
|
280
|
-
queue.poll();
|
|
81
|
+
- **Optimized for V8 JIT** (Node.js 18+, modern browsers)
|
|
281
82
|
|
|
282
|
-
|
|
283
|
-
queue.push(item);
|
|
284
|
-
queue.shift();
|
|
83
|
+
- **Tree-shakable** ESM / CJS / legacy builds
|
|
285
84
|
|
|
286
|
-
|
|
287
|
-
queue.enqueue(item);
|
|
288
|
-
queue.dequeue();
|
|
289
|
-
```
|
|
85
|
+
📊 [Full benchmarks →](./docs/PERFORMANCE.md)
|
|
290
86
|
|
|
291
|
-
|
|
87
|
+
---
|
|
292
88
|
|
|
293
|
-
|
|
89
|
+
## ✨ Key Features
|
|
294
90
|
|
|
295
|
-
|
|
296
|
-
|---|---|---|---|
|
|
297
|
-
| add | offer | push | push |
|
|
298
|
-
| remove | poll | removeLast | removeLast |
|
|
299
|
-
| remove | poll | removeFirst | removeFirst |
|
|
300
|
-
| add(0, element) | offerFirst | unshift | unshift |
|
|
91
|
+
### 🏠 Uniform API
|
|
301
92
|
|
|
302
|
-
|
|
93
|
+
Don't learn new APIs. Just use `push`, `pop`, `map`, `filter`, and `reduce` everywhere.
|
|
303
94
|
|
|
304
95
|
```javascript
|
|
305
|
-
//
|
|
96
|
+
// All linear structures use THE SAME 4 methods
|
|
306
97
|
const deque = new Deque([1, 2, 3]);
|
|
307
98
|
const queue = new Queue([1, 2, 3]);
|
|
308
|
-
const
|
|
309
|
-
const
|
|
99
|
+
const doublyLinkeList = new DoublyLinkedList([1, 2, 3]);
|
|
100
|
+
const singlyLinkedList = new SinglyLinkedList([1, 2, 3]);
|
|
310
101
|
|
|
311
102
|
// They ALL support:
|
|
312
|
-
structure.push(item);
|
|
313
|
-
structure.pop();
|
|
314
|
-
structure.shift();
|
|
315
|
-
structure.unshift(item);
|
|
316
|
-
|
|
317
|
-
// And ALL support Array's advanced methods
|
|
318
|
-
structure.map((_value, key) => key * 2);
|
|
319
|
-
structure.filter((_value, key) => key > 5);
|
|
320
|
-
structure.reduce((acc, _value, key) => acc + key, 0);
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
#### 3️⃣ Conversion Hell: Bouncing Data Between Structures
|
|
324
|
-
|
|
325
|
-
❌ The Painful Way:
|
|
326
|
-
|
|
327
|
-
```javascript
|
|
328
|
-
const scores = [95, 23, 67, 89, 12, 45];
|
|
329
|
-
const tree = new SomeTreeLibrary(scores);
|
|
330
|
-
|
|
331
|
-
const filtered = tree.toArray().filter(s => s > 50); // Convert to array
|
|
332
|
-
const mapped = filtered.map(s => s * 2); // Another conversion
|
|
333
|
-
// Multiple conversions, lost benefits, easy to make mistakes
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
✅ The Clean Way:
|
|
337
|
-
|
|
338
|
-
```javascript
|
|
339
|
-
const tree = new RedBlackTree(scores);
|
|
340
|
-
|
|
341
|
-
// All methods work DIRECTLY on the tree
|
|
342
|
-
const result = tree
|
|
343
|
-
.filter((_value, key) => key > 50) // Direct
|
|
344
|
-
.map((_value, key) => [key, key * 1]) // Direct
|
|
345
|
-
.reduce((acc, value) => acc + (value ?? 0), 0); // Direct
|
|
346
|
-
|
|
347
|
-
// ✅ Zero conversions, tree structure maintained
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
---
|
|
351
|
-
|
|
352
|
-
## 🔗 Seamless Interoperability: Iterator Protocol Everywhere
|
|
353
|
-
|
|
354
|
-
### The Hidden Superpower
|
|
355
|
-
|
|
356
|
-
Every single data structure implements the **Iterator protocol**:
|
|
357
|
-
|
|
358
|
-
- ✅ Spread operator: `[...tree]`
|
|
359
|
-
- ✅ for...of loops: `for (const item of tree)`
|
|
360
|
-
- ✅ Destructuring: `const [a, b, c] = tree`
|
|
361
|
-
- ✅ Array.from(): `Array.from(tree)`
|
|
362
|
-
- ✅ Set/Map constructors: `new Set(tree)`
|
|
363
|
-
|
|
364
|
-
### Iterator Support Comparison
|
|
365
|
-
|
|
366
|
-
| Feature | Array | Map | Set | Other Lib | data-structure-typed |
|
|
367
|
-
|---------|-------|-----|-----|-----------|----------------------|
|
|
368
|
-
| Spread operator | ✅ | ❌/⚠️ | ✅ | ❌/⚠️ | ✅ |
|
|
369
|
-
| for...of loop | ✅ | ✅ | ✅ | ❌/⚠️ | ✅ |
|
|
370
|
-
| Destructuring | ✅ | ❌ | ❌ | ❌ | ✅ |
|
|
371
|
-
| Array.from() | ✅ | ❌/⚠️ | ❌ | ❌/⚠️ | ✅ |
|
|
372
|
-
| Set constructor | ✅ | ❌ | ✅ | ❌ | ✅ |
|
|
373
|
-
| **Full Integration** | ✅ | ⚠️ | ⚠️ | ⚠️ | **✅** |
|
|
374
|
-
|
|
375
|
-
### Live Examples: Zero Friction Conversions
|
|
376
|
-
|
|
377
|
-
#### Example 1: Array to Tree to Array
|
|
378
|
-
|
|
379
|
-
```javascript
|
|
380
|
-
const array = [64, 34, 25, 12, 22, 11, 90];
|
|
381
|
-
const rbTree = new RedBlackTree(array);
|
|
382
|
-
const sorted = [...rbTree.keys()];
|
|
383
|
-
console.log(sorted); // [11, 12, 22, 25, 34, 64, 90] ✅
|
|
103
|
+
structure.push(item); // Add to end
|
|
104
|
+
structure.pop(); // Remove from end
|
|
105
|
+
structure.shift(); // Remove from start
|
|
106
|
+
structure.unshift(item); // Add to start
|
|
384
107
|
```
|
|
385
108
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
```javascript
|
|
389
|
-
const rbTree = new RedBlackTree([
|
|
390
|
-
[1, 'Alice'],
|
|
391
|
-
[2, 'Bob'],
|
|
392
|
-
[3, 'Charlie']
|
|
393
|
-
]);
|
|
394
|
-
|
|
395
|
-
const allKeys = [...rbTree.keys()]; // [1, 2, 3]
|
|
396
|
-
const allValues = [...rbTree.values()]; // ['Alice', 'Bob', 'Charlie']
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
#### Example 3: for...of on Any Structure
|
|
400
|
-
|
|
401
|
-
```javascript
|
|
402
|
-
const tree = new RedBlackTree(entries);
|
|
403
|
-
const deque = new Deque(items);
|
|
404
|
-
const heap = new MaxHeap(items);
|
|
405
|
-
|
|
406
|
-
for (const entry of tree) console.log(entry);
|
|
407
|
-
for (const item of deque) console.log(item);
|
|
408
|
-
for (const item of heap) console.log(item);
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
---
|
|
109
|
+
### 🛡️ Type Safe
|
|
412
110
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
### The Biggest Developer Joy: Array Methods, Everywhere
|
|
416
|
-
|
|
417
|
-
You know these methods. You use them every day. They work on **every data structure**:
|
|
418
|
-
|
|
419
|
-
#### Chain on Tree
|
|
420
|
-
|
|
421
|
-
```typescript
|
|
422
|
-
const rbTree = new RedBlackTree([
|
|
423
|
-
[1, { name: 'Alice', age: 25 }],
|
|
424
|
-
[2, { name: 'Bob', age: 30 }],
|
|
425
|
-
[3, { name: 'Charlie', age: 28 }],
|
|
426
|
-
]);
|
|
427
|
-
|
|
428
|
-
const result = rbTree
|
|
429
|
-
.filter((value, _key) => (value?.age ?? 0) > 26)
|
|
430
|
-
.map((value, key) => [key, { ...value, id: key }])
|
|
431
|
-
.reduce((sum, value) => sum + (value?.age ?? 0), 0);
|
|
432
|
-
|
|
433
|
-
console.log(result); // 58 ✅
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
#### Chain on Heap
|
|
111
|
+
Full generics and strict TypeScript support out of the box.
|
|
437
112
|
|
|
438
113
|
```typescript
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
{ priority: 8, task: 'Alert' },
|
|
443
|
-
], { comparator: (a, b) => a.priority - b.priority });
|
|
444
|
-
|
|
445
|
-
const urgent = minHeap
|
|
446
|
-
.filter((value, _key) => value.priority > 4)
|
|
447
|
-
.map((value, _key) => value.task);
|
|
114
|
+
const tree = new RedBlackTree<number, string>();
|
|
115
|
+
tree.set(1, 'Alice');
|
|
116
|
+
tree.set(2, 'Bob');
|
|
448
117
|
|
|
449
|
-
|
|
118
|
+
// Type-safe access
|
|
119
|
+
const value = tree.get(1); // Type: string | undefined
|
|
450
120
|
```
|
|
451
121
|
|
|
452
|
-
|
|
122
|
+
### ✨ Zero Friction
|
|
453
123
|
|
|
454
|
-
|
|
455
|
-
const deque = new Deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
456
|
-
|
|
457
|
-
const stats = {
|
|
458
|
-
even: deque.filter((value, _key) => value % 2 === 0).toArray(),
|
|
459
|
-
squared: deque.map((value, _key) => value * value).toArray(),
|
|
460
|
-
hasLarge: deque.some((value, _key) => value > 8),
|
|
461
|
-
sum: deque.reduce((acc, value, _key) => acc + value, 0),
|
|
462
|
-
};
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
### Supported Methods Across All Structures
|
|
466
|
-
|
|
467
|
-
| Method | Tree | Heap | Deque | Graph | LinkedList |
|
|
468
|
-
|--------|------|------|-------|-------|------------|
|
|
469
|
-
| map | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
470
|
-
| filter | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
471
|
-
| reduce | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
472
|
-
| find | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
473
|
-
| some/every | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
474
|
-
| keys/values | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
475
|
-
| forEach | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
476
|
-
|
|
477
|
-
---
|
|
478
|
-
|
|
479
|
-
## Why Not Just Use Native JavaScript?
|
|
480
|
-
|
|
481
|
-
### Case 1: Map Doesn't Maintain Sorted Order
|
|
482
|
-
|
|
483
|
-
❌ Map iteration is insertion order, not key order:
|
|
124
|
+
Works everywhere. Spread it `[...]`, loop it `for..of`, convert it instantly.
|
|
484
125
|
|
|
485
126
|
```javascript
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
✅ RedBlackTree maintains sorted order automatically:
|
|
493
|
-
|
|
494
|
-
```javascript
|
|
495
|
-
const tree = new RedBlackTree([[5, 'E'], [2, 'B'], [8, 'H'], [1, 'A']]);
|
|
496
|
-
for (const [key, value] of tree) {
|
|
497
|
-
console.log(key); // 1, 2, 5, 8 (key order) ✅
|
|
498
|
-
}
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
### Case 2: Array.shift is Too Slow
|
|
502
|
-
|
|
503
|
-
❌ Array.shift is O(n):
|
|
504
|
-
|
|
505
|
-
```javascript
|
|
506
|
-
const queue = [];
|
|
507
|
-
for (let i = 0; i < 100000; i++) queue.push(i);
|
|
508
|
-
for (let i = 0; i < 100000; i++) queue.shift();
|
|
509
|
-
// Time: 2829ms ❌
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
✅ Deque.shift is O(1):
|
|
513
|
-
|
|
514
|
-
```javascript
|
|
515
|
-
const deque = new Deque();
|
|
516
|
-
for (let i = 0; i < 100000; i++) deque.push(i);
|
|
517
|
-
for (let i = 0; i < 100000; i++) deque.shift();
|
|
518
|
-
// Time: 5.83ms ✅
|
|
127
|
+
// All data structures work with iterator protocol
|
|
128
|
+
const tree = new RedBlackTree([5, 2, 8]);
|
|
129
|
+
const sorted = [...tree]; // Spread operator
|
|
130
|
+
for (const item of tree) {
|
|
131
|
+
} // for...of loop
|
|
132
|
+
const set = new Set(tree); // Set constructor
|
|
519
133
|
```
|
|
520
134
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
❌ Array requires re-sorting O(n log n):
|
|
524
|
-
|
|
525
|
-
```javascript
|
|
526
|
-
const tasks = [];
|
|
527
|
-
function addTask(task) {
|
|
528
|
-
tasks.push(task);
|
|
529
|
-
tasks.sort((a, b) => b.priority - a.priority);
|
|
530
|
-
}
|
|
531
|
-
```
|
|
135
|
+
---
|
|
532
136
|
|
|
533
|
-
|
|
137
|
+
## 📥 Installation
|
|
534
138
|
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
function addTask(task) {
|
|
538
|
-
pq.add(task); // O(log n)
|
|
539
|
-
}
|
|
139
|
+
```bash
|
|
140
|
+
pnpm add data-structure-typed
|
|
540
141
|
```
|
|
541
142
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
❌ Array.filter is O(n):
|
|
545
|
-
|
|
546
|
-
```javascript
|
|
547
|
-
const prices = [10, 45, 23, 67, 89, 12, 54, 33, 78];
|
|
548
|
-
const inRange = prices.filter(p => p >= 30 && p <= 70);
|
|
143
|
+
```bash
|
|
144
|
+
npm i data-structure-typed --save
|
|
549
145
|
```
|
|
550
146
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
```javascript
|
|
554
|
-
const tree = new RedBlackTree(prices.map((p, i) => [p, i]));
|
|
555
|
-
const inRange = tree.filter((_value, p) => p >= 30 && p <= 70);
|
|
147
|
+
```bash
|
|
148
|
+
yarn add data-structure-typed
|
|
556
149
|
```
|
|
557
150
|
|
|
558
|
-
###
|
|
151
|
+
### Individual Packages
|
|
559
152
|
|
|
560
|
-
|
|
153
|
+
Use only what you need:
|
|
561
154
|
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
const matches = words.filter(w => w.startsWith('app'));
|
|
565
|
-
// For 1M words: checks 1M words ❌
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
✅ Trie prefix matching is O(m + k):
|
|
569
|
-
|
|
570
|
-
```javascript
|
|
571
|
-
const trie = new Trie(words);
|
|
572
|
-
const matches = trie.getWords('appl');
|
|
573
|
-
// O(5 + 4) = 9 operations ✅
|
|
155
|
+
```bash
|
|
156
|
+
pnpm add heap-typed deque-typed red-black-tree-typed
|
|
574
157
|
```
|
|
575
158
|
|
|
576
159
|
---
|
|
577
160
|
|
|
578
|
-
##
|
|
579
|
-
|
|
580
|
-
Performance surpasses that of native JS/TS
|
|
581
|
-
|
|
582
|
-
| Method | Time Taken | Data Scale | Belongs To | Big O |
|
|
583
|
-
|--------|-----------|-----------|-----------|-------|
|
|
584
|
-
| Queue.push & shift | 5.83 ms | 100K | Ours | O(1) |
|
|
585
|
-
| Array.push & shift | 2829.59 ms | 100K | Native JS | O(n) |
|
|
586
|
-
| Deque.unshift & shift | 2.44 ms | 100K | Ours | O(1) |
|
|
587
|
-
| Array.unshift & shift | 4750.37 ms | 100K | Native JS | O(n) |
|
|
588
|
-
| HashMap.set | 122.51 ms | 1M | Ours | O(1) |
|
|
589
|
-
| Map.set | 223.80 ms | 1M | Native JS | O(1) |
|
|
590
|
-
| Set.add | 185.06 ms | 1M | Native JS | O(1) |
|
|
591
|
-
|
|
592
|
-
### Benchmark
|
|
593
|
-
|
|
594
|
-
MacBook Pro (15-inch, 2018)
|
|
595
|
-
|
|
596
|
-
Processor 2.2 GHz 6-Core Intel Core i7
|
|
597
|
-
|
|
598
|
-
Memory 16 GB 2400 MHz DDR4
|
|
161
|
+
## 💡 When Should I Consider This Library?
|
|
599
162
|
|
|
600
|
-
|
|
163
|
+
✅ **When you need:**
|
|
601
164
|
|
|
602
|
-
|
|
165
|
+
- Top-K / Leaderboard queries without repeated sorting
|
|
166
|
+
- Insertion order + lookup performance simultaneously
|
|
167
|
+
- Priority queues with fast position-based access
|
|
168
|
+
- Time-series data with range queries
|
|
169
|
+
- Red-Black Tree / Heap performance without learning new APIs
|
|
603
170
|
|
|
604
|
-
|
|
171
|
+
✅ **When your current code has:**
|
|
605
172
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
[//]: # (No deletion!!! End of Replace Section)
|
|
173
|
+
- `array.sort()` in hot paths (request handlers, loops)
|
|
174
|
+
- Manual index tracking after insertions
|
|
175
|
+
- `Array.shift()` on large lists (queues)
|
|
176
|
+
- Custom sorting logic you repeat across files
|
|
177
|
+
- Map that needs to be ordered
|
|
613
178
|
|
|
614
179
|
---
|
|
615
180
|
|
|
616
|
-
##
|
|
617
|
-
|
|
618
|
-
For those who love understanding concepts through metaphors:
|
|
619
|
-
|
|
620
|
-
| Data Structure | Plain Language Definition | Example |
|
|
621
|
-
|---|---|---|
|
|
622
|
-
| **Linked List** | A line of bunnies, where each bunny holds the tail of the bunny in front (each bunny only knows the bunny behind). Search takes O(n) time but insertion is O(1). | To find bunny "Pablo", start from the first bunny and follow tails until found |
|
|
623
|
-
| **Array** | A line of numbered bunnies. You can find bunny #680 directly (O(1)), but inserting a bunny requires renumbering all bunnies behind it (O(n)). | Finding element by index is instant, but inserting in the middle is slow |
|
|
624
|
-
| **Queue** | A line of numbered bunnies with a sticky note on the first bunny. Removing from front only moves the sticky note (O(1)), without renumbering. Adding to the tail gives new numbers (O(1)). | Process items in FIFO order, efficiently from both ends |
|
|
625
|
-
| **Deque** | A line of grouped, numbered bunnies with a sticky note. Remove from front by moving sticky note (O(1)). When a group is exhausted, renumber only that group. Tail handled similarly. | Efficient removal/insertion from both ends with batching optimization |
|
|
626
|
-
| **Stack** | A line of bunnies in a dead-end tunnel. Add/remove only at the entrance/end. | Process items in LIFO order |
|
|
627
|
-
| **Binary Tree** | A tree where each node (bunny) has at most two children. When you add sorted data like [4,2,6,1,3,5,7], it forms a complete binary tree. | Hierarchical organization of data |
|
|
628
|
-
| **Binary Search Tree** | Disciplined bunnies arranged by order: all left subtree values < node < all right subtree values. This maintains O(log n) for search/insert/delete. | Find items exponentially faster than linear search |
|
|
629
|
-
| **Red-Black Tree** | A self-balancing binary search tree where nodes are marked red/black to ensure no path is twice as long as another. | Maintains O(log n) guarantees automatically |
|
|
630
|
-
| **AVL Tree** | A strictly balanced binary search tree where every node's left/right subtrees differ by at most 1 in height. Provides highest search efficiency but slower insertions/deletions. | Maximum search speed with strict balance |
|
|
631
|
-
| **Heap** | A special complete binary tree stored in an array. Parent at index i has children at 2i+1 and 2i+2. | Efficient priority queue implementation |
|
|
632
|
-
| **Trie** | A tree where each node represents a character. Path from root to node spells a word. | Prefix search in O(m + k) time instead of O(n*m) |
|
|
633
|
-
| **Graph** | A network of connected bunnies. Directed: each bunny points to specific other bunnies. Undirected: mutual connections. | Model relationships, networks, dependencies |
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
---
|
|
181
|
+
## 🚀 Quick Start: 30 Seconds
|
|
637
182
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
### Pattern 1: Interoperability & Iterator Conversion
|
|
183
|
+
### Leaderboard (Ranked Collections)
|
|
641
184
|
|
|
642
185
|
```typescript
|
|
643
186
|
import { RedBlackTree } from 'data-structure-typed';
|
|
644
187
|
|
|
645
|
-
const
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
// Convert to array (spread operator)
|
|
651
|
-
const sorted = [...tree];
|
|
652
|
-
console.log(sorted); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
653
|
-
|
|
654
|
-
// Iterate with for...of
|
|
655
|
-
for (const item of tree) {
|
|
656
|
-
console.log(item);
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
// Get keys/values separately
|
|
660
|
-
const keys = [...tree.keys()];
|
|
661
|
-
const values = [...tree.values()];
|
|
662
|
-
|
|
663
|
-
// Destructuring works
|
|
664
|
-
const [first, second, ...rest] = tree;
|
|
665
|
-
|
|
666
|
-
// Works with native JavaScript
|
|
667
|
-
const json = JSON.stringify([...tree]);
|
|
668
|
-
const set = new Set(tree.keys());
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
### Pattern 2: Method Chaining on Exotic Structures
|
|
672
|
-
|
|
673
|
-
❌ Before (Array with shift):
|
|
674
|
-
|
|
675
|
-
```javascript
|
|
676
|
-
const queue = [1, 2, 3, 4, 5];
|
|
677
|
-
for (let i = 0; i < 100000; i++) {
|
|
678
|
-
queue.shift(); // O(n)
|
|
679
|
-
}
|
|
680
|
-
```
|
|
681
|
-
|
|
682
|
-
✅ After (Deque):
|
|
683
|
-
|
|
684
|
-
```javascript
|
|
685
|
-
import { Deque } from 'data-structure-typed';
|
|
188
|
+
const leaderboard = new RedBlackTree([
|
|
189
|
+
[100, 'Alice'],
|
|
190
|
+
[85, 'Bob'],
|
|
191
|
+
[92, 'Charlie']
|
|
192
|
+
]);
|
|
686
193
|
|
|
687
|
-
|
|
688
|
-
for (
|
|
689
|
-
|
|
194
|
+
// Get sorted scores (automatically maintained!)
|
|
195
|
+
for (const [score, player] of leaderboard) {
|
|
196
|
+
console.log(`${player}: ${score}`);
|
|
690
197
|
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
```typescript
|
|
696
|
-
import { RedBlackTree, MaxHeap, Deque } from 'data-structure-typed';
|
|
697
|
-
|
|
698
|
-
const data = [64, 34, 25, 12, 22, 11, 90];
|
|
699
|
-
|
|
700
|
-
// Array → Tree for sorting
|
|
701
|
-
const tree = new RedBlackTree(data);
|
|
702
|
-
console.log([...tree.keys()]); // [11, 12, 22, 25, 34, 64, 90]
|
|
198
|
+
// Output:
|
|
199
|
+
// Alice: 100
|
|
200
|
+
// Charlie: 92
|
|
201
|
+
// Bob: 85
|
|
703
202
|
|
|
704
|
-
//
|
|
705
|
-
|
|
203
|
+
// Update score
|
|
204
|
+
leaderboard.delete(85);
|
|
205
|
+
leaderboard.set(95, 'Bob'); // O(log n)
|
|
706
206
|
|
|
707
|
-
//
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
// Back to Array for final output
|
|
711
|
-
const result = [...deque];
|
|
207
|
+
// Query top players
|
|
208
|
+
const topPlayers = [...leaderboard.values()].reverse().slice(0, 3);
|
|
712
209
|
```
|
|
713
210
|
|
|
714
|
-
###
|
|
715
|
-
|
|
716
|
-
#### Tree Example
|
|
211
|
+
### Task Queue (Scheduling)
|
|
717
212
|
|
|
718
213
|
```typescript
|
|
719
|
-
|
|
720
|
-
tree.add(1, { name: 'Alice', score: 95 });
|
|
721
|
-
tree.add(2, { name: 'Bob', score: 87 });
|
|
722
|
-
tree.add(3, { name: 'Charlie', score: 92 });
|
|
723
|
-
|
|
724
|
-
const totalHighScore = tree
|
|
725
|
-
.filter((value, _key) => (value?.score ?? 0) >= 85)
|
|
726
|
-
.map((value, key) => [key, value?.score ?? 0])
|
|
727
|
-
.reduce((sum, score) => sum + (score ?? 0), 0);
|
|
214
|
+
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
728
215
|
|
|
729
|
-
|
|
730
|
-
|
|
216
|
+
const taskQueue = new MaxPriorityQueue<{priority: number; task: string}>([], {
|
|
217
|
+
comparator: (a, b) => b.priority - a.priority
|
|
218
|
+
});
|
|
731
219
|
|
|
732
|
-
|
|
220
|
+
taskQueue.add({ priority: 5, task: 'Email' });
|
|
221
|
+
taskQueue.add({ priority: 9, task: 'Alert' }); // Instant priority handling
|
|
733
222
|
|
|
734
|
-
|
|
735
|
-
const heap = new MaxHeap([
|
|
736
|
-
{ priority: 5, task: 'Email' },
|
|
737
|
-
{ priority: 8, task: 'Alert' },
|
|
738
|
-
], { comparator: (a, b) => b.priority - a.priority });
|
|
739
|
-
|
|
740
|
-
const urgentTasks = heap
|
|
741
|
-
.filter((value, _key) => value.priority >= 8)
|
|
742
|
-
.map((value, _key) => [value.priority, value.task]);
|
|
223
|
+
const nextTask = taskQueue.poll(); // { priority: 9, task: 'Alert' }
|
|
743
224
|
```
|
|
744
225
|
|
|
745
|
-
|
|
226
|
+
### Fast Queue (FIFO)
|
|
746
227
|
|
|
747
228
|
```typescript
|
|
748
|
-
|
|
229
|
+
import { Deque } from 'data-structure-typed';
|
|
749
230
|
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
.reduce((sum, value) => sum + value, 0);
|
|
231
|
+
const queue = new Deque([1, 2, 3, 4, 5]);
|
|
232
|
+
queue.shift(); // Remove from front: O(1) not O(n)
|
|
233
|
+
queue.push(6); // Add to back: O(1)
|
|
754
234
|
```
|
|
755
235
|
|
|
756
236
|
---
|
|
757
237
|
|
|
758
|
-
##
|
|
759
|
-
|
|
760
|
-
### Red Black Tree CRUD
|
|
761
|
-
|
|
762
|
-
#### TS
|
|
763
|
-
|
|
764
|
-
```ts
|
|
765
|
-
import { RedBlackTree } from 'data-structure-typed';
|
|
766
|
-
|
|
767
|
-
const rbTree = new RedBlackTree<number>();
|
|
768
|
-
|
|
769
|
-
// CREATE: Add elements
|
|
770
|
-
rbTree.add(11);
|
|
771
|
-
rbTree.add(3);
|
|
772
|
-
rbTree.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
|
773
|
-
|
|
774
|
-
// READ: Query elements
|
|
775
|
-
rbTree.has(6); // true
|
|
776
|
-
rbTree.size === 16; // true
|
|
777
|
-
const node6 = rbTree.getNode(6); // BSTNode
|
|
778
|
-
rbTree.getHeight(6) === 2; // true (height of node with key 6)
|
|
779
|
-
rbTree.getHeight() === 5; // true (tree height)
|
|
780
|
-
|
|
781
|
-
// UPDATE: Delete elements
|
|
782
|
-
rbTree.delete(6);
|
|
783
|
-
rbTree.get(6); // undefined
|
|
784
|
-
|
|
785
|
-
// Query after update
|
|
786
|
-
rbTree.getLeftMost()?.key === 1; // true
|
|
787
|
-
rbTree.isAVLBalanced(); // true
|
|
788
|
-
|
|
789
|
-
rbTree.print()
|
|
790
|
-
// ______________11_____
|
|
791
|
-
// / \
|
|
792
|
-
// ___3_______ _13_____
|
|
793
|
-
// / \ / \
|
|
794
|
-
// 1_ _____8____ 12 _15__
|
|
795
|
-
// \ / \ / \
|
|
796
|
-
// 2 4_ _10 14 16
|
|
797
|
-
// \ /
|
|
798
|
-
// 5_ 9
|
|
799
|
-
// \
|
|
800
|
-
// 7
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
#### JS
|
|
804
|
-
|
|
805
|
-
```js
|
|
806
|
-
import { RedBlackTree } from 'data-structure-typed';
|
|
807
|
-
|
|
808
|
-
const rbTree = new RedBlackTree();
|
|
809
|
-
|
|
810
|
-
// CREATE
|
|
811
|
-
rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]);
|
|
812
|
-
|
|
813
|
-
// READ
|
|
814
|
-
rbTree.has(6); // true
|
|
815
|
-
const height = rbTree.getHeight(); // 5
|
|
816
|
-
|
|
817
|
-
// UPDATE
|
|
818
|
-
rbTree.delete(10);
|
|
819
|
-
rbTree.isAVLBalanced(); // true
|
|
820
|
-
|
|
821
|
-
// PRINT
|
|
822
|
-
rbTree.print();
|
|
823
|
-
```
|
|
824
|
-
|
|
825
|
-
### BST CRUD with Custom Objects
|
|
826
|
-
|
|
827
|
-
```ts
|
|
828
|
-
import { BST, BSTNode } from 'data-structure-typed';
|
|
829
|
-
|
|
830
|
-
const bst = new BST<number, { height: number, age: number }>();
|
|
831
|
-
|
|
832
|
-
// CREATE
|
|
833
|
-
bst.add(11, { "name": "Pablo", "size": 15 });
|
|
834
|
-
bst.add(3, { "name": "Kirk", "size": 1 });
|
|
835
|
-
|
|
836
|
-
bst.addMany(
|
|
837
|
-
[15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5],
|
|
838
|
-
[
|
|
839
|
-
{ "name": "Alice", "size": 15 },
|
|
840
|
-
{ "name": "Bob", "size": 1 },
|
|
841
|
-
{ "name": "Charlie", "size": 8 },
|
|
842
|
-
{ "name": "David", "size": 13 },
|
|
843
|
-
{ "name": "Emma", "size": 16 },
|
|
844
|
-
{ "name": "Frank", "size": 2 },
|
|
845
|
-
{ "name": "Grace", "size": 6 },
|
|
846
|
-
{ "name": "Hannah", "size": 9 },
|
|
847
|
-
{ "name": "Isaac", "size": 12 },
|
|
848
|
-
{ "name": "Jack", "size": 14 },
|
|
849
|
-
{ "name": "Katie", "size": 4 },
|
|
850
|
-
{ "name": "Liam", "size": 7 },
|
|
851
|
-
{ "name": "Mia", "size": 10 },
|
|
852
|
-
{ "name": "Noah", "size": 5 }
|
|
853
|
-
]
|
|
854
|
-
);
|
|
855
|
-
|
|
856
|
-
// READ
|
|
857
|
-
const value = bst.get(11); // { "name": "Pablo", "size": 15 }
|
|
858
|
-
const has11 = bst.has(11); // true
|
|
859
|
-
|
|
860
|
-
// UPDATE
|
|
861
|
-
bst.delete(11);
|
|
862
|
-
|
|
863
|
-
// VERIFY
|
|
864
|
-
const afterDelete = bst.has(11); // false
|
|
865
|
-
```
|
|
866
|
-
|
|
867
|
-
### Queue/Deque CRUD
|
|
868
|
-
|
|
869
|
-
```ts
|
|
870
|
-
import { Queue, Deque } from 'data-structure-typed';
|
|
871
|
-
|
|
872
|
-
const queue = new Queue([1, 2, 3, 4, 5]);
|
|
873
|
-
|
|
874
|
-
// CREATE/ADD
|
|
875
|
-
queue.push(6); // O(1)
|
|
876
|
-
|
|
877
|
-
// READ
|
|
878
|
-
const front = queue.peek(); // 1
|
|
879
|
-
const size = queue.size; // 6
|
|
880
|
-
|
|
881
|
-
// REMOVE
|
|
882
|
-
const removed = queue.shift(); // O(1) - removes 1
|
|
883
|
-
queue.pop(); // O(1) - removes last
|
|
884
|
-
|
|
885
|
-
// Same API for Deque
|
|
886
|
-
const deque = new Deque([1, 2, 3, 4, 5]);
|
|
887
|
-
deque.push(6);
|
|
888
|
-
deque.unshift(0); // Add to front
|
|
889
|
-
deque.pop(); // Remove from end
|
|
890
|
-
deque.shift(); // Remove from front
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
### Graph CRUD
|
|
894
|
-
|
|
895
|
-
```ts
|
|
896
|
-
import { DirectedGraph } from 'data-structure-typed';
|
|
897
|
-
|
|
898
|
-
const graph = new DirectedGraph<string>();
|
|
899
|
-
|
|
900
|
-
// CREATE
|
|
901
|
-
graph.addVertex('A');
|
|
902
|
-
graph.addVertex('B');
|
|
903
|
-
graph.addVertex('C');
|
|
904
|
-
|
|
905
|
-
// CONNECT
|
|
906
|
-
graph.addEdge('A', 'B');
|
|
907
|
-
graph.addEdge('B', 'C');
|
|
908
|
-
graph.addEdge('A', 'C');
|
|
238
|
+
## 📊 Data Structures Available
|
|
909
239
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
240
|
+
| Structure | Use Case | Time Complexity | NPM |
|
|
241
|
+
|--------------------------|-----------------------------------|-----------------|-----------------------------------------------------------|
|
|
242
|
+
| **RedBlackTree** | Sorted collections, range queries | O(log n) | [npm](https://www.npmjs.com/package/red-black-tree-typed) |
|
|
243
|
+
| **Heap / PriorityQueue** | Task scheduling, top-K elements | O(log n) | [npm](https://www.npmjs.com/package/heap-typed) |
|
|
244
|
+
| **Deque** | Fast front/back operations | O(1) | [npm](https://www.npmjs.com/package/deque-typed) |
|
|
245
|
+
| **Trie** | Autocomplete, prefix search | O(m+k) | [npm](https://www.npmjs.com/package/trie-typed) |
|
|
246
|
+
| **DirectedGraph** | Pathfinding, DAG algorithms | O(V+E) | [npm](https://www.npmjs.com/package/directed-graph-typed) |
|
|
247
|
+
| **Stack** | Undo/redo, expression parsing | O(1) | [npm](https://www.npmjs.com/package/stack-typed) |
|
|
248
|
+
| **LinkedList** | Dynamic sizing, no index shift | O(1)* | [npm](https://www.npmjs.com/package/linked-list-typed) |
|
|
249
|
+
| **AVLTree** | Stricter balance than RB-Tree | O(log n) | [npm](https://www.npmjs.com/package/avl-tree-typed) |
|
|
914
250
|
|
|
915
|
-
|
|
916
|
-
graph.deleteEdgeSrcToDest('A', 'C');
|
|
917
|
-
graph.hasEdge('A', 'C'); // false
|
|
918
|
-
|
|
919
|
-
// ALGORITHMS
|
|
920
|
-
const topologicalOrder = graph.topologicalSort();
|
|
921
|
-
const { minDist, minPath } = graph.dijkstra('A', 'C');
|
|
922
|
-
```
|
|
251
|
+
👉 [See all 20+ structures →](./docs/REFERENCE.md)
|
|
923
252
|
|
|
924
253
|
---
|
|
925
254
|
|
|
926
|
-
##
|
|
927
|
-
|
|
928
|
-
###
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
255
|
+
## 📖 Documentation
|
|
256
|
+
|
|
257
|
+
### For Different Use Cases
|
|
258
|
+
|
|
259
|
+
| Your Goal | Start Here | Next Steps |
|
|
260
|
+
|---------------------------|-------------------------------------------|-----------------------------------------|
|
|
261
|
+
| **Learn concepts** | [CONCEPTS.md](./docs/CONCEPTS.md) | [GUIDES.md](./docs/GUIDES.md) |
|
|
262
|
+
| **Use in my project** | [GUIDES.md](./docs/GUIDES.md) | [REFERENCE.md](./docs/REFERENCE.md) |
|
|
263
|
+
| **Look up API** | [REFERENCE.md](./docs/REFERENCE.md) | [PERFORMANCE.md](./docs/PERFORMANCE.md) |
|
|
264
|
+
| **Performance questions** | [PERFORMANCE.md](./docs/PERFORMANCE.md) | [ARCHITECTURE.md](./docs/ARCHITECTURE.md) |
|
|
265
|
+
| **Framework integration** | [INTEGRATIONS.md](./docs/INTEGRATIONS.md) | [GUIDES.md](./docs/GUIDES.md) |
|
|
266
|
+
| **Understand design** | [ARCHITECTURE.md](./docs/ARCHITECTURE.md) | [CONCEPTS.md](./docs/CONCEPTS.md) |
|
|
267
|
+
|
|
268
|
+
### Documentation Files
|
|
269
|
+
|
|
270
|
+
1. **[CONCEPTS.md](./docs/CONCEPTS.md)** - Core Fundamentals & Theory
|
|
271
|
+
- Big Three Concepts (BST, Balanced Trees, Heap)
|
|
272
|
+
- 13 Plain Language Explanations
|
|
273
|
+
- Iterator Protocol Design
|
|
274
|
+
- 5 Comparisons with Native JavaScript
|
|
275
|
+
- Complete Decision Guide
|
|
276
|
+
|
|
277
|
+
2. **[REFERENCE.md](./docs/REFERENCE.md)** - Complete API & Data Structures
|
|
278
|
+
- Quick Reference Table
|
|
279
|
+
- All 20+ Structures with Examples
|
|
280
|
+
- CRUD Operations
|
|
281
|
+
- Common Methods
|
|
282
|
+
- TypeScript Support
|
|
283
|
+
|
|
284
|
+
3. **[ARCHITECTURE.md](./docs/ARCHITECTURE.md)** - Design & Implementation
|
|
285
|
+
- Design Philosophy & Principles
|
|
286
|
+
- 3 Pain Points Solved
|
|
287
|
+
- Why Deque is 484x Faster
|
|
288
|
+
- Iterator Protocol Design
|
|
289
|
+
- Self-Balancing Strategy
|
|
290
|
+
- V8 JIT Optimizations
|
|
291
|
+
|
|
292
|
+
4. **[PERFORMANCE.md](./docs/PERFORMANCE.md)** - Benchmarks & Comparisons
|
|
293
|
+
- Performance Summary
|
|
294
|
+
- 3 Real-World Scenarios
|
|
295
|
+
- Detailed Benchmarks
|
|
296
|
+
- When to Use What
|
|
297
|
+
- Optimization Tips
|
|
298
|
+
|
|
299
|
+
5. **[GUIDES.md](./docs/GUIDES.md)** - Real-World Examples
|
|
300
|
+
- 4 Design Patterns
|
|
301
|
+
- 5 Production Code Examples
|
|
302
|
+
- Common Mistakes
|
|
303
|
+
- Best Practices
|
|
304
|
+
|
|
305
|
+
6. **[INTEGRATIONS.md](./docs/INTEGRATIONS.md)** - Framework Integration
|
|
306
|
+
- React Integration (State Management, Leaderboard)
|
|
307
|
+
- Express Integration (LRU Cache, Rate Limiting)
|
|
308
|
+
- Nest.js Integration (Ranking Service, Task Queue)
|
|
309
|
+
- TypeScript Configuration
|
|
932
310
|
|
|
933
|
-
|
|
934
|
-
id: string;
|
|
935
|
-
customerId: string;
|
|
936
|
-
priority: 'normal' | 'urgent';
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
class OrderProcessor {
|
|
940
|
-
private normalQueue = new Deque<Order>();
|
|
941
|
-
private urgentQueue = new Deque<Order>();
|
|
942
|
-
private running = false;
|
|
943
|
-
|
|
944
|
-
constructor(private readonly urgentBurst: number = 5) {}
|
|
945
|
-
|
|
946
|
-
addOrder(order: Order): void {
|
|
947
|
-
if (order.priority === 'urgent') {
|
|
948
|
-
this.urgentQueue.push(order);
|
|
949
|
-
} else {
|
|
950
|
-
this.normalQueue.push(order);
|
|
951
|
-
}
|
|
952
|
-
void this.processOrders();
|
|
953
|
-
}
|
|
954
|
-
|
|
955
|
-
async processOrders(): Promise<void> {
|
|
956
|
-
if (this.running) return;
|
|
957
|
-
this.running = true;
|
|
958
|
-
|
|
959
|
-
try {
|
|
960
|
-
let urgentStreak = 0;
|
|
961
|
-
|
|
962
|
-
while (!this.urgentQueue.isEmpty() || !this.normalQueue.isEmpty()) {
|
|
963
|
-
const shouldTakeUrgent =
|
|
964
|
-
!this.urgentQueue.isEmpty() &&
|
|
965
|
-
(urgentStreak < this.urgentBurst || this.normalQueue.isEmpty());
|
|
966
|
-
|
|
967
|
-
const order = shouldTakeUrgent ? this.urgentQueue.shift() : this.normalQueue.shift();
|
|
968
|
-
if (!order) continue;
|
|
969
|
-
|
|
970
|
-
urgentStreak = order.priority === 'urgent' ? urgentStreak + 1 : 0;
|
|
971
|
-
|
|
972
|
-
try {
|
|
973
|
-
await this.processOrder(order);
|
|
974
|
-
} catch (err) {
|
|
975
|
-
console.error(`FAILED`, order.id, err);
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
} finally {
|
|
979
|
-
this.running = false;
|
|
980
|
-
}
|
|
981
|
-
}
|
|
311
|
+
---
|
|
982
312
|
|
|
983
|
-
|
|
984
|
-
await new Promise<void>(r => setTimeout(r, 10));
|
|
985
|
-
console.log(
|
|
986
|
-
`OK [${order.priority.toUpperCase()}] order:${order.id} customer:${order.customerId}`
|
|
987
|
-
);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
```
|
|
313
|
+
## 💻 Real-World Examples
|
|
991
314
|
|
|
992
|
-
###
|
|
315
|
+
### LRU Cache
|
|
993
316
|
|
|
994
317
|
```typescript
|
|
995
|
-
class LRUCache<
|
|
996
|
-
private cache = new
|
|
997
|
-
private
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
this.cache.delete(node);
|
|
1005
|
-
const newNode = this.cache.push(key, node.value[1]);
|
|
1006
|
-
this.map.set(key, newNode);
|
|
1007
|
-
return node.value[1];
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
set(key: string, value: T): void {
|
|
1011
|
-
if (this.map.has(key)) {
|
|
1012
|
-
const node = this.map.get(key)!;
|
|
1013
|
-
this.cache.delete(node);
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1016
|
-
const node = this.cache.push(key, value);
|
|
1017
|
-
this.map.set(key, node);
|
|
1018
|
-
|
|
1019
|
-
if (this.cache.length > this.maxSize) {
|
|
1020
|
-
const oldest = this.cache.shift();
|
|
1021
|
-
if (oldest) {
|
|
1022
|
-
this.map.delete(oldest[0]);
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
318
|
+
class LRUCache<K, V> {
|
|
319
|
+
private cache = new Map<K, V>();
|
|
320
|
+
private order = new DoublyLinkedList<K>();
|
|
321
|
+
|
|
322
|
+
get(key: K): V | null {
|
|
323
|
+
if (!this.cache.has(key)) return null;
|
|
324
|
+
// Move to end (recently used)
|
|
325
|
+
// Efficient with O(1) operations
|
|
326
|
+
return this.cache.get(key)!;
|
|
1025
327
|
}
|
|
1026
328
|
}
|
|
1027
|
-
|
|
1028
|
-
// Why DoublyLinkedList?
|
|
1029
|
-
// - O(1) delete from any position
|
|
1030
|
-
// - O(1) push to end
|
|
1031
|
-
// - Perfect for LRU implementation
|
|
1032
329
|
```
|
|
1033
330
|
|
|
1034
|
-
###
|
|
331
|
+
### Leaderboard
|
|
1035
332
|
|
|
1036
333
|
```typescript
|
|
1037
|
-
import { RedBlackTree } from 'data-structure-typed';
|
|
1038
334
|
|
|
1039
|
-
|
|
335
|
+
type Player = {
|
|
1040
336
|
id: string;
|
|
1041
337
|
name: string;
|
|
1042
338
|
score: number;
|
|
1043
|
-
}
|
|
339
|
+
};
|
|
1044
340
|
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
341
|
+
const seedPlayers: Player[] = [
|
|
342
|
+
{ id: 'player_01HZX4E8Q2K8Y3J9M7T1A6B3C4', name: 'Pablo', score: 65 },
|
|
343
|
+
{ id: 'player_01HZX4E9R6V2D8K1P0N5S4T7U8', name: 'Bunny', score: 10 },
|
|
344
|
+
{ id: 'player_01HZX4EA3M9Q7W1E2R8T6Y5U0I', name: 'Jeff', score: 99 },
|
|
345
|
+
];
|
|
1048
346
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
const oldScore = this.playerMap.get(playerId)!;
|
|
1052
|
-
this.scoreTree.delete(oldScore);
|
|
1053
|
-
}
|
|
347
|
+
class ScoreLeaderboard {
|
|
348
|
+
private readonly byScore: RedBlackTree<number, Player, Player>;
|
|
1054
349
|
|
|
1055
|
-
|
|
1056
|
-
this.
|
|
1057
|
-
|
|
350
|
+
constructor(initialPlayers: Player[]) {
|
|
351
|
+
this.byScore = new RedBlackTree<number, Player, Player>(initialPlayers, {
|
|
352
|
+
isMapMode: false,// Use "node value" storage rather than Map-style.
|
|
353
|
+
toEntryFn: (player) => [player.score, player], // Convert a player object into the tree entry: key = score, value = player.
|
|
354
|
+
});
|
|
1058
355
|
}
|
|
1059
356
|
|
|
1060
|
-
|
|
1061
|
-
|
|
357
|
+
/**
|
|
358
|
+
* Returns players whose scores fall within the given range.
|
|
359
|
+
* Supports either a tuple [min, max] or a Range object for inclusive/exclusive bounds.
|
|
360
|
+
*/
|
|
361
|
+
public findPlayersByScoreRange(range: [number, number] | Range<number>): (Player | undefined)[] {
|
|
362
|
+
return this.byScore.rangeSearch(range, (node) => node.value);
|
|
1062
363
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
if (score === undefined) return null;
|
|
1067
|
-
|
|
1068
|
-
const higherScores = [...this.scoreTree.keys()].filter(s => s > score).length;
|
|
1069
|
-
return higherScores + 1;
|
|
364
|
+
|
|
365
|
+
public upsertPlayer(player: Player) {
|
|
366
|
+
return this.byScore.set(player.score, player);
|
|
1070
367
|
}
|
|
1071
368
|
}
|
|
1072
369
|
|
|
1073
|
-
|
|
1074
|
-
// - Automatically maintains sorted order
|
|
1075
|
-
// - O(log n) insertions and deletions
|
|
1076
|
-
// - O(log n) searches
|
|
1077
|
-
// - Perfect for real-time rankings
|
|
1078
|
-
```
|
|
1079
|
-
|
|
1080
|
-
### Example 4: Task Scheduler with Priority Queue
|
|
1081
|
-
|
|
1082
|
-
```typescript
|
|
1083
|
-
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
1084
|
-
|
|
1085
|
-
interface Task {
|
|
1086
|
-
id: string;
|
|
1087
|
-
priority: number;
|
|
1088
|
-
action: () => Promise<void>;
|
|
1089
|
-
}
|
|
370
|
+
const leaderboard = new ScoreLeaderboard(seedPlayers);
|
|
1090
371
|
|
|
1091
|
-
|
|
1092
|
-
private maxPQ = new MaxPriorityQueue<Task>([], {
|
|
1093
|
-
comparator: (a, b) => b.priority - a.priority,
|
|
1094
|
-
});
|
|
372
|
+
console.log(leaderboard.findPlayersByScoreRange([65, 100]));
|
|
1095
373
|
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
374
|
+
leaderboard.upsertPlayer({
|
|
375
|
+
id: 'player_01HZX4EB7C4N2M9Q8R1T3Y6U5I',
|
|
376
|
+
name: 'Alex',
|
|
377
|
+
score: 80,
|
|
378
|
+
});
|
|
1099
379
|
|
|
1100
|
-
|
|
1101
|
-
while (!this.maxPQ.isEmpty()) {
|
|
1102
|
-
const task = this.maxPQ.poll();
|
|
1103
|
-
if (!task) break;
|
|
1104
|
-
|
|
1105
|
-
try {
|
|
1106
|
-
await task.action();
|
|
1107
|
-
console.log(`Task ${task.id} completed (priority: ${task.priority})`);
|
|
1108
|
-
} catch (error) {
|
|
1109
|
-
console.error(`Task ${task.id} failed (priority: ${task.priority}):`, error);
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
380
|
+
console.log(leaderboard.findPlayersByScoreRange(new Range(65, 100, true, true)));
|
|
1114
381
|
```
|
|
1115
382
|
|
|
1116
|
-
###
|
|
383
|
+
### Message Queue
|
|
1117
384
|
|
|
1118
385
|
```typescript
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
for (const word of words) {
|
|
1128
|
-
const existing = this.trie.get(word);
|
|
1129
|
-
if (!existing) {
|
|
1130
|
-
this.trie.set(word, [docId]);
|
|
1131
|
-
} else {
|
|
1132
|
-
if (!existing.includes(docId)) {
|
|
1133
|
-
existing.push(docId);
|
|
1134
|
-
}
|
|
1135
|
-
this.trie.set(word, existing);
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
386
|
+
type Message = {
|
|
387
|
+
id: string;
|
|
388
|
+
type: string;
|
|
389
|
+
payload: unknown;
|
|
390
|
+
priority: 'urgent' | 'normal';
|
|
391
|
+
createdAt: number;
|
|
392
|
+
retryCount?: number;
|
|
393
|
+
};
|
|
1139
394
|
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
395
|
+
class MessageQueue {
|
|
396
|
+
private urgent = new Deque<Message>();
|
|
397
|
+
private normal = new Deque<Message>();
|
|
1143
398
|
|
|
1144
|
-
|
|
1145
|
-
return this.
|
|
399
|
+
dequeue(): Message | null {
|
|
400
|
+
return this.urgent.shift() || this.normal.shift();
|
|
1146
401
|
}
|
|
1147
402
|
}
|
|
1148
|
-
|
|
1149
|
-
// Why Trie?
|
|
1150
|
-
// - O(m + k) prefix search (m = prefix length, k = results)
|
|
1151
|
-
// - Perfect for autocomplete
|
|
1152
|
-
// - Scales to millions of words
|
|
1153
403
|
```
|
|
1154
404
|
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
## 🔄 Migration Guide: From Native JS
|
|
1158
|
-
|
|
1159
|
-
### Pattern 1: Replacing Array.shift with Deque
|
|
1160
|
-
|
|
1161
|
-
❌ Before:
|
|
1162
|
-
|
|
1163
|
-
```javascript
|
|
1164
|
-
const queue = [1, 2, 3, 4, 5];
|
|
1165
|
-
for (let i = 0; i < 100000; i++) {
|
|
1166
|
-
queue.shift(); // O(n)
|
|
1167
|
-
}
|
|
1168
|
-
```
|
|
1169
|
-
|
|
1170
|
-
✅ After:
|
|
1171
|
-
|
|
1172
|
-
```javascript
|
|
1173
|
-
import { Deque } from 'data-structure-typed';
|
|
1174
|
-
|
|
1175
|
-
const deque = new Deque([1, 2, 3, 4, 5]);
|
|
1176
|
-
for (let i = 0; i < 100000; i++) {
|
|
1177
|
-
deque.shift(); // O(1)
|
|
1178
|
-
}
|
|
1179
|
-
```
|
|
1180
|
-
|
|
1181
|
-
### Pattern 2: Replacing unsorted Map with RedBlackTree
|
|
1182
|
-
|
|
1183
|
-
❌ Before:
|
|
405
|
+
👉 [More examples in GUIDES.md](./docs/GUIDES.md)
|
|
1184
406
|
|
|
1185
|
-
|
|
1186
|
-
const userMap = new Map([
|
|
1187
|
-
[5, { id: 5, name: 'Alice' }],
|
|
1188
|
-
[2, { id: 2, name: 'Bob' }],
|
|
1189
|
-
]);
|
|
407
|
+
---
|
|
1190
408
|
|
|
1191
|
-
|
|
1192
|
-
console.log(id); // 5, 2 (insertion order)
|
|
1193
|
-
}
|
|
1194
|
-
```
|
|
409
|
+
## 🎯 Use Cases by Industry
|
|
1195
410
|
|
|
1196
|
-
|
|
411
|
+
### 📊 Finance
|
|
1197
412
|
|
|
1198
|
-
|
|
1199
|
-
|
|
413
|
+
- Price-sorted order book
|
|
414
|
+
- Real-time portfolio rankings
|
|
415
|
+
- Option chain ordering
|
|
1200
416
|
|
|
1201
|
-
|
|
1202
|
-
[5, { id: 5, name: 'Alice' }],
|
|
1203
|
-
[2, { id: 2, name: 'Bob' }],
|
|
1204
|
-
]);
|
|
417
|
+
### 🎮 Gaming
|
|
1205
418
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
```
|
|
419
|
+
- Player leaderboards
|
|
420
|
+
- Enemy priority queues
|
|
421
|
+
- Game event scheduling
|
|
1210
422
|
|
|
1211
|
-
###
|
|
423
|
+
### 📱 Social Media
|
|
1212
424
|
|
|
1213
|
-
|
|
425
|
+
- Trending posts (top-K)
|
|
426
|
+
- Feed ordering
|
|
427
|
+
- Notification scheduling
|
|
1214
428
|
|
|
1215
|
-
|
|
1216
|
-
const tasks = [];
|
|
1217
|
-
for (const task of incomingTasks) {
|
|
1218
|
-
tasks.push(task);
|
|
1219
|
-
}
|
|
1220
|
-
tasks.sort((a, b) => b.priority - a.priority); // O(n log n)
|
|
1221
|
-
```
|
|
429
|
+
### 🏥 Healthcare
|
|
1222
430
|
|
|
1223
|
-
|
|
431
|
+
- Patient priority queues
|
|
432
|
+
- Appointment scheduling
|
|
433
|
+
- Medical record organization
|
|
1224
434
|
|
|
1225
|
-
|
|
1226
|
-
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
435
|
+
### 🛒 E-commerce
|
|
1227
436
|
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
}
|
|
1232
|
-
```
|
|
437
|
+
- Product price ranges
|
|
438
|
+
- Inventory management
|
|
439
|
+
- Order scheduling
|
|
1233
440
|
|
|
1234
441
|
---
|
|
1235
442
|
|
|
1236
|
-
##
|
|
443
|
+
## ✨ Why Developers Love This
|
|
1237
444
|
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
↓
|
|
1246
|
-
Yes → RedBlackTree (O(log n) search)
|
|
1247
|
-
No → Continue
|
|
1248
|
-
|
|
1249
|
-
Need priority handling?
|
|
1250
|
-
↓
|
|
1251
|
-
Yes → PriorityQueue (O(log n) add)
|
|
1252
|
-
No → Continue
|
|
1253
|
-
|
|
1254
|
-
Need prefix matching?
|
|
1255
|
-
↓
|
|
1256
|
-
Yes → Trie (O(m + k) search)
|
|
1257
|
-
No → Continue
|
|
1258
|
-
|
|
1259
|
-
Need graph algorithms?
|
|
1260
|
-
↓
|
|
1261
|
-
Yes → DirectedGraph / UndirectedGraph
|
|
1262
|
-
No → Use Array
|
|
1263
|
-
```
|
|
445
|
+
| Pain Point | Solution |
|
|
446
|
+
|------------------------------------|-------------------------------------------|
|
|
447
|
+
| Repeated sorting slowing down code | TreeSet auto-maintains order |
|
|
448
|
+
| Array.shift timeout in loops | Deque O(1) shift instead of O(n) |
|
|
449
|
+
| Learning different APIs | All structures use push/pop/shift/unshift |
|
|
450
|
+
| Type safety nightmares | Full TypeScript generics support |
|
|
451
|
+
| Browser compatibility issues | Works everywhere: Node, browsers, CDN |
|
|
1264
452
|
|
|
1265
453
|
---
|
|
1266
454
|
|
|
1267
|
-
##
|
|
455
|
+
## 📦 What You Get
|
|
1268
456
|
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
<th>API Doc</th>
|
|
1276
|
-
<th>NPM</th>
|
|
1277
|
-
<th>Downloads</th>
|
|
1278
|
-
</tr>
|
|
1279
|
-
</thead>
|
|
1280
|
-
<tbody>
|
|
1281
|
-
<tr>
|
|
1282
|
-
<td>Binary Tree</td>
|
|
1283
|
-
<td>✅</td>
|
|
1284
|
-
<td>✅</td>
|
|
1285
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryTree.html">Docs</a></td>
|
|
1286
|
-
<td><a href="https://www.npmjs.com/package/binary-tree-typed">NPM</a></td>
|
|
1287
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/binary-tree-typed"></td>
|
|
1288
|
-
</tr>
|
|
1289
|
-
<tr>
|
|
1290
|
-
<td>Binary Search Tree (BST)</td>
|
|
1291
|
-
<td>✅</td>
|
|
1292
|
-
<td>✅</td>
|
|
1293
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/BST.html">Docs</a></td>
|
|
1294
|
-
<td><a href="https://www.npmjs.com/package/bst-typed">NPM</a></td>
|
|
1295
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/bst-typed"></td>
|
|
1296
|
-
</tr>
|
|
1297
|
-
<tr>
|
|
1298
|
-
<td>AVL Tree</td>
|
|
1299
|
-
<td>✅</td>
|
|
1300
|
-
<td>✅</td>
|
|
1301
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/AVLTree.html">Docs</a></td>
|
|
1302
|
-
<td><a href="https://www.npmjs.com/package/avl-tree-typed">NPM</a></td>
|
|
1303
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/avl-tree-typed"></td>
|
|
1304
|
-
</tr>
|
|
1305
|
-
<tr>
|
|
1306
|
-
<td>Red Black Tree</td>
|
|
1307
|
-
<td>✅</td>
|
|
1308
|
-
<td>✅</td>
|
|
1309
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/RedBlackTree.html">Docs</a></td>
|
|
1310
|
-
<td><a href="https://www.npmjs.com/package/red-black-tree-typed">NPM</a></td>
|
|
1311
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/red-black-tree-typed"></td>
|
|
1312
|
-
</tr>
|
|
1313
|
-
<tr>
|
|
1314
|
-
<td>Tree Multimap</td>
|
|
1315
|
-
<td>✅</td>
|
|
1316
|
-
<td>✅</td>
|
|
1317
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/TreeMultiMap.html">Docs</a></td>
|
|
1318
|
-
<td><a href="https://www.npmjs.com/package/tree-multimap-typed">NPM</a></td>
|
|
1319
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/tree-multimap-typed"></td>
|
|
1320
|
-
</tr>
|
|
1321
|
-
<tr>
|
|
1322
|
-
<td>Heap</td>
|
|
1323
|
-
<td>✅</td>
|
|
1324
|
-
<td>✅</td>
|
|
1325
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/Heap.html">Docs</a></td>
|
|
1326
|
-
<td><a href="https://www.npmjs.com/package/heap-typed">NPM</a></td>
|
|
1327
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/heap-typed"></td>
|
|
1328
|
-
</tr>
|
|
1329
|
-
<tr>
|
|
1330
|
-
<td>Priority Queue</td>
|
|
1331
|
-
<td>✅</td>
|
|
1332
|
-
<td>✅</td>
|
|
1333
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/PriorityQueue.html">Docs</a></td>
|
|
1334
|
-
<td><a href="https://www.npmjs.com/package/priority-queue-typed">NPM</a></td>
|
|
1335
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/priority-queue-typed"></td>
|
|
1336
|
-
</tr>
|
|
1337
|
-
<tr>
|
|
1338
|
-
<td>Max Priority Queue</td>
|
|
1339
|
-
<td>✅</td>
|
|
1340
|
-
<td>✅</td>
|
|
1341
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/MaxPriorityQueue.html">Docs</a></td>
|
|
1342
|
-
<td><a href="https://www.npmjs.com/package/max-priority-queue-typed">NPM</a></td>
|
|
1343
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/max-priority-queue-typed"></td>
|
|
1344
|
-
</tr>
|
|
1345
|
-
<tr>
|
|
1346
|
-
<td>Min Priority Queue</td>
|
|
1347
|
-
<td>✅</td>
|
|
1348
|
-
<td>✅</td>
|
|
1349
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/MinPriorityQueue.html">Docs</a></td>
|
|
1350
|
-
<td><a href="https://www.npmjs.com/package/min-priority-queue-typed">NPM</a></td>
|
|
1351
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/min-priority-queue-typed"></td>
|
|
1352
|
-
</tr>
|
|
1353
|
-
<tr>
|
|
1354
|
-
<td>Trie</td>
|
|
1355
|
-
<td>✅</td>
|
|
1356
|
-
<td>✅</td>
|
|
1357
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/Trie.html">Docs</a></td>
|
|
1358
|
-
<td><a href="https://www.npmjs.com/package/trie-typed">NPM</a></td>
|
|
1359
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/trie-typed"></td>
|
|
1360
|
-
</tr>
|
|
1361
|
-
<tr>
|
|
1362
|
-
<td>Graph</td>
|
|
1363
|
-
<td>✅</td>
|
|
1364
|
-
<td>✅</td>
|
|
1365
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/AbstractGraph.html">Docs</a></td>
|
|
1366
|
-
<td><a href="https://www.npmjs.com/package/graph-typed">NPM</a></td>
|
|
1367
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/graph-typed"></td>
|
|
1368
|
-
</tr>
|
|
1369
|
-
<tr>
|
|
1370
|
-
<td>Directed Graph</td>
|
|
1371
|
-
<td>✅</td>
|
|
1372
|
-
<td>✅</td>
|
|
1373
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/DirectedGraph.html">Docs</a></td>
|
|
1374
|
-
<td><a href="https://www.npmjs.com/package/directed-graph-typed">NPM</a></td>
|
|
1375
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/directed-graph-typed"></td>
|
|
1376
|
-
</tr>
|
|
1377
|
-
<tr>
|
|
1378
|
-
<td>Undirected Graph</td>
|
|
1379
|
-
<td>✅</td>
|
|
1380
|
-
<td>✅</td>
|
|
1381
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/UndirectedGraph.html">Docs</a></td>
|
|
1382
|
-
<td><a href="https://www.npmjs.com/package/undirected-graph-typed">NPM</a></td>
|
|
1383
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/undirected-graph-typed"></td>
|
|
1384
|
-
</tr>
|
|
1385
|
-
<tr>
|
|
1386
|
-
<td>Queue</td>
|
|
1387
|
-
<td>✅</td>
|
|
1388
|
-
<td>✅</td>
|
|
1389
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/Queue.html">Docs</a></td>
|
|
1390
|
-
<td><a href="https://www.npmjs.com/package/queue-typed">NPM</a></td>
|
|
1391
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/queue-typed"></td>
|
|
1392
|
-
</tr>
|
|
1393
|
-
<tr>
|
|
1394
|
-
<td>Deque</td>
|
|
1395
|
-
<td>✅</td>
|
|
1396
|
-
<td>✅</td>
|
|
1397
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/Deque.html">Docs</a></td>
|
|
1398
|
-
<td><a href="https://www.npmjs.com/package/deque-typed">NPM</a></td>
|
|
1399
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/deque-typed"></td>
|
|
1400
|
-
</tr>
|
|
1401
|
-
<tr>
|
|
1402
|
-
<td>Hash Map</td>
|
|
1403
|
-
<td>✅</td>
|
|
1404
|
-
<td>✅</td>
|
|
1405
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/HashMap.html">Docs</a></td>
|
|
1406
|
-
<td><a href="https://www.npmjs.com/package/hashmap-typed">NPM</a></td>
|
|
1407
|
-
<td></td>
|
|
1408
|
-
</tr>
|
|
1409
|
-
<tr>
|
|
1410
|
-
<td>Linked List</td>
|
|
1411
|
-
<td>✅</td>
|
|
1412
|
-
<td>✅</td>
|
|
1413
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/SinglyLinkedList.html">Docs</a></td>
|
|
1414
|
-
<td><a href="https://www.npmjs.com/package/linked-list-typed">NPM</a></td>
|
|
1415
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/linked-list-typed"></td>
|
|
1416
|
-
</tr>
|
|
1417
|
-
<tr>
|
|
1418
|
-
<td>Singly Linked List</td>
|
|
1419
|
-
<td>✅</td>
|
|
1420
|
-
<td>✅</td>
|
|
1421
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/SinglyLinkedList.html">Docs</a></td>
|
|
1422
|
-
<td><a href="https://www.npmjs.com/package/singly-linked-list-typed">NPM</a></td>
|
|
1423
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/singly-linked-list-typed"></td>
|
|
1424
|
-
</tr>
|
|
1425
|
-
<tr>
|
|
1426
|
-
<td>Doubly Linked List</td>
|
|
1427
|
-
<td>✅</td>
|
|
1428
|
-
<td>✅</td>
|
|
1429
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/DoublyLinkedList.html">Docs</a></td>
|
|
1430
|
-
<td><a href="https://www.npmjs.com/package/doubly-linked-list-typed">NPM</a></td>
|
|
1431
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/doubly-linked-list-typed"></td>
|
|
1432
|
-
</tr>
|
|
1433
|
-
<tr>
|
|
1434
|
-
<td>Stack</td>
|
|
1435
|
-
<td>✅</td>
|
|
1436
|
-
<td>✅</td>
|
|
1437
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/Stack.html">Docs</a></td>
|
|
1438
|
-
<td><a href="https://www.npmjs.com/package/stack-typed">NPM</a></td>
|
|
1439
|
-
<td><img alt="NPM Downloads" src="https://img.shields.io/npm/dm/stack-typed"></td>
|
|
1440
|
-
</tr>
|
|
1441
|
-
<tr>
|
|
1442
|
-
<td>Segment Tree</td>
|
|
1443
|
-
<td>✅</td>
|
|
1444
|
-
<td></td>
|
|
1445
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/SegmentTree.html">Docs</a></td>
|
|
1446
|
-
<td><a href="https://www.npmjs.com/package/segment-tree-typed">NPM</a></td>
|
|
1447
|
-
<td></td>
|
|
1448
|
-
</tr>
|
|
1449
|
-
<tr>
|
|
1450
|
-
<td>Binary Indexed Tree</td>
|
|
1451
|
-
<td>✅</td>
|
|
1452
|
-
<td></td>
|
|
1453
|
-
<td><a href="https://data-structure-typed-docs.vercel.app/classes/BinaryIndexedTree.html">Docs</a></td>
|
|
1454
|
-
<td><a href="https://www.npmjs.com/package/binary-indexed-tree-typed">NPM</a></td>
|
|
1455
|
-
<td></td>
|
|
1456
|
-
</tr>
|
|
1457
|
-
</tbody>
|
|
1458
|
-
</table>
|
|
457
|
+
✅ **20+ data structures** (production-ready)
|
|
458
|
+
✅ **50+ code examples** (real-world patterns)
|
|
459
|
+
✅ **Full TypeScript support** (strict typing)
|
|
460
|
+
✅ **Performance benchmarks** (484x speedups)
|
|
461
|
+
✅ **Framework integrations** (React, Express, Nest.js)
|
|
462
|
+
✅ **6 core documentation files** (2500+ lines)
|
|
1459
463
|
|
|
1460
464
|
---
|
|
1461
465
|
|
|
1462
|
-
##
|
|
1463
|
-
|
|
1464
|
-
[Try it out](https://vivid-algorithm.vercel.app/), or you can run your own code using our [visual tool](https://github.com/zrwusa/vivid-algorithm)
|
|
1465
|
-
|
|
1466
|
-
### AVL Tree
|
|
1467
|
-
|
|
1468
|
-

|
|
1469
|
-
|
|
1470
|
-
### Tree Multi Map
|
|
1471
|
-
|
|
1472
|
-

|
|
1473
|
-
|
|
1474
|
-
### Directed Graph
|
|
1475
|
-
|
|
1476
|
-

|
|
1477
|
-
|
|
1478
|
-
### Map Graph
|
|
466
|
+
## 🚀 Getting Started
|
|
1479
467
|
|
|
1480
|
-
|
|
468
|
+
### Step 1: Install
|
|
1481
469
|
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
## 🔗 Integration Examples
|
|
1485
|
-
|
|
1486
|
-
### React: State Management with Sorted Data
|
|
1487
|
-
|
|
1488
|
-
```tsx
|
|
1489
|
-
import { useMemo, useState } from 'react';
|
|
1490
|
-
import { RedBlackTree } from 'data-structure-typed';
|
|
1491
|
-
|
|
1492
|
-
type TodoItem = { id: number; title: string };
|
|
1493
|
-
|
|
1494
|
-
export default function TodoList() {
|
|
1495
|
-
const [todoTree, setTodoTree] = useState(
|
|
1496
|
-
new RedBlackTree<number, TodoItem>([
|
|
1497
|
-
[100, { id: 100, title: 'Title 100' }],
|
|
1498
|
-
[1, { id: 1, title: 'Title 1' }],
|
|
1499
|
-
])
|
|
1500
|
-
);
|
|
1501
|
-
|
|
1502
|
-
const todos = useMemo(() => [...todoTree.values()], [todoTree]);
|
|
1503
|
-
|
|
1504
|
-
const addTodo = () => {
|
|
1505
|
-
setTodoTree((prev) => {
|
|
1506
|
-
const next = prev.clone();
|
|
1507
|
-
let id = Math.floor(Math.random() * 100);
|
|
1508
|
-
while (next.has(id)) {
|
|
1509
|
-
id = Math.floor(Math.random() * 100);
|
|
1510
|
-
}
|
|
1511
|
-
next.add(id, { id, title: `Title ${id}` });
|
|
1512
|
-
return next;
|
|
1513
|
-
});
|
|
1514
|
-
};
|
|
1515
|
-
|
|
1516
|
-
const deleteTodo = (id: number) => {
|
|
1517
|
-
setTodoTree((prev) => {
|
|
1518
|
-
const next = prev.clone();
|
|
1519
|
-
next.delete(id);
|
|
1520
|
-
return next;
|
|
1521
|
-
});
|
|
1522
|
-
};
|
|
1523
|
-
|
|
1524
|
-
return (
|
|
1525
|
-
<div>
|
|
1526
|
-
<h2>Todo List (sorted by id)</h2>
|
|
1527
|
-
{/* Component implementation */}
|
|
1528
|
-
</div>
|
|
1529
|
-
);
|
|
1530
|
-
}
|
|
470
|
+
```bash
|
|
471
|
+
npm i data-structure-typed
|
|
1531
472
|
```
|
|
1532
473
|
|
|
1533
|
-
###
|
|
474
|
+
### Step 2: Import
|
|
1534
475
|
|
|
1535
476
|
```typescript
|
|
1536
|
-
import
|
|
1537
|
-
import { DoublyLinkedList } from 'data-structure-typed';
|
|
1538
|
-
|
|
1539
|
-
interface CacheEntry {
|
|
1540
|
-
key: string;
|
|
1541
|
-
value: any;
|
|
1542
|
-
}
|
|
1543
|
-
|
|
1544
|
-
class ApiCache {
|
|
1545
|
-
private cache = new DoublyLinkedList<CacheEntry>();
|
|
1546
|
-
private keyMap = new Map<string, any>();
|
|
1547
|
-
private maxSize = 1000;
|
|
1548
|
-
|
|
1549
|
-
set(key: string, value: any): void {
|
|
1550
|
-
const entry: CacheEntry = { key, value };
|
|
1551
|
-
this.cache.push(entry);
|
|
1552
|
-
this.keyMap.set(key, value);
|
|
1553
|
-
|
|
1554
|
-
if (this.cache.size > this.maxSize) {
|
|
1555
|
-
const oldest = this.cache.shift();
|
|
1556
|
-
if (oldest) {
|
|
1557
|
-
this.keyMap.delete(oldest.key);
|
|
1558
|
-
}
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
get(key: string): any {
|
|
1563
|
-
return this.keyMap.get(key);
|
|
1564
|
-
}
|
|
1565
|
-
}
|
|
1566
|
-
|
|
1567
|
-
const app = express();
|
|
1568
|
-
const cache = new ApiCache();
|
|
1569
|
-
|
|
1570
|
-
app.get('/api/user/:id', (req, res) => {
|
|
1571
|
-
const cacheKey = `user:${req.params.id}`;
|
|
1572
|
-
let userData = cache.get(cacheKey);
|
|
1573
|
-
if (!userData) {
|
|
1574
|
-
userData = { id: req.params.id, name: 'User' };
|
|
1575
|
-
cache.set(cacheKey, userData);
|
|
1576
|
-
}
|
|
1577
|
-
res.json(userData);
|
|
1578
|
-
});
|
|
477
|
+
import { RedBlackTree, Deque, MaxPriorityQueue } from 'data-structure-typed';
|
|
1579
478
|
```
|
|
1580
479
|
|
|
1581
|
-
###
|
|
480
|
+
### Step 3: Use
|
|
1582
481
|
|
|
1583
482
|
```typescript
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
interface RankEntry {
|
|
1588
|
-
userId: string;
|
|
1589
|
-
score: number;
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
@Injectable()
|
|
1593
|
-
export class RankingService {
|
|
1594
|
-
private rankingTree = new RedBlackTree<number, RankEntry>();
|
|
1595
|
-
|
|
1596
|
-
updateScore(userId: string, newScore: number): void {
|
|
1597
|
-
const existing = [...this.rankingTree.values()].find(
|
|
1598
|
-
(e) => e?.userId === userId
|
|
1599
|
-
);
|
|
1600
|
-
|
|
1601
|
-
if (existing) {
|
|
1602
|
-
this.rankingTree.delete(existing.score);
|
|
1603
|
-
}
|
|
1604
|
-
|
|
1605
|
-
this.rankingTree.add(newScore, { userId, score: newScore });
|
|
1606
|
-
}
|
|
1607
|
-
|
|
1608
|
-
getRanking(topN: number = 100): RankEntry[] | undefined {
|
|
1609
|
-
return [...this.rankingTree.values()].reverse().slice(0, topN);
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
getUserRank(userId: string): number | null {
|
|
1613
|
-
const allEntries = [...this.rankingTree.values()].reverse();
|
|
1614
|
-
const index = allEntries.findIndex((e) => e?.userId === userId);
|
|
1615
|
-
return index >= 0 ? index + 1 : null;
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
483
|
+
const tree = new RedBlackTree([5, 2, 8]);
|
|
484
|
+
console.log([...tree]); // [2, 5, 8] - Automatically sorted!
|
|
1618
485
|
```
|
|
1619
486
|
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
## Free Conversion Between Data Structures
|
|
1623
|
-
|
|
1624
|
-
```js
|
|
1625
|
-
const orgArr = [6, 1, 2, 7, 5, 3, 4, 9, 8];
|
|
1626
|
-
const entries = [[6, "6"], [1, "1"], [2, "2"], [7, "7"], [5, "5"], [3, "3"], [4, "4"], [9, "9"], [8, "8"]];
|
|
1627
|
-
|
|
1628
|
-
const queue = new Queue(orgArr);
|
|
1629
|
-
queue.print();
|
|
1630
|
-
// [6, 1, 2, 7, 5, 3, 4, 9, 8]
|
|
1631
|
-
|
|
1632
|
-
const deque = new Deque(orgArr);
|
|
1633
|
-
deque.print();
|
|
1634
|
-
// [6, 1, 2, 7, 5, 3, 4, 9, 8]
|
|
1635
|
-
|
|
1636
|
-
const sList = new SinglyLinkedList(orgArr);
|
|
1637
|
-
sList.print();
|
|
1638
|
-
// [6, 1, 2, 7, 5, 3, 4, 9, 8]
|
|
1639
|
-
|
|
1640
|
-
const dList = new DoublyLinkedList(orgArr);
|
|
1641
|
-
dList.print();
|
|
1642
|
-
// [6, 1, 2, 7, 5, 3, 4, 9, 8]
|
|
1643
|
-
|
|
1644
|
-
const stack = new Stack(orgArr);
|
|
1645
|
-
stack.print();
|
|
1646
|
-
// [6, 1, 2, 7, 5, 3, 4, 9, 8]
|
|
1647
|
-
|
|
1648
|
-
const minHeap = new MinHeap(orgArr);
|
|
1649
|
-
minHeap.print();
|
|
1650
|
-
// [1, 5, 2, 7, 6, 3, 4, 9, 8]
|
|
1651
|
-
|
|
1652
|
-
const maxPQ = new MaxPriorityQueue(orgArr);
|
|
1653
|
-
maxPQ.print();
|
|
1654
|
-
// [9, 8, 4, 7, 5, 2, 3, 1, 6]
|
|
1655
|
-
|
|
1656
|
-
const biTree = new BinaryTree(entries);
|
|
1657
|
-
biTree.print();
|
|
1658
|
-
// ___6___
|
|
1659
|
-
// / \
|
|
1660
|
-
// ___1_ _2_
|
|
1661
|
-
// / \ / \
|
|
1662
|
-
// _7_ 5 3 4
|
|
1663
|
-
// / \
|
|
1664
|
-
// 9 8
|
|
1665
|
-
|
|
1666
|
-
const bst = new BST(entries);
|
|
1667
|
-
bst.print();
|
|
1668
|
-
// _____5___
|
|
1669
|
-
// / \
|
|
1670
|
-
// _2_ _7_
|
|
1671
|
-
// / \ / \
|
|
1672
|
-
// 1 3_ 6 8_
|
|
1673
|
-
// \ \
|
|
1674
|
-
// 4 9
|
|
1675
|
-
|
|
1676
|
-
const rbTree = new RedBlackTree(entries);
|
|
1677
|
-
rbTree.print();
|
|
1678
|
-
// ___4___
|
|
1679
|
-
// / \
|
|
1680
|
-
// _2_ _6___
|
|
1681
|
-
// / \ / \
|
|
1682
|
-
// 1 3 5 _8_
|
|
1683
|
-
// / \
|
|
1684
|
-
// 7 9
|
|
1685
|
-
|
|
1686
|
-
const avl = new AVLTree(entries);
|
|
1687
|
-
avl.print();
|
|
1688
|
-
// ___4___
|
|
1689
|
-
// / \
|
|
1690
|
-
// _2_ _6___
|
|
1691
|
-
// / \ / \
|
|
1692
|
-
// 1 3 5 _8_
|
|
1693
|
-
// / \
|
|
1694
|
-
// 7 9
|
|
1695
|
-
|
|
1696
|
-
const treeMulti = new TreeMultiMap(entries);
|
|
1697
|
-
treeMulti.print();
|
|
1698
|
-
// ___4___
|
|
1699
|
-
// / \
|
|
1700
|
-
// _2_ _6___
|
|
1701
|
-
// / \ / \
|
|
1702
|
-
// 1 3 5 _8_
|
|
1703
|
-
// / \
|
|
1704
|
-
// 7 9
|
|
1705
|
-
|
|
1706
|
-
const hm = new HashMap(entries);
|
|
1707
|
-
hm.print()
|
|
1708
|
-
// [[6, "6"], [1, "1"], [2, "2"], [7, "7"], [5, "5"], [3, "3"], [4, "4"], [9, "9"], [8, "8"]]
|
|
1709
|
-
|
|
1710
|
-
const rbTreeH = new RedBlackTree(hm);
|
|
1711
|
-
rbTreeH.print();
|
|
1712
|
-
// ___4___
|
|
1713
|
-
// / \
|
|
1714
|
-
// _2_ _6___
|
|
1715
|
-
// / \ / \
|
|
1716
|
-
// 1 3 5 _8_
|
|
1717
|
-
// / \
|
|
1718
|
-
// 7 9
|
|
1719
|
-
|
|
1720
|
-
const pq = new MinPriorityQueue(orgArr);
|
|
1721
|
-
pq.print();
|
|
1722
|
-
// [1, 5, 2, 7, 6, 3, 4, 9, 8]
|
|
1723
|
-
|
|
1724
|
-
const bst1 = new BST(pq);
|
|
1725
|
-
bst1.print();
|
|
1726
|
-
// _____5___
|
|
1727
|
-
// / \
|
|
1728
|
-
// _2_ _7_
|
|
1729
|
-
// / \ / \
|
|
1730
|
-
// 1 3_ 6 8_
|
|
1731
|
-
// \ \
|
|
1732
|
-
// 4 9
|
|
1733
|
-
|
|
1734
|
-
const dq1 = new Deque(orgArr);
|
|
1735
|
-
dq1.print();
|
|
1736
|
-
// [6, 1, 2, 7, 5, 3, 4, 9, 8]
|
|
1737
|
-
const rbTree1 = new RedBlackTree(dq1);
|
|
1738
|
-
rbTree1.print();
|
|
1739
|
-
// _____5___
|
|
1740
|
-
// / \
|
|
1741
|
-
// _2___ _7___
|
|
1742
|
-
// / \ / \
|
|
1743
|
-
// 1 _4 6 _9
|
|
1744
|
-
// / /
|
|
1745
|
-
// 3 8
|
|
1746
|
-
```
|
|
487
|
+
## 🏃🏻♀️ Playground
|
|
1747
488
|
|
|
1748
|
-
|
|
489
|
+
Try it instantly:
|
|
1749
490
|
|
|
1750
|
-
|
|
491
|
+
- [Node.js TypeScript](https://stackblitz.com/edit/stackblitz-starters-e1vdy3zw?file=src%2Findex.ts)
|
|
492
|
+
- [Node.js JavaScript](https://stackblitz.com/edit/stackblitz-starters-dgvchziu?file=src%2Findex.js)
|
|
493
|
+
- [React TypeScript](https://stackblitz.com/edit/vitejs-vite-6xvhtdua?file=src%2FApp.tsx)
|
|
494
|
+
- [NestJS](https://stackblitz.com/edit/nestjs-typescript-starter-3cyp7pel?file=src%2Franking%2Franking.service.ts)
|
|
1751
495
|
|
|
1752
|
-
Now you can use it in Node.js and browser environments
|
|
1753
496
|
|
|
1754
|
-
###
|
|
497
|
+
### Step 4: Learn More
|
|
1755
498
|
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
- **UMD**: `var Deque = dataStructureTyped.Deque`
|
|
499
|
+
👉 Check [CONCEPTS.md](./docs/CONCEPTS.md) for core concepts
|
|
500
|
+
👉 See [GUIDES.md](./docs/GUIDES.md) for production examples
|
|
501
|
+
👉 Read [REFERENCE.md](./docs/REFERENCE.md) for complete API
|
|
1760
502
|
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
#### Development
|
|
1764
|
-
|
|
1765
|
-
##### ES Module
|
|
503
|
+
---
|
|
1766
504
|
|
|
1767
|
-
|
|
1768
|
-
<script type="module">
|
|
1769
|
-
import { BST } from "https://cdn.jsdelivr.net/npm/data-structure-typed/dist/esm/index.mjs";
|
|
505
|
+
## 📊 Comparison Chart
|
|
1770
506
|
|
|
1771
|
-
const bst = new BST([2, 1, 6, 7, 5, 3, 4, 8, 9]);
|
|
1772
|
-
bst.print();
|
|
1773
|
-
</script>
|
|
1774
507
|
```
|
|
508
|
+
Need frequent head/tail operations?
|
|
509
|
+
→ Deque (O(1) shift/unshift/push/pop)
|
|
1775
510
|
|
|
1776
|
-
|
|
511
|
+
Need sorted + fast lookup?
|
|
512
|
+
→ RedBlackTree (O(log n) guaranteed)
|
|
1777
513
|
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
```
|
|
514
|
+
Need highest/lowest priority?
|
|
515
|
+
→ Heap/PriorityQueue (O(log n) add/remove)
|
|
1781
516
|
|
|
1782
|
-
|
|
517
|
+
Need prefix/text matching?
|
|
518
|
+
→ Trie (O(m+k) where m=prefix)
|
|
1783
519
|
|
|
1784
|
-
|
|
1785
|
-
|
|
520
|
+
Need graph operations?
|
|
521
|
+
→ DirectedGraph/UndirectedGraph
|
|
1786
522
|
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
const { BinaryTree, Graph, Queue, Stack } = dataStructureTyped;
|
|
1790
|
-
|
|
1791
|
-
const heap = new Heap([1, 2, 3]);
|
|
1792
|
-
heap.print();
|
|
1793
|
-
</script>
|
|
523
|
+
Otherwise?
|
|
524
|
+
→ Use Array (simplest case)
|
|
1794
525
|
```
|
|
1795
526
|
|
|
1796
527
|
---
|
|
1797
528
|
|
|
1798
|
-
##
|
|
1799
|
-
|
|
1800
|
-
<table style="display: table; width:100%; table-layout: fixed;">
|
|
1801
|
-
<tr>
|
|
1802
|
-
<th>Principle</th>
|
|
1803
|
-
<th>Description</th>
|
|
1804
|
-
</tr>
|
|
1805
|
-
<tr>
|
|
1806
|
-
<td>Practicality</td>
|
|
1807
|
-
<td>Follows ES6 and ESNext standards, offering unified and considerate optional parameters, and simplifies method names.</td>
|
|
1808
|
-
</tr>
|
|
1809
|
-
<tr>
|
|
1810
|
-
<td>Extensibility</td>
|
|
1811
|
-
<td>Adheres to OOP (Object-Oriented Programming) principles, allowing inheritance for all data structures.</td>
|
|
1812
|
-
</tr>
|
|
1813
|
-
<tr>
|
|
1814
|
-
<td>Modularization</td>
|
|
1815
|
-
<td>Includes data structure modularization and independent NPM packages.</td>
|
|
1816
|
-
</tr>
|
|
1817
|
-
<tr>
|
|
1818
|
-
<td>Efficiency</td>
|
|
1819
|
-
<td>All methods provide time and space complexity, comparable to native JS performance.</td>
|
|
1820
|
-
</tr>
|
|
1821
|
-
<tr>
|
|
1822
|
-
<td>Maintainability</td>
|
|
1823
|
-
<td>Follows open-source community development standards, complete documentation, continuous integration, and adheres to TDD (Test-Driven Development) patterns.</td>
|
|
1824
|
-
</tr>
|
|
1825
|
-
<tr>
|
|
1826
|
-
<td>Testability</td>
|
|
1827
|
-
<td>Automated and customized unit testing, performance testing, and integration testing.</td>
|
|
1828
|
-
</tr>
|
|
1829
|
-
<tr>
|
|
1830
|
-
<td>Portability</td>
|
|
1831
|
-
<td>Plans for porting to Java, Python, and C++, currently achieved to 80%.</td>
|
|
1832
|
-
</tr>
|
|
1833
|
-
<tr>
|
|
1834
|
-
<td>Reusability</td>
|
|
1835
|
-
<td>Fully decoupled, minimized side effects, and adheres to OOP.</td>
|
|
1836
|
-
</tr>
|
|
1837
|
-
<tr>
|
|
1838
|
-
<td>Security</td>
|
|
1839
|
-
<td>Carefully designed security for member variables and methods. Read-write separation. Data structure software does not need to consider other security aspects.</td>
|
|
1840
|
-
</tr>
|
|
1841
|
-
<tr>
|
|
1842
|
-
<td>Scalability</td>
|
|
1843
|
-
<td>Data structure software does not involve load issues.</td>
|
|
1844
|
-
</tr>
|
|
1845
|
-
</table>
|
|
529
|
+
## 🤝 Contributing
|
|
1846
530
|
|
|
1847
|
-
|
|
531
|
+
Found a bug? Have suggestions? [Open an issue](https://github.com/zrwusa/data-structure-typed/issues)
|
|
1848
532
|
|
|
1849
|
-
|
|
533
|
+
---
|
|
1850
534
|
|
|
1851
|
-
|
|
535
|
+
## 📄 License
|
|
1852
536
|
|
|
1853
|
-
|
|
1854
|
-
// Generic type parameters
|
|
1855
|
-
const bst = new BST<number, { name: string }>();
|
|
1856
|
-
bst.add(10, { name: 'Alice' });
|
|
537
|
+
MIT
|
|
1857
538
|
|
|
1858
|
-
|
|
1859
|
-
const value: { name: string } | undefined = bst.get(10);
|
|
539
|
+
---
|
|
1860
540
|
|
|
1861
|
-
|
|
1862
|
-
const descBST = new BST<number>([], (a, b) => b - a);
|
|
541
|
+
## 📚 Full Documentation Structure
|
|
1863
542
|
|
|
1864
|
-
|
|
1865
|
-
|
|
543
|
+
```
|
|
544
|
+
docs/
|
|
545
|
+
├── README.md (this file)
|
|
546
|
+
├── CONCEPTS.md (theory & fundamentals)
|
|
547
|
+
├── REFERENCE.md (API documentation)
|
|
548
|
+
├── ARCHITECTURE.md (design principles)
|
|
549
|
+
├── PERFORMANCE.md (benchmarks)
|
|
550
|
+
├── GUIDES.md (real-world examples)
|
|
551
|
+
└── INTEGRATIONS.md (framework guides)
|
|
1866
552
|
```
|
|
1867
553
|
|
|
1868
554
|
---
|
|
1869
555
|
|
|
1870
|
-
##
|
|
556
|
+
## 🎓 Learn More
|
|
1871
557
|
|
|
1872
|
-
|
|
558
|
+
**Just started?** → [Quick Start](#-quick-start-30-seconds)
|
|
1873
559
|
|
|
1874
|
-
|
|
1875
|
-
- **Discussions**: [GitHub Discussions](https://github.com/zrwusa/data-structure-typed/discussions)
|
|
560
|
+
**Need concepts?** → [CONCEPTS.md](./docs/CONCEPTS.md)
|
|
1876
561
|
|
|
1877
|
-
|
|
562
|
+
**Want to build?** → [GUIDES.md](./docs/GUIDES.md)
|
|
1878
563
|
|
|
1879
|
-
|
|
564
|
+
**Need API?** → [REFERENCE.md](./docs/REFERENCE.md)
|
|
1880
565
|
|
|
1881
|
-
[
|
|
566
|
+
**Curious about performance?** → [PERFORMANCE.md](./docs/PERFORMANCE.md)
|
|
1882
567
|
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
## 🙏 Thank You
|
|
568
|
+
**Framework questions?** → [INTEGRATIONS.md](./docs/INTEGRATIONS.md)
|
|
1886
569
|
|
|
1887
|
-
|
|
570
|
+
---
|
|
1888
571
|
|
|
1889
|
-
|
|
572
|
+
**Ready to supercharge your TypeScript data structures? [Get started now →](#-quick-start-30-seconds)**
|