data-structure-typed 2.2.2 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -1
- package/README.md +311 -1687
- 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 +163 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs-legacy/index.cjs +164 -0
- package/dist/cjs-legacy/index.cjs.map +1 -1
- package/dist/esm/index.mjs +163 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm-legacy/index.mjs +164 -0
- package/dist/esm-legacy/index.mjs.map +1 -1
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +96 -2
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +103 -7
- package/dist/types/data-structures/binary-tree/bst.d.ts +156 -13
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +84 -35
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +2 -2
- package/dist/types/data-structures/graph/directed-graph.d.ts +126 -1
- package/dist/types/data-structures/graph/undirected-graph.d.ts +160 -1
- package/dist/types/data-structures/hash/hash-map.d.ts +110 -27
- package/dist/types/data-structures/heap/heap.d.ts +107 -58
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +72 -404
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +121 -5
- package/dist/types/data-structures/queue/deque.d.ts +95 -67
- package/dist/types/data-structures/queue/queue.d.ts +90 -34
- package/dist/types/data-structures/stack/stack.d.ts +58 -40
- package/dist/types/data-structures/trie/trie.d.ts +109 -47
- package/dist/types/interfaces/binary-tree.d.ts +1 -0
- package/dist/umd/data-structure-typed.js +164 -0
- 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.ts +96 -2
- package/src/data-structures/binary-tree/binary-tree.ts +117 -7
- package/src/data-structures/binary-tree/bst.ts +322 -13
- package/src/data-structures/binary-tree/red-black-tree.ts +84 -35
- package/src/data-structures/binary-tree/tree-multi-map.ts +2 -2
- package/src/data-structures/graph/directed-graph.ts +126 -1
- package/src/data-structures/graph/undirected-graph.ts +160 -1
- package/src/data-structures/hash/hash-map.ts +110 -27
- package/src/data-structures/heap/heap.ts +107 -58
- package/src/data-structures/linked-list/doubly-linked-list.ts +72 -404
- package/src/data-structures/linked-list/singly-linked-list.ts +121 -5
- package/src/data-structures/queue/deque.ts +95 -67
- package/src/data-structures/queue/queue.ts +90 -34
- package/src/data-structures/stack/stack.ts +58 -40
- package/src/data-structures/trie/trie.ts +109 -47
- package/src/interfaces/binary-tree.ts +2 -0
- 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.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 +766 -8
- package/test/unit/data-structures/binary-tree/red-black-tree.test.ts +89 -37
- 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,513 @@
|
|
|
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) • [Full Docs](./docs/CONCEPTS.md) • [API Reference](./docs/REFERENCE.md) • [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
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
✅ The Solution: Use Deque:
|
|
255
|
-
|
|
256
|
-
```javascript
|
|
257
|
-
import { Deque } from 'data-structure-typed';
|
|
58
|
+
// Time: 2829ms ❌
|
|
258
59
|
|
|
259
|
-
|
|
60
|
+
// ✅ WITH data-structure-typed (Deque)
|
|
61
|
+
const deque = new Deque([1, 2, 3, ..., 100000
|
|
62
|
+
])
|
|
63
|
+
;
|
|
260
64
|
for (let i = 0; i < 100000; i++) {
|
|
261
65
|
deque.shift(); // O(1) - Just moves a pointer
|
|
262
66
|
}
|
|
263
|
-
// Time: 5.83ms
|
|
264
|
-
//
|
|
67
|
+
// Time: 5.83ms ✅
|
|
68
|
+
// **484x faster!**
|
|
265
69
|
```
|
|
266
70
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
- Competitive programming: TLE ❌ → AC ✅
|
|
270
|
-
- Real-time systems: P99 latency 500ms ❌ → 5ms ✅
|
|
271
|
-
- Message queues: Throughput 100/sec ❌ → 10,000/sec ✅
|
|
71
|
+
---
|
|
272
72
|
|
|
273
|
-
|
|
73
|
+
## 🚀 Performance (TL;DR)
|
|
274
74
|
|
|
275
|
-
|
|
75
|
+
- **10–40% faster** than common JS implementations in hot paths
|
|
76
|
+
- Array.sort() O(n log n) → TreeSet O(log n) insertion
|
|
77
|
+
- Repeated Array.shift() O(n) → Queue O(1)
|
|
78
|
+
- Manual index tracking → RB-Tree auto-balance
|
|
276
79
|
|
|
277
|
-
|
|
278
|
-
// Library 1: Uses offer/poll (Java-style)
|
|
279
|
-
queue.offer(item);
|
|
280
|
-
queue.poll();
|
|
80
|
+
- **Optimized for V8 JIT** (Node.js 18+, modern browsers)
|
|
281
81
|
|
|
282
|
-
|
|
283
|
-
queue.push(item);
|
|
284
|
-
queue.shift();
|
|
82
|
+
- **Tree-shakable** ESM / CJS / legacy builds
|
|
285
83
|
|
|
286
|
-
|
|
287
|
-
queue.enqueue(item);
|
|
288
|
-
queue.dequeue();
|
|
289
|
-
```
|
|
84
|
+
📊 [Full benchmarks →](./docs/PERFORMANCE.md)
|
|
290
85
|
|
|
291
|
-
|
|
86
|
+
---
|
|
292
87
|
|
|
293
|
-
|
|
88
|
+
## ✨ Key Features
|
|
294
89
|
|
|
295
|
-
|
|
296
|
-
|---|---|---|---|
|
|
297
|
-
| add | offer | push | push |
|
|
298
|
-
| remove | poll | removeLast | removeLast |
|
|
299
|
-
| remove | poll | removeFirst | removeFirst |
|
|
300
|
-
| add(0, element) | offerFirst | unshift | unshift |
|
|
90
|
+
### 🏠 Uniform API
|
|
301
91
|
|
|
302
|
-
|
|
92
|
+
Don't learn new APIs. Just use `push`, `pop`, `map`, `filter`, and `reduce` everywhere.
|
|
303
93
|
|
|
304
94
|
```javascript
|
|
305
|
-
//
|
|
95
|
+
// All linear structures use THE SAME 4 methods
|
|
306
96
|
const deque = new Deque([1, 2, 3]);
|
|
307
97
|
const queue = new Queue([1, 2, 3]);
|
|
308
98
|
const stack = new Stack([1, 2, 3]);
|
|
309
|
-
const list = new DoublyLinkedList([1, 2, 3]);
|
|
310
99
|
|
|
311
100
|
// 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] ✅
|
|
101
|
+
structure.push(item); // Add to end
|
|
102
|
+
structure.pop(); // Remove from end
|
|
103
|
+
structure.shift(); // Remove from start
|
|
104
|
+
structure.unshift(item); // Add to start
|
|
384
105
|
```
|
|
385
106
|
|
|
386
|
-
|
|
107
|
+
### 🛡️ Type Safe
|
|
387
108
|
|
|
388
|
-
|
|
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
|
-
---
|
|
412
|
-
|
|
413
|
-
## 🎁 All Array Methods Work Everywhere
|
|
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
|
|
109
|
+
Full generics and strict TypeScript support out of the box.
|
|
420
110
|
|
|
421
111
|
```typescript
|
|
422
|
-
const
|
|
423
|
-
|
|
424
|
-
|
|
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);
|
|
112
|
+
const tree = new RedBlackTree<number, string>();
|
|
113
|
+
tree.set(1, 'Alice');
|
|
114
|
+
tree.set(2, 'Bob');
|
|
432
115
|
|
|
433
|
-
|
|
116
|
+
// Type-safe access
|
|
117
|
+
const value = tree.get(1); // Type: string | undefined
|
|
434
118
|
```
|
|
435
119
|
|
|
436
|
-
|
|
120
|
+
### ✨ Zero Friction
|
|
437
121
|
|
|
438
|
-
|
|
439
|
-
const minHeap = new Heap([
|
|
440
|
-
{ priority: 5, task: 'Email' },
|
|
441
|
-
{ priority: 3, task: 'Chat' },
|
|
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);
|
|
448
|
-
|
|
449
|
-
urgent.print(); // ['Alert', 'Email'] ✅
|
|
450
|
-
```
|
|
451
|
-
|
|
452
|
-
#### Chain on Deque
|
|
453
|
-
|
|
454
|
-
```typescript
|
|
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:
|
|
122
|
+
Works everywhere. Spread it `[...]`, loop it `for..of`, convert it instantly.
|
|
484
123
|
|
|
485
124
|
```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 ✅
|
|
125
|
+
// All data structures work with iterator protocol
|
|
126
|
+
const tree = new RedBlackTree([5, 2, 8]);
|
|
127
|
+
const sorted = [...tree]; // Spread operator
|
|
128
|
+
for (const item of tree) {
|
|
129
|
+
} // for...of loop
|
|
130
|
+
const set = new Set(tree); // Set constructor
|
|
519
131
|
```
|
|
520
132
|
|
|
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
|
-
```
|
|
133
|
+
---
|
|
532
134
|
|
|
533
|
-
|
|
135
|
+
## 📥 Installation
|
|
534
136
|
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
function addTask(task) {
|
|
538
|
-
pq.add(task); // O(log n)
|
|
539
|
-
}
|
|
137
|
+
```bash
|
|
138
|
+
pnpm add data-structure-typed
|
|
540
139
|
```
|
|
541
140
|
|
|
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);
|
|
141
|
+
```bash
|
|
142
|
+
npm i data-structure-typed --save
|
|
549
143
|
```
|
|
550
144
|
|
|
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);
|
|
145
|
+
```bash
|
|
146
|
+
yarn add data-structure-typed
|
|
556
147
|
```
|
|
557
148
|
|
|
558
|
-
###
|
|
149
|
+
### Individual Packages
|
|
559
150
|
|
|
560
|
-
|
|
151
|
+
Use only what you need:
|
|
561
152
|
|
|
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 ✅
|
|
153
|
+
```bash
|
|
154
|
+
pnpm add heap-typed deque-typed red-black-tree-typed
|
|
574
155
|
```
|
|
575
156
|
|
|
576
157
|
---
|
|
577
158
|
|
|
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
|
|
159
|
+
## 💡 When Should I Consider This Library?
|
|
599
160
|
|
|
600
|
-
|
|
161
|
+
✅ **When you need:**
|
|
601
162
|
|
|
602
|
-
|
|
163
|
+
- Top-K / Leaderboard queries without repeated sorting
|
|
164
|
+
- Insertion order + lookup performance simultaneously
|
|
165
|
+
- Priority queues with fast position-based access
|
|
166
|
+
- Time-series data with range queries
|
|
167
|
+
- Red-Black Tree / Heap performance without learning new APIs
|
|
603
168
|
|
|
604
|
-
|
|
169
|
+
✅ **When your current code has:**
|
|
605
170
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
[//]: # (No deletion!!! End of Replace Section)
|
|
171
|
+
- `array.sort()` in hot paths (request handlers, loops)
|
|
172
|
+
- Manual index tracking after insertions
|
|
173
|
+
- `Array.shift()` on large lists (queues)
|
|
174
|
+
- Custom sorting logic you repeat across files
|
|
175
|
+
- Map that needs to be ordered
|
|
613
176
|
|
|
614
177
|
---
|
|
615
178
|
|
|
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
|
-
---
|
|
179
|
+
## 🚀 Quick Start: 30 Seconds
|
|
637
180
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
### Pattern 1: Interoperability & Iterator Conversion
|
|
181
|
+
### Leaderboard (Ranked Collections)
|
|
641
182
|
|
|
642
183
|
```typescript
|
|
643
184
|
import { RedBlackTree } from 'data-structure-typed';
|
|
644
185
|
|
|
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';
|
|
186
|
+
const leaderboard = new RedBlackTree([
|
|
187
|
+
[100, 'Alice'],
|
|
188
|
+
[85, 'Bob'],
|
|
189
|
+
[92, 'Charlie']
|
|
190
|
+
]);
|
|
686
191
|
|
|
687
|
-
|
|
688
|
-
for (
|
|
689
|
-
|
|
192
|
+
// Get sorted scores (automatically maintained!)
|
|
193
|
+
for (const [score, player] of leaderboard) {
|
|
194
|
+
console.log(`${player}: ${score}`);
|
|
690
195
|
}
|
|
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]
|
|
196
|
+
// Output:
|
|
197
|
+
// Alice: 100
|
|
198
|
+
// Charlie: 92
|
|
199
|
+
// Bob: 85
|
|
703
200
|
|
|
704
|
-
//
|
|
705
|
-
|
|
201
|
+
// Update score
|
|
202
|
+
leaderboard.delete(85);
|
|
203
|
+
leaderboard.set(95, 'Bob'); // O(log n)
|
|
706
204
|
|
|
707
|
-
//
|
|
708
|
-
const
|
|
709
|
-
|
|
710
|
-
// Back to Array for final output
|
|
711
|
-
const result = [...deque];
|
|
205
|
+
// Query top players
|
|
206
|
+
const topPlayers = [...leaderboard.values()].reverse().slice(0, 3);
|
|
712
207
|
```
|
|
713
208
|
|
|
714
|
-
###
|
|
715
|
-
|
|
716
|
-
#### Tree Example
|
|
209
|
+
### Task Queue (Scheduling)
|
|
717
210
|
|
|
718
211
|
```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);
|
|
212
|
+
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
728
213
|
|
|
729
|
-
|
|
730
|
-
|
|
214
|
+
const taskQueue = new MaxPriorityQueue([], {
|
|
215
|
+
comparator: (a, b) => b.priority - a.priority
|
|
216
|
+
});
|
|
731
217
|
|
|
732
|
-
|
|
218
|
+
taskQueue.add({ priority: 5, task: 'Email' });
|
|
219
|
+
taskQueue.add({ priority: 9, task: 'Alert' }); // Instant priority handling
|
|
733
220
|
|
|
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]);
|
|
221
|
+
const nextTask = taskQueue.poll(); // { priority: 9, task: 'Alert' }
|
|
743
222
|
```
|
|
744
223
|
|
|
745
|
-
|
|
224
|
+
### Fast Queue (FIFO)
|
|
746
225
|
|
|
747
226
|
```typescript
|
|
748
|
-
|
|
227
|
+
import { Deque } from 'data-structure-typed';
|
|
749
228
|
|
|
750
|
-
const
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
.reduce((sum, value) => sum + value, 0);
|
|
229
|
+
const queue = new Deque([1, 2, 3, 4, 5]);
|
|
230
|
+
queue.shift(); // Remove from front: O(1) not O(n)
|
|
231
|
+
queue.push(6); // Add to back: O(1)
|
|
754
232
|
```
|
|
755
233
|
|
|
756
234
|
---
|
|
757
235
|
|
|
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');
|
|
236
|
+
## 📊 Data Structures Available
|
|
909
237
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
238
|
+
| Structure | Use Case | Time Complexity | NPM |
|
|
239
|
+
|--------------------------|-----------------------------------|-----------------|-----------------------------------------------------------|
|
|
240
|
+
| **RedBlackTree** | Sorted collections, range queries | O(log n) | [npm](https://www.npmjs.com/package/red-black-tree-typed) |
|
|
241
|
+
| **Heap / PriorityQueue** | Task scheduling, top-K elements | O(log n) | [npm](https://www.npmjs.com/package/heap-typed) |
|
|
242
|
+
| **Deque** | Fast front/back operations | O(1) | [npm](https://www.npmjs.com/package/deque-typed) |
|
|
243
|
+
| **Trie** | Autocomplete, prefix search | O(m+k) | [npm](https://www.npmjs.com/package/trie-typed) |
|
|
244
|
+
| **DirectedGraph** | Pathfinding, DAG algorithms | O(V+E) | [npm](https://www.npmjs.com/package/directed-graph-typed) |
|
|
245
|
+
| **Stack** | Undo/redo, expression parsing | O(1) | [npm](https://www.npmjs.com/package/stack-typed) |
|
|
246
|
+
| **LinkedList** | Dynamic sizing, no index shift | O(1)* | [npm](https://www.npmjs.com/package/linked-list-typed) |
|
|
247
|
+
| **AVLTree** | Stricter balance than RB-Tree | O(log n) | [npm](https://www.npmjs.com/package/avl-tree-typed) |
|
|
914
248
|
|
|
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
|
-
```
|
|
249
|
+
👉 [See all 20+ structures →](./docs/REFERENCE.md)
|
|
923
250
|
|
|
924
251
|
---
|
|
925
252
|
|
|
926
|
-
##
|
|
927
|
-
|
|
928
|
-
###
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
253
|
+
## 📖 Documentation
|
|
254
|
+
|
|
255
|
+
### For Different Use Cases
|
|
256
|
+
|
|
257
|
+
| Your Goal | Start Here | Next Steps |
|
|
258
|
+
|---------------------------|-------------------------------------------|-----------------------------------------|
|
|
259
|
+
| **Learn concepts** | [CONCEPTS.md](./docs/CONCEPTS.md) | [GUIDES.md](./docs/GUIDES.md) |
|
|
260
|
+
| **Use in my project** | [GUIDES.md](./docs/GUIDES.md) | [REFERENCE.md](./docs/REFERENCE.md) |
|
|
261
|
+
| **Look up API** | [REFERENCE.md](./docs/REFERENCE.md) | [PERFORMANCE.md](./docs/PERFORMANCE.md) |
|
|
262
|
+
| **Performance questions** | [PERFORMANCE.md](./docs/PERFORMANCE.md) | [ARCHITECTURE.md](./docs/ARCHITECTURE.md) |
|
|
263
|
+
| **Framework integration** | [INTEGRATIONS.md](./docs/INTEGRATIONS.md) | [GUIDES.md](./docs/GUIDES.md) |
|
|
264
|
+
| **Understand design** | [ARCHITECTURE.md](./docs/ARCHITECTURE.md) | [CONCEPTS.md](./docs/CONCEPTS.md) |
|
|
265
|
+
|
|
266
|
+
### Documentation Files
|
|
267
|
+
|
|
268
|
+
1. **[CONCEPTS.md](./docs/CONCEPTS.md)** - Core Fundamentals & Theory
|
|
269
|
+
- Big Three Concepts (BST, Balanced Trees, Heap)
|
|
270
|
+
- 13 Plain Language Explanations
|
|
271
|
+
- Iterator Protocol Design
|
|
272
|
+
- 5 Comparisons with Native JavaScript
|
|
273
|
+
- Complete Decision Guide
|
|
274
|
+
|
|
275
|
+
2. **[REFERENCE.md](./docs/REFERENCE.md)** - Complete API & Data Structures
|
|
276
|
+
- Quick Reference Table
|
|
277
|
+
- All 20+ Structures with Examples
|
|
278
|
+
- CRUD Operations
|
|
279
|
+
- Common Methods
|
|
280
|
+
- TypeScript Support
|
|
281
|
+
|
|
282
|
+
3. **[ARCHITECTURE.md](./docs/ARCHITECTURE.md)** - Design & Implementation
|
|
283
|
+
- Design Philosophy & Principles
|
|
284
|
+
- 3 Pain Points Solved
|
|
285
|
+
- Why Deque is 484x Faster
|
|
286
|
+
- Iterator Protocol Design
|
|
287
|
+
- Self-Balancing Strategy
|
|
288
|
+
- V8 JIT Optimizations
|
|
289
|
+
|
|
290
|
+
4. **[PERFORMANCE.md](./docs/PERFORMANCE.md)** - Benchmarks & Comparisons
|
|
291
|
+
- Performance Summary
|
|
292
|
+
- 3 Real-World Scenarios
|
|
293
|
+
- Detailed Benchmarks
|
|
294
|
+
- When to Use What
|
|
295
|
+
- Optimization Tips
|
|
296
|
+
|
|
297
|
+
5. **[GUIDES.md](./docs/GUIDES.md)** - Real-World Examples
|
|
298
|
+
- 4 Design Patterns
|
|
299
|
+
- 5 Production Code Examples
|
|
300
|
+
- Common Mistakes
|
|
301
|
+
- Best Practices
|
|
302
|
+
|
|
303
|
+
6. **[INTEGRATIONS.md](./docs/INTEGRATIONS.md)** - Framework Integration
|
|
304
|
+
- React Integration (State Management, Leaderboard)
|
|
305
|
+
- Express Integration (LRU Cache, Rate Limiting)
|
|
306
|
+
- Nest.js Integration (Ranking Service, Task Queue)
|
|
307
|
+
- TypeScript Configuration
|
|
958
308
|
|
|
959
|
-
|
|
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
|
-
}
|
|
309
|
+
---
|
|
982
310
|
|
|
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
|
-
```
|
|
311
|
+
## 💻 Real-World Examples
|
|
991
312
|
|
|
992
|
-
###
|
|
313
|
+
### LRU Cache
|
|
993
314
|
|
|
994
315
|
```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
|
-
}
|
|
316
|
+
class LRUCache<K, V> {
|
|
317
|
+
private cache = new Map<K, V>();
|
|
318
|
+
private order = new DoublyLinkedList<K>();
|
|
319
|
+
|
|
320
|
+
get(key: K): V | null {
|
|
321
|
+
if (!this.cache.has(key)) return null;
|
|
322
|
+
// Move to end (recently used)
|
|
323
|
+
// Efficient with O(1) operations
|
|
324
|
+
return this.cache.get(key)!;
|
|
1025
325
|
}
|
|
1026
326
|
}
|
|
1027
|
-
|
|
1028
|
-
// Why DoublyLinkedList?
|
|
1029
|
-
// - O(1) delete from any position
|
|
1030
|
-
// - O(1) push to end
|
|
1031
|
-
// - Perfect for LRU implementation
|
|
1032
327
|
```
|
|
1033
328
|
|
|
1034
|
-
###
|
|
329
|
+
### Leaderboard
|
|
1035
330
|
|
|
1036
331
|
```typescript
|
|
1037
|
-
import { RedBlackTree } from 'data-structure-typed';
|
|
1038
|
-
|
|
1039
|
-
interface Player {
|
|
1040
|
-
id: string;
|
|
1041
|
-
name: string;
|
|
1042
|
-
score: number;
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
332
|
class Leaderboard {
|
|
1046
|
-
private
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
updateScore(playerId: string, newScore: number): void {
|
|
1050
|
-
if (this.playerMap.has(playerId)) {
|
|
1051
|
-
const oldScore = this.playerMap.get(playerId)!;
|
|
1052
|
-
this.scoreTree.delete(oldScore);
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
const player: Player = { id: playerId, name: playerId, score: newScore };
|
|
1056
|
-
this.scoreTree.add(newScore, player);
|
|
1057
|
-
this.playerMap.set(playerId, newScore);
|
|
1058
|
-
}
|
|
333
|
+
private scores = new RedBlackTree<number, Player>(
|
|
334
|
+
(a, b) => b - a // Descending
|
|
335
|
+
);
|
|
1059
336
|
|
|
1060
337
|
getTopN(n: number): Player[] {
|
|
1061
|
-
return [...this.
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
getRank(playerId: string): number | null {
|
|
1065
|
-
const score = this.playerMap.get(playerId);
|
|
1066
|
-
if (score === undefined) return null;
|
|
1067
|
-
|
|
1068
|
-
const higherScores = [...this.scoreTree.keys()].filter(s => s > score).length;
|
|
1069
|
-
return higherScores + 1;
|
|
338
|
+
return [...this.scores.values()].slice(0, n);
|
|
1070
339
|
}
|
|
1071
340
|
}
|
|
1072
|
-
|
|
1073
|
-
// Why RedBlackTree?
|
|
1074
|
-
// - Automatically maintains sorted order
|
|
1075
|
-
// - O(log n) insertions and deletions
|
|
1076
|
-
// - O(log n) searches
|
|
1077
|
-
// - Perfect for real-time rankings
|
|
1078
341
|
```
|
|
1079
342
|
|
|
1080
|
-
###
|
|
343
|
+
### Message Queue
|
|
1081
344
|
|
|
1082
345
|
```typescript
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
id: string;
|
|
1087
|
-
priority: number;
|
|
1088
|
-
action: () => Promise<void>;
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
class TaskScheduler {
|
|
1092
|
-
private maxPQ = new MaxPriorityQueue<Task>([], {
|
|
1093
|
-
comparator: (a, b) => b.priority - a.priority,
|
|
1094
|
-
});
|
|
1095
|
-
|
|
1096
|
-
addTask(task: Task): void {
|
|
1097
|
-
this.maxPQ.add(task);
|
|
1098
|
-
}
|
|
346
|
+
class MessageQueue {
|
|
347
|
+
private urgent = new Deque<Message>();
|
|
348
|
+
private normal = new Deque<Message>();
|
|
1099
349
|
|
|
1100
|
-
|
|
1101
|
-
|
|
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
|
-
}
|
|
350
|
+
dequeue(): Message | null {
|
|
351
|
+
return this.urgent.shift() || this.normal.shift();
|
|
1112
352
|
}
|
|
1113
353
|
}
|
|
1114
354
|
```
|
|
1115
355
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
```typescript
|
|
1119
|
-
import { Trie } from 'data-structure-typed';
|
|
1120
|
-
|
|
1121
|
-
class SearchIndex {
|
|
1122
|
-
private trie = new Trie();
|
|
1123
|
-
|
|
1124
|
-
indexDocument(docId: number, content: string): void {
|
|
1125
|
-
const words = content.toLowerCase().split(/\s+/);
|
|
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
|
-
}
|
|
1139
|
-
|
|
1140
|
-
autocomplete(prefix: string): string[] {
|
|
1141
|
-
return this.trie.getWordsWithPrefix(prefix.toLowerCase());
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
search(word: string): number[] {
|
|
1145
|
-
return this.trie.get(word.toLowerCase()) ?? [];
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
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
|
-
```
|
|
356
|
+
👉 [More examples in GUIDES.md](./docs/GUIDES.md)
|
|
1154
357
|
|
|
1155
358
|
---
|
|
1156
359
|
|
|
1157
|
-
##
|
|
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:
|
|
1184
|
-
|
|
1185
|
-
```javascript
|
|
1186
|
-
const userMap = new Map([
|
|
1187
|
-
[5, { id: 5, name: 'Alice' }],
|
|
1188
|
-
[2, { id: 2, name: 'Bob' }],
|
|
1189
|
-
]);
|
|
1190
|
-
|
|
1191
|
-
for (const [id, user] of userMap) {
|
|
1192
|
-
console.log(id); // 5, 2 (insertion order)
|
|
1193
|
-
}
|
|
1194
|
-
```
|
|
360
|
+
## 🎯 Use Cases by Industry
|
|
1195
361
|
|
|
1196
|
-
|
|
362
|
+
### 📊 Finance
|
|
1197
363
|
|
|
1198
|
-
|
|
1199
|
-
|
|
364
|
+
- Price-sorted order book
|
|
365
|
+
- Real-time portfolio rankings
|
|
366
|
+
- Option chain ordering
|
|
1200
367
|
|
|
1201
|
-
|
|
1202
|
-
[5, { id: 5, name: 'Alice' }],
|
|
1203
|
-
[2, { id: 2, name: 'Bob' }],
|
|
1204
|
-
]);
|
|
368
|
+
### 🎮 Gaming
|
|
1205
369
|
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
```
|
|
370
|
+
- Player leaderboards
|
|
371
|
+
- Enemy priority queues
|
|
372
|
+
- Game event scheduling
|
|
1210
373
|
|
|
1211
|
-
###
|
|
374
|
+
### 📱 Social Media
|
|
1212
375
|
|
|
1213
|
-
|
|
376
|
+
- Trending posts (top-K)
|
|
377
|
+
- Feed ordering
|
|
378
|
+
- Notification scheduling
|
|
1214
379
|
|
|
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
|
-
```
|
|
380
|
+
### 🏥 Healthcare
|
|
1222
381
|
|
|
1223
|
-
|
|
382
|
+
- Patient priority queues
|
|
383
|
+
- Appointment scheduling
|
|
384
|
+
- Medical record organization
|
|
1224
385
|
|
|
1225
|
-
|
|
1226
|
-
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
386
|
+
### 🛒 E-commerce
|
|
1227
387
|
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
}
|
|
1232
|
-
```
|
|
388
|
+
- Product price ranges
|
|
389
|
+
- Inventory management
|
|
390
|
+
- Order scheduling
|
|
1233
391
|
|
|
1234
392
|
---
|
|
1235
393
|
|
|
1236
|
-
##
|
|
394
|
+
## ✨ Why Developers Love This
|
|
1237
395
|
|
|
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
|
-
```
|
|
396
|
+
| Pain Point | Solution |
|
|
397
|
+
|------------------------------------|-------------------------------------------|
|
|
398
|
+
| Repeated sorting slowing down code | TreeSet auto-maintains order |
|
|
399
|
+
| Array.shift timeout in loops | Deque O(1) shift instead of O(n) |
|
|
400
|
+
| Learning different APIs | All structures use push/pop/shift/unshift |
|
|
401
|
+
| Type safety nightmares | Full TypeScript generics support |
|
|
402
|
+
| Browser compatibility issues | Works everywhere: Node, browsers, CDN |
|
|
1264
403
|
|
|
1265
404
|
---
|
|
1266
405
|
|
|
1267
|
-
##
|
|
406
|
+
## 📦 What You Get
|
|
1268
407
|
|
|
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>
|
|
408
|
+
✅ **20+ data structures** (production-ready)
|
|
409
|
+
✅ **50+ code examples** (real-world patterns)
|
|
410
|
+
✅ **Full TypeScript support** (strict typing)
|
|
411
|
+
✅ **Performance benchmarks** (484x speedups)
|
|
412
|
+
✅ **Framework integrations** (React, Express, Nest.js)
|
|
413
|
+
✅ **6 core documentation files** (2500+ lines)
|
|
1459
414
|
|
|
1460
415
|
---
|
|
1461
416
|
|
|
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
|
|
417
|
+
## 🚀 Getting Started
|
|
1467
418
|
|
|
1468
|
-
|
|
419
|
+
### Step 1: Install
|
|
1469
420
|
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-

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

|
|
1477
|
-
|
|
1478
|
-
### Map Graph
|
|
1479
|
-
|
|
1480
|
-

|
|
1481
|
-
|
|
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
|
-
}
|
|
421
|
+
```bash
|
|
422
|
+
npm i data-structure-typed
|
|
1531
423
|
```
|
|
1532
424
|
|
|
1533
|
-
###
|
|
425
|
+
### Step 2: Import
|
|
1534
426
|
|
|
1535
427
|
```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
|
-
});
|
|
428
|
+
import { RedBlackTree, Deque, MaxPriorityQueue } from 'data-structure-typed';
|
|
1579
429
|
```
|
|
1580
430
|
|
|
1581
|
-
###
|
|
431
|
+
### Step 3: Use
|
|
1582
432
|
|
|
1583
433
|
```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
|
-
}
|
|
434
|
+
const tree = new RedBlackTree([5, 2, 8]);
|
|
435
|
+
console.log([...tree]); // [2, 5, 8] - Automatically sorted!
|
|
1618
436
|
```
|
|
1619
437
|
|
|
1620
|
-
|
|
438
|
+
### Step 4: Learn More
|
|
1621
439
|
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
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
|
-
```
|
|
440
|
+
👉 Check [CONCEPTS.md](./docs/CONCEPTS.md) for core concepts
|
|
441
|
+
👉 See [GUIDES.md](./docs/GUIDES.md) for production examples
|
|
442
|
+
👉 Read [REFERENCE.md](./docs/REFERENCE.md) for complete API
|
|
1747
443
|
|
|
1748
444
|
---
|
|
1749
445
|
|
|
1750
|
-
##
|
|
1751
|
-
|
|
1752
|
-
Now you can use it in Node.js and browser environments
|
|
1753
|
-
|
|
1754
|
-
### Module Formats
|
|
1755
|
-
|
|
1756
|
-
- **CommonJS**: `require export.modules =`
|
|
1757
|
-
- **ESModule**: `import export`
|
|
1758
|
-
- **TypeScript**: `import export`
|
|
1759
|
-
- **UMD**: `var Deque = dataStructureTyped.Deque`
|
|
1760
|
-
|
|
1761
|
-
### CDN
|
|
1762
|
-
|
|
1763
|
-
#### Development
|
|
1764
|
-
|
|
1765
|
-
##### ES Module
|
|
446
|
+
## 📊 Comparison Chart
|
|
1766
447
|
|
|
1767
|
-
```html
|
|
1768
|
-
<script type="module">
|
|
1769
|
-
import { BST } from "https://cdn.jsdelivr.net/npm/data-structure-typed/dist/esm/index.mjs";
|
|
1770
|
-
|
|
1771
|
-
const bst = new BST([2, 1, 6, 7, 5, 3, 4, 8, 9]);
|
|
1772
|
-
bst.print();
|
|
1773
|
-
</script>
|
|
1774
448
|
```
|
|
449
|
+
Need frequent head/tail operations?
|
|
450
|
+
→ Deque (O(1) shift/unshift/push/pop)
|
|
1775
451
|
|
|
1776
|
-
|
|
452
|
+
Need sorted + fast lookup?
|
|
453
|
+
→ RedBlackTree (O(log n) guaranteed)
|
|
1777
454
|
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
```
|
|
455
|
+
Need highest/lowest priority?
|
|
456
|
+
→ Heap/PriorityQueue (O(log n) add/remove)
|
|
1781
457
|
|
|
1782
|
-
|
|
458
|
+
Need prefix/text matching?
|
|
459
|
+
→ Trie (O(m+k) where m=prefix)
|
|
1783
460
|
|
|
1784
|
-
|
|
1785
|
-
|
|
461
|
+
Need graph operations?
|
|
462
|
+
→ DirectedGraph/UndirectedGraph
|
|
1786
463
|
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
const { BinaryTree, Graph, Queue, Stack } = dataStructureTyped;
|
|
1790
|
-
|
|
1791
|
-
const heap = new Heap([1, 2, 3]);
|
|
1792
|
-
heap.print();
|
|
1793
|
-
</script>
|
|
464
|
+
Otherwise?
|
|
465
|
+
→ Use Array (simplest case)
|
|
1794
466
|
```
|
|
1795
467
|
|
|
1796
468
|
---
|
|
1797
469
|
|
|
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>
|
|
470
|
+
## 🤝 Contributing
|
|
1846
471
|
|
|
1847
|
-
|
|
472
|
+
Found a bug? Have suggestions? [Open an issue](https://github.com/zrwusa/data-structure-typed/issues)
|
|
1848
473
|
|
|
1849
|
-
|
|
474
|
+
---
|
|
1850
475
|
|
|
1851
|
-
|
|
476
|
+
## 📄 License
|
|
1852
477
|
|
|
1853
|
-
|
|
1854
|
-
// Generic type parameters
|
|
1855
|
-
const bst = new BST<number, { name: string }>();
|
|
1856
|
-
bst.add(10, { name: 'Alice' });
|
|
478
|
+
MIT
|
|
1857
479
|
|
|
1858
|
-
|
|
1859
|
-
const value: { name: string } | undefined = bst.get(10);
|
|
480
|
+
---
|
|
1860
481
|
|
|
1861
|
-
|
|
1862
|
-
const descBST = new BST<number>([], (a, b) => b - a);
|
|
482
|
+
## 📚 Full Documentation Structure
|
|
1863
483
|
|
|
1864
|
-
|
|
1865
|
-
|
|
484
|
+
```
|
|
485
|
+
docs/
|
|
486
|
+
├── README.md (this file)
|
|
487
|
+
├── CONCEPTS.md (theory & fundamentals)
|
|
488
|
+
├── REFERENCE.md (API documentation)
|
|
489
|
+
├── ARCHITECTURE.md (design principles)
|
|
490
|
+
├── PERFORMANCE.md (benchmarks)
|
|
491
|
+
├── GUIDES.md (real-world examples)
|
|
492
|
+
└── INTEGRATIONS.md (framework guides)
|
|
1866
493
|
```
|
|
1867
494
|
|
|
1868
495
|
---
|
|
1869
496
|
|
|
1870
|
-
##
|
|
497
|
+
## 🎓 Learn More
|
|
1871
498
|
|
|
1872
|
-
|
|
499
|
+
**Just started?** → [Quick Start](#-quick-start-30-seconds)
|
|
1873
500
|
|
|
1874
|
-
|
|
1875
|
-
- **Discussions**: [GitHub Discussions](https://github.com/zrwusa/data-structure-typed/discussions)
|
|
501
|
+
**Need concepts?** → [CONCEPTS.md](./docs/CONCEPTS.md)
|
|
1876
502
|
|
|
1877
|
-
|
|
503
|
+
**Want to build?** → [GUIDES.md](./docs/GUIDES.md)
|
|
1878
504
|
|
|
1879
|
-
|
|
505
|
+
**Need API?** → [REFERENCE.md](./docs/REFERENCE.md)
|
|
1880
506
|
|
|
1881
|
-
[
|
|
507
|
+
**Curious about performance?** → [PERFORMANCE.md](./docs/PERFORMANCE.md)
|
|
1882
508
|
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
## 🙏 Thank You
|
|
509
|
+
**Framework questions?** → [INTEGRATIONS.md](./docs/INTEGRATIONS.md)
|
|
1886
510
|
|
|
1887
|
-
|
|
511
|
+
---
|
|
1888
512
|
|
|
1889
|
-
|
|
513
|
+
**Ready to supercharge your TypeScript data structures? [Get started now →](#-quick-start-30-seconds)**
|