data-structure-typed 2.5.0 → 2.5.2
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/.vitepress/cache/deps_temp_51f5f1b0/chunk-7OIKW5WK.js +12984 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/package.json +3 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vue_devtools-api.js +4505 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vueuse_core.js +9731 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vue.js +347 -0
- package/CHANGELOG.md +5 -1
- package/README.md +124 -29
- package/dist/cjs/binary-tree.cjs +26282 -0
- package/dist/cjs/graph.cjs +5422 -0
- package/dist/cjs/hash.cjs +1310 -0
- package/dist/cjs/heap.cjs +1602 -0
- package/dist/cjs/index.cjs +31257 -14673
- package/dist/cjs/linked-list.cjs +4576 -0
- package/dist/cjs/matrix.cjs +1080 -0
- package/dist/cjs/priority-queue.cjs +1376 -0
- package/dist/cjs/queue.cjs +4264 -0
- package/dist/cjs/stack.cjs +907 -0
- package/dist/cjs/trie.cjs +1223 -0
- package/dist/cjs-legacy/binary-tree.cjs +26319 -0
- package/dist/cjs-legacy/graph.cjs +5420 -0
- package/dist/cjs-legacy/hash.cjs +1310 -0
- package/dist/cjs-legacy/heap.cjs +1599 -0
- package/dist/cjs-legacy/index.cjs +31268 -14679
- package/dist/cjs-legacy/linked-list.cjs +4582 -0
- package/dist/cjs-legacy/matrix.cjs +1083 -0
- package/dist/cjs-legacy/priority-queue.cjs +1374 -0
- package/dist/cjs-legacy/queue.cjs +4262 -0
- package/dist/cjs-legacy/stack.cjs +907 -0
- package/dist/cjs-legacy/trie.cjs +1222 -0
- package/dist/esm/binary-tree.mjs +26267 -0
- package/dist/esm/graph.mjs +5409 -0
- package/dist/esm/hash.mjs +1307 -0
- package/dist/esm/heap.mjs +1596 -0
- package/dist/esm/index.mjs +31254 -14674
- package/dist/esm/linked-list.mjs +4569 -0
- package/dist/esm/matrix.mjs +1076 -0
- package/dist/esm/priority-queue.mjs +1372 -0
- package/dist/esm/queue.mjs +4260 -0
- package/dist/esm/stack.mjs +905 -0
- package/dist/esm/trie.mjs +1220 -0
- package/dist/esm-legacy/binary-tree.mjs +26304 -0
- package/dist/esm-legacy/graph.mjs +5407 -0
- package/dist/esm-legacy/hash.mjs +1307 -0
- package/dist/esm-legacy/heap.mjs +1593 -0
- package/dist/esm-legacy/index.mjs +31265 -14680
- package/dist/esm-legacy/linked-list.mjs +4575 -0
- package/dist/esm-legacy/matrix.mjs +1079 -0
- package/dist/esm-legacy/priority-queue.mjs +1370 -0
- package/dist/esm-legacy/queue.mjs +4258 -0
- package/dist/esm-legacy/stack.mjs +905 -0
- package/dist/esm-legacy/trie.mjs +1219 -0
- package/dist/types/common/error.d.ts +9 -0
- package/dist/types/common/index.d.ts +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
- package/dist/types/data-structures/base/linear-base.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +288 -0
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +336 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +618 -18
- package/dist/types/data-structures/binary-tree/bst.d.ts +676 -1
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +456 -0
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +144 -1
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +3307 -399
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3285 -360
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2674 -325
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +3072 -287
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +240 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +216 -0
- package/dist/types/data-structures/hash/hash-map.d.ts +274 -10
- package/dist/types/data-structures/heap/heap.d.ts +336 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +411 -3
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +363 -3
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +434 -2
- package/dist/types/data-structures/matrix/matrix.d.ts +192 -0
- package/dist/types/data-structures/queue/deque.d.ts +364 -4
- package/dist/types/data-structures/queue/queue.d.ts +288 -0
- package/dist/types/data-structures/stack/stack.d.ts +240 -0
- package/dist/types/data-structures/trie/trie.d.ts +292 -4
- package/dist/types/interfaces/graph.d.ts +1 -1
- package/dist/types/types/common.d.ts +2 -2
- package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
- package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
- package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
- package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
- package/dist/types/types/utils/validate-type.d.ts +4 -4
- package/dist/umd/data-structure-typed.js +31196 -14608
- package/dist/umd/data-structure-typed.min.js +11 -5
- package/docs-site-docusaurus/README.md +41 -0
- package/docs-site-docusaurus/docs/api/README.md +52 -0
- package/docs-site-docusaurus/docs/api/classes/AVLTree.md +6644 -0
- package/docs-site-docusaurus/docs/api/classes/AVLTreeNode.md +282 -0
- package/docs-site-docusaurus/docs/api/classes/AbstractGraph.md +2266 -0
- package/docs-site-docusaurus/docs/api/classes/BST.md +6293 -0
- package/docs-site-docusaurus/docs/api/classes/BSTNode.md +333 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +455 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +4647 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryTreeNode.md +331 -0
- package/docs-site-docusaurus/docs/api/classes/Deque.md +2767 -0
- package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +2999 -0
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +2685 -0
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedListNode.md +221 -0
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +253 -0
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +21 -0
- package/docs-site-docusaurus/docs/api/classes/HashMap.md +1333 -0
- package/docs-site-docusaurus/docs/api/classes/Heap.md +1881 -0
- package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +800 -0
- package/docs-site-docusaurus/docs/api/classes/IterableEntryBase.md +644 -0
- package/docs-site-docusaurus/docs/api/classes/LinearBase.md +1632 -0
- package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +1853 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +1108 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedListNode.md +156 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +2824 -0
- package/docs-site-docusaurus/docs/api/classes/MapGraph.md +2929 -0
- package/docs-site-docusaurus/docs/api/classes/Matrix.md +1026 -0
- package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +1866 -0
- package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +1883 -0
- package/docs-site-docusaurus/docs/api/classes/MinHeap.md +1879 -0
- package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +1882 -0
- package/docs-site-docusaurus/docs/api/classes/Navigator.md +109 -0
- package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +1839 -0
- package/docs-site-docusaurus/docs/api/classes/Queue.md +2244 -0
- package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +6888 -0
- package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +372 -0
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +2897 -0
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedListNode.md +169 -0
- package/docs-site-docusaurus/docs/api/classes/SkipList.md +1229 -0
- package/docs-site-docusaurus/docs/api/classes/Stack.md +1573 -0
- package/docs-site-docusaurus/docs/api/classes/TreeMap.md +1389 -0
- package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +1591 -0
- package/docs-site-docusaurus/docs/api/classes/TreeSet.md +1246 -0
- package/docs-site-docusaurus/docs/api/classes/Trie.md +1708 -0
- package/docs-site-docusaurus/docs/api/classes/TrieNode.md +199 -0
- package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +2979 -0
- package/docs-site-docusaurus/docs/guide/_category_.json +6 -0
- package/docs-site-docusaurus/docs/guide/architecture.md +615 -0
- package/docs-site-docusaurus/docs/guide/concepts.md +451 -0
- package/docs-site-docusaurus/docs/guide/faq.md +180 -0
- package/docs-site-docusaurus/docs/guide/guides.md +597 -0
- package/docs-site-docusaurus/docs/guide/installation.md +62 -0
- package/docs-site-docusaurus/docs/guide/integrations.md +825 -0
- package/docs-site-docusaurus/docs/guide/overview.md +645 -0
- package/docs-site-docusaurus/docs/guide/performance.md +835 -0
- package/docs-site-docusaurus/docs/guide/quick-start.md +104 -0
- package/docs-site-docusaurus/docs/guide/use-cases/_category_.json +6 -0
- package/docs-site-docusaurus/docs/guide/use-cases/array-sort-alternative.md +158 -0
- package/docs-site-docusaurus/docs/guide/use-cases/heap-vs-sorting.md +92 -0
- package/docs-site-docusaurus/docs/guide/use-cases/map-vs-treemap.md +151 -0
- package/docs-site-docusaurus/docs/guide/use-cases/priority-queue-typescript.md +113 -0
- package/docs-site-docusaurus/docs/guide/use-cases/treemap-javascript.md +151 -0
- package/docs-site-docusaurus/docusaurus.config.ts +159 -0
- package/docs-site-docusaurus/fix-mdx-generics.mjs +75 -0
- package/docs-site-docusaurus/package-lock.json +18667 -0
- package/docs-site-docusaurus/package.json +50 -0
- package/docs-site-docusaurus/prefix-class-to-methods.mjs +48 -0
- package/docs-site-docusaurus/sidebars.ts +23 -0
- package/docs-site-docusaurus/sort-protected.mjs +87 -0
- package/docs-site-docusaurus/src/css/custom.css +96 -0
- package/docs-site-docusaurus/src/pages/index.module.css +13 -0
- package/docs-site-docusaurus/src/pages/index.tsx +120 -0
- package/docs-site-docusaurus/src/pages/markdown-page.md +7 -0
- package/docs-site-docusaurus/src/theme/TOCItems/index.tsx +34 -0
- package/docs-site-docusaurus/static/.nojekyll +0 -0
- package/docs-site-docusaurus/static/img/docusaurus-social-card.jpg +0 -0
- package/docs-site-docusaurus/static/img/docusaurus.png +0 -0
- package/docs-site-docusaurus/static/img/favicon.ico +0 -0
- package/docs-site-docusaurus/static/img/favicon.png +0 -0
- package/docs-site-docusaurus/static/img/logo-180.png +0 -0
- package/docs-site-docusaurus/static/img/logo.jpg +0 -0
- package/docs-site-docusaurus/static/img/logo.png +0 -0
- package/docs-site-docusaurus/static/img/logo.svg +1 -0
- package/docs-site-docusaurus/static/img/og-image.png +0 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
- package/docs-site-docusaurus/static/llms.txt +37 -0
- package/docs-site-docusaurus/static/robots.txt +4 -0
- package/docs-site-docusaurus/typedoc.json +23 -0
- package/llms.txt +37 -0
- package/package.json +159 -55
- package/src/common/error.ts +19 -1
- package/src/common/index.ts +1 -1
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-element-base.ts +3 -2
- package/src/data-structures/base/iterable-entry-base.ts +8 -8
- package/src/data-structures/base/linear-base.ts +3 -3
- package/src/data-structures/binary-tree/avl-tree.ts +287 -0
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +327 -5
- package/src/data-structures/binary-tree/binary-tree.ts +581 -6
- package/src/data-structures/binary-tree/bst.ts +922 -7
- package/src/data-structures/binary-tree/red-black-tree.ts +453 -0
- package/src/data-structures/binary-tree/segment-tree.ts +139 -2
- package/src/data-structures/binary-tree/tree-map.ts +3300 -495
- package/src/data-structures/binary-tree/tree-multi-map.ts +3384 -563
- package/src/data-structures/binary-tree/tree-multi-set.ts +2757 -493
- package/src/data-structures/binary-tree/tree-set.ts +3122 -440
- package/src/data-structures/graph/abstract-graph.ts +6 -6
- package/src/data-structures/graph/directed-graph.ts +230 -0
- package/src/data-structures/graph/undirected-graph.ts +207 -0
- package/src/data-structures/hash/hash-map.ts +270 -19
- package/src/data-structures/heap/heap.ts +326 -4
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +394 -3
- package/src/data-structures/linked-list/singly-linked-list.ts +348 -3
- package/src/data-structures/linked-list/skip-linked-list.ts +421 -7
- package/src/data-structures/matrix/matrix.ts +194 -10
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +350 -5
- package/src/data-structures/queue/queue.ts +276 -0
- package/src/data-structures/stack/stack.ts +230 -0
- package/src/data-structures/trie/trie.ts +283 -7
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/binary-tree/bst.ts +1 -0
- package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
- package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
- package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
- package/vercel.json +6 -0
- package/dist/leetcode/avl-tree-counter.mjs +0 -2957
- package/dist/leetcode/avl-tree-multi-map.mjs +0 -2889
- package/dist/leetcode/avl-tree.mjs +0 -2720
- package/dist/leetcode/binary-tree.mjs +0 -1594
- package/dist/leetcode/bst.mjs +0 -2398
- package/dist/leetcode/deque.mjs +0 -683
- package/dist/leetcode/directed-graph.mjs +0 -1733
- package/dist/leetcode/doubly-linked-list.mjs +0 -709
- package/dist/leetcode/hash-map.mjs +0 -493
- package/dist/leetcode/heap.mjs +0 -542
- package/dist/leetcode/max-heap.mjs +0 -375
- package/dist/leetcode/max-priority-queue.mjs +0 -383
- package/dist/leetcode/min-heap.mjs +0 -363
- package/dist/leetcode/min-priority-queue.mjs +0 -371
- package/dist/leetcode/priority-queue.mjs +0 -363
- package/dist/leetcode/queue.mjs +0 -943
- package/dist/leetcode/red-black-tree.mjs +0 -2765
- package/dist/leetcode/singly-linked-list.mjs +0 -754
- package/dist/leetcode/stack.mjs +0 -217
- package/dist/leetcode/tree-counter.mjs +0 -3039
- package/dist/leetcode/tree-multi-map.mjs +0 -2913
- package/dist/leetcode/trie.mjs +0 -413
- package/dist/leetcode/undirected-graph.mjs +0 -1650
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_label: "ARCHITECTURE"
|
|
3
|
+
description: "Internal architecture: inheritance hierarchy, iterator protocol, memory layout, and algorithmic guarantees."
|
|
4
|
+
title: "Architecture — Inheritance, Iterators, Memory Layout"
|
|
5
|
+
keywords: [data structure library architecture, typescript inheritance, iterator protocol, memory layout, algorithmic guarantees]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ARCHITECTURE
|
|
9
|
+
|
|
10
|
+
Understand why this library is designed the way it is, and how it works internally.
|
|
11
|
+
|
|
12
|
+
**[Back to README](/.md) • [See Performance](/guide/performance.md) • [Real Examples](/guide/guides.md)**
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Table of Contents
|
|
17
|
+
|
|
18
|
+
1. [Design Philosophy](#design-philosophy)
|
|
19
|
+
2. [The Big Three Pain Points](#the-big-three-pain-points)
|
|
20
|
+
3. [Why Deque is 484x Faster](#why-deque-is-484x-faster)
|
|
21
|
+
4. [Iterator Protocol Design](#iterator-protocol-design)
|
|
22
|
+
5. [Self-Balancing Strategy](#self-balancing-strategy)
|
|
23
|
+
6. [V8 JIT Optimizations](#v8-jit-optimizations)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Design Philosophy
|
|
28
|
+
|
|
29
|
+
### Core Principles
|
|
30
|
+
|
|
31
|
+
1. **Practicality**: Follows ES6 standards, ESNext patterns, simple method names
|
|
32
|
+
2. **Extensibility**: OOP inheritance for all data structures
|
|
33
|
+
3. **Modularization**: Independent NPM packages, no bloat
|
|
34
|
+
4. **Efficiency**: Time/space complexity comparable to native JS
|
|
35
|
+
5. **Maintainability**: Open-source standards, TDD, CI/CD
|
|
36
|
+
6. **Testability**: Automated unit + performance testing
|
|
37
|
+
7. **Reusability**: Fully decoupled, minimized side effects
|
|
38
|
+
8. **Security**: Read-write separation, safe member access
|
|
39
|
+
|
|
40
|
+
### API Design: Unified Interface
|
|
41
|
+
|
|
42
|
+
Instead of learning different APIs for each library:
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// ❌ Different libraries, different APIs
|
|
46
|
+
const queue = new Queue();
|
|
47
|
+
queue.enqueue(1); // Library A
|
|
48
|
+
queue.push(1); // Library B
|
|
49
|
+
queue.offer(1); // Library C (Java style)
|
|
50
|
+
|
|
51
|
+
// ✅ data-structure-typed: Consistent everywhere
|
|
52
|
+
const queue = new Queue();
|
|
53
|
+
const deque = new Deque();
|
|
54
|
+
const stack = new Stack();
|
|
55
|
+
|
|
56
|
+
// All use THE SAME 4 methods
|
|
57
|
+
queue.push(item); // Add
|
|
58
|
+
deque.unshift(item); // Add to front
|
|
59
|
+
stack.pop(); // Remove
|
|
60
|
+
queue.shift(); // Remove from front
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Why?** Because developers already know `push`, `pop`, `shift`, `unshift` from Arrays. Zero new mental models needed.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## The Big Three Pain Points
|
|
68
|
+
|
|
69
|
+
### Pain Point 1: Performance Wall
|
|
70
|
+
|
|
71
|
+
When operations become bottlenecks:
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
const games = [
|
|
75
|
+
{ id: 'game_001', name: 'Tetris', score: 9850 },
|
|
76
|
+
{ id: 'game_002', name: 'Minecraft', score: 9750 },
|
|
77
|
+
{ id: 'game_003', name: 'Grand Theft Auto V', score: 9600 },
|
|
78
|
+
{ id: 'game_004', name: 'Wii Sports', score: 9500 },
|
|
79
|
+
{ id: 'game_005', name: 'PlayerUnknown\'s Battlegrounds', score: 9200 },
|
|
80
|
+
{ id: 'game_006', name: 'Fortnite', score: 9100 },
|
|
81
|
+
{ id: 'game_007', name: 'League of Legends', score: 8950 },
|
|
82
|
+
{ id: 'game_008', name: 'The Legend of Zelda: Breath of the Wild', score: 8850 },
|
|
83
|
+
{ id: 'game_009', name: 'Elden Ring', score: 8700 },
|
|
84
|
+
{ id: 'game_010', name: 'Super Mario Bros', score: 8600 },
|
|
85
|
+
];
|
|
86
|
+
// ❌ Repeated sorting slows everything
|
|
87
|
+
const scores = [];
|
|
88
|
+
for (const game of games) {
|
|
89
|
+
scores.push(game.score);
|
|
90
|
+
scores.sort((a, b) => b - a); // O(n log n) every time!
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
// ✅ Auto-maintained sorted order
|
|
96
|
+
const rankings = new RedBlackTree(games, {
|
|
97
|
+
toEntryFn: (game) => [game.id, game.score],
|
|
98
|
+
comparator: (a, b) => b - a,
|
|
99
|
+
}); // O(n log n) in total!
|
|
100
|
+
// Iteration is always sorted!
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Real Impact:**
|
|
104
|
+
|
|
105
|
+
- Competitive programming: TLE → AC (Time Exceeded to Accepted)
|
|
106
|
+
- Real-time systems: P99 latency 500ms → 5ms
|
|
107
|
+
- Message queues: 100 msg/sec → 10,000 msg/sec
|
|
108
|
+
|
|
109
|
+
### Pain Point 2: API Chaos
|
|
110
|
+
|
|
111
|
+
Different libraries use completely different method names:
|
|
112
|
+
|
|
113
|
+
| Operation | ArrayList | Queue | ArrayDeque | LinkedList |
|
|
114
|
+
|--------------|-----------|--------------|---------------|---------------|
|
|
115
|
+
| Add end | add() | offer() | push() | add() |
|
|
116
|
+
| Remove end | remove() | - | pop() | removeLast() |
|
|
117
|
+
| Remove start | remove(0) | poll() | removeFirst() | removeFirst() |
|
|
118
|
+
| Add start | add(0, e) | offerFirst() | unshift() | addFirst() |
|
|
119
|
+
|
|
120
|
+
**Result**: Developers must memorize N different APIs.
|
|
121
|
+
|
|
122
|
+
**Solution**: Use 4 consistent methods everywhere:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// Every linear structure uses same API
|
|
126
|
+
const deque = new Deque();
|
|
127
|
+
const queue = new Queue();
|
|
128
|
+
const list = new DoublyLinkedList();
|
|
129
|
+
|
|
130
|
+
// All support these 4 methods:
|
|
131
|
+
structure.push(item); // Add to end
|
|
132
|
+
structure.pop(); // Remove from end
|
|
133
|
+
structure.shift(); // Remove from start
|
|
134
|
+
structure.unshift(item); // Add to start
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Pain Point 3: Conversion Hell
|
|
138
|
+
|
|
139
|
+
Bouncing data between structures wastes cycles:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// ❌ Painful way: conversions everywhere
|
|
143
|
+
const tree = new TreeLibrary(data);
|
|
144
|
+
const filtered = tree.toArray()
|
|
145
|
+
.filter(x => x > 5) // Convert to Array
|
|
146
|
+
.map(x => x * 2) // Still Array
|
|
147
|
+
.sort((a, b) => b - a); // Array sort is O(n log n)
|
|
148
|
+
|
|
149
|
+
// Lost the tree's sorted benefits!
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// ✅ Clean way: operations work directly
|
|
154
|
+
const tree = new RedBlackTree<number, number>();
|
|
155
|
+
const result = tree
|
|
156
|
+
.filter(v => (v ?? 0) > 5) // Direct on tree
|
|
157
|
+
.map((v, k) => [k, (v ?? 0) * 2]) // Still on tree
|
|
158
|
+
.reduce((sum, v) => sum + (v ?? 0), 0); // Still on tree
|
|
159
|
+
|
|
160
|
+
// Zero conversions, tree structure maintained!
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Why Deque is 484x Faster
|
|
166
|
+
|
|
167
|
+
### The Problem: Array.shift()
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
// What happens when you shift from an array:
|
|
171
|
+
const arr = [1, 2, 3, 4, 5];
|
|
172
|
+
arr.shift(); // Remove 1
|
|
173
|
+
|
|
174
|
+
// JavaScript engine must:
|
|
175
|
+
// 1. Create new memory for index 0
|
|
176
|
+
// 2. Copy element 2 → index 0
|
|
177
|
+
// 3. Copy element 3 → index 1
|
|
178
|
+
// 4. Copy element 4 → index 2
|
|
179
|
+
// 5. Copy element 5 → index 3
|
|
180
|
+
// 6. Resize array
|
|
181
|
+
|
|
182
|
+
// For 100,000 elements: O(n) = 100,000 operations each time!
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Real benchmark:
|
|
186
|
+
|
|
187
|
+
```javascript
|
|
188
|
+
const queue = [];
|
|
189
|
+
for (let i = 0; i < 100000; i++) queue.push(i);
|
|
190
|
+
for (let i = 0; i < 100000; i++) queue.shift();
|
|
191
|
+
// Time: 2829ms for 100,000 shifts ❌
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### The Solution: Deque's Chunked Rings
|
|
195
|
+
|
|
196
|
+
```javascript
|
|
197
|
+
// Deque implementation strategy:
|
|
198
|
+
// Instead of physical array, use chunked buckets
|
|
199
|
+
|
|
200
|
+
// bucket[0] bucket[1] bucket[2]
|
|
201
|
+
// [1,2,3,4,5] [6,7,8,9,10] [11,12,13]
|
|
202
|
+
// ^
|
|
203
|
+
// head pointer
|
|
204
|
+
|
|
205
|
+
// When you shift():
|
|
206
|
+
// Move pointer forward in bucket
|
|
207
|
+
// No copying until bucket is empty!
|
|
208
|
+
// Only then delete bucket (batch operation)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Benchmark result:
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
const deque = new Deque();
|
|
215
|
+
for (let i = 0; i < 100000; i++) deque.push(i);
|
|
216
|
+
for (let i = 0; i < 100000; i++) deque.shift();
|
|
217
|
+
// Time: 5.83ms for 100,000 shifts ✅
|
|
218
|
+
|
|
219
|
+
// 2829ms / 5.83ms = 485x faster!
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Why This Works
|
|
223
|
+
|
|
224
|
+
**Batching Operations**: Instead of reindexing on every shift, Deque batches operations into chunks. Only when an entire chunk is consumed does it get cleaned up.
|
|
225
|
+
|
|
226
|
+
**Memory Locality**: Chunked structure is better for CPU cache than scattered reindexing operations.
|
|
227
|
+
|
|
228
|
+
**Pointer Movement**: Shifting is just moving a pointer forward in memory, which is a CPU register operation (nanoseconds).
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Iterator Protocol Design
|
|
233
|
+
|
|
234
|
+
### The Hidden Superpower
|
|
235
|
+
|
|
236
|
+
Every data structure implements JavaScript's iterator protocol:
|
|
237
|
+
|
|
238
|
+
```javascript
|
|
239
|
+
// Why this matters:
|
|
240
|
+
const tree = new RedBlackTree([5, 2, 8]);
|
|
241
|
+
|
|
242
|
+
// All of these work automatically:
|
|
243
|
+
[...tree] // Spread operator
|
|
244
|
+
for (const x of tree) {
|
|
245
|
+
} // for...of loop
|
|
246
|
+
const [a, b, c] = tree // Destructuring
|
|
247
|
+
new Set(tree) // Set constructor
|
|
248
|
+
Array.from(tree) // Array.from
|
|
249
|
+
|
|
250
|
+
// No special methods needed!
|
|
251
|
+
// Just implement Symbol.iterator
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Implementation Strategy
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
class CustomStructure<T> {
|
|
258
|
+
private items: T[] = [];
|
|
259
|
+
|
|
260
|
+
// One method makes everything work
|
|
261
|
+
* [Symbol.iterator]() {
|
|
262
|
+
for (const item of this.items) {
|
|
263
|
+
yield item;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
push(...item: T[]) {
|
|
268
|
+
this.items.concat(item);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Now the structure works everywhere:
|
|
273
|
+
const struct = new CustomStructure();
|
|
274
|
+
struct.push(1, 2, 3);
|
|
275
|
+
|
|
276
|
+
// All of these work automatically:
|
|
277
|
+
[...struct]; // [1, 2, 3]
|
|
278
|
+
for (const x of struct) {
|
|
279
|
+
} // Loops 1, 2, 3
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Why Iterator Protocol?
|
|
283
|
+
|
|
284
|
+
1. **Consistency**: Uses same interface as Arrays and Maps
|
|
285
|
+
2. **Zero Learning Curve**: Developers already know `for...of`
|
|
286
|
+
3. **Interoperability**: Works with spread, destructuring, Set constructor
|
|
287
|
+
4. **Future-Proof**: JavaScript standard, not library-specific
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Self-Balancing Strategy
|
|
292
|
+
|
|
293
|
+
### The Problem: Unbalanced Trees
|
|
294
|
+
|
|
295
|
+
```javascript
|
|
296
|
+
// Create an unbalanced tree:
|
|
297
|
+
const bst = new BST();
|
|
298
|
+
[1, 2, 3, 4, 5].forEach(x => bst.add(x));
|
|
299
|
+
|
|
300
|
+
// 1
|
|
301
|
+
// \
|
|
302
|
+
// 2
|
|
303
|
+
// \
|
|
304
|
+
// 3
|
|
305
|
+
// \
|
|
306
|
+
// 4
|
|
307
|
+
// \
|
|
308
|
+
// 5
|
|
309
|
+
|
|
310
|
+
// This becomes a linked list! O(n) instead of O(log n)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Red-Black Tree Solution
|
|
314
|
+
|
|
315
|
+
**Rules:**
|
|
316
|
+
|
|
317
|
+
1. Every node is either Red or Black
|
|
318
|
+
2. Root is always Black
|
|
319
|
+
3. Red nodes have Black children (no consecutive Reds)
|
|
320
|
+
4. All paths to null have same number of Black nodes
|
|
321
|
+
|
|
322
|
+
**Result**: Tree height limited to ~2 * log(n), guaranteeing O(log n)
|
|
323
|
+
|
|
324
|
+
```javascript
|
|
325
|
+
const rbTree = new RedBlackTree([1, 2, 3, 4, 5]);
|
|
326
|
+
|
|
327
|
+
// 3(B) Balanced!
|
|
328
|
+
// / \
|
|
329
|
+
// 2(B) 4(R)
|
|
330
|
+
// / \
|
|
331
|
+
// 1(R) 5(B)
|
|
332
|
+
|
|
333
|
+
// Even with sequential inserts: O(log n) guaranteed!
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### AVL Tree Alternative
|
|
337
|
+
|
|
338
|
+
**Stricter balance requirement**: Height difference ≤ 1
|
|
339
|
+
|
|
340
|
+
```javascript
|
|
341
|
+
// 3
|
|
342
|
+
// / \
|
|
343
|
+
// 2 4
|
|
344
|
+
// / \
|
|
345
|
+
// 1 5
|
|
346
|
+
|
|
347
|
+
// More strictly balanced = better search
|
|
348
|
+
// Trade-off: Slower insertions/deletions (more rebalancing)
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### SkipList: Probabilistic Balancing
|
|
352
|
+
|
|
353
|
+
Unlike Red-Black Tree or AVL Tree which rebalance deterministically, **SkipList** uses randomization:
|
|
354
|
+
|
|
355
|
+
```
|
|
356
|
+
Level 3: ──────────────────────────► 50
|
|
357
|
+
Level 2: ────────► 20 ──────────────► 50
|
|
358
|
+
Level 1: ──► 10 ──► 20 ──► 30 ──► 50 ──► 70
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Each node is promoted to a higher level with probability 0.5 (configurable). This gives O(log n) **average** performance — equivalent to Red-Black Tree in practice, but implemented with much simpler code.
|
|
362
|
+
|
|
363
|
+
**When to use SkipList vs TreeMap:**
|
|
364
|
+
- Both provide identical APIs (`NavigableMap` semantics)
|
|
365
|
+
- SkipList: simpler codebase, constant factors slightly higher
|
|
366
|
+
- TreeMap (Red-Black Tree): guaranteed O(log n) worst-case
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Range Query Structures
|
|
371
|
+
|
|
372
|
+
### SegmentTree
|
|
373
|
+
|
|
374
|
+
Stores aggregated values in a complete binary tree backed by a flat array:
|
|
375
|
+
|
|
376
|
+
```
|
|
377
|
+
Array: [1, 3, 5, 7]
|
|
378
|
+
|
|
379
|
+
Tree: 16 (root = sum all)
|
|
380
|
+
/ \
|
|
381
|
+
4 12 (sum of halves)
|
|
382
|
+
/ \ / \
|
|
383
|
+
1 3 5 7 (leaves = original values)
|
|
384
|
+
|
|
385
|
+
Internal array: [_, 16, 4, 12, 1, 3, 5, 7] (1-indexed)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Query `[1,2]` (3+5=8): combines nodes covering exactly that range in O(log n).
|
|
389
|
+
|
|
390
|
+
Supports any associative operation via `merger` function: sum, min, max, GCD, product, etc.
|
|
391
|
+
|
|
392
|
+
### BinaryIndexedTree (Fenwick Tree)
|
|
393
|
+
|
|
394
|
+
A more compact structure for prefix sums only:
|
|
395
|
+
|
|
396
|
+
```
|
|
397
|
+
Array: [1, 3, 5, 7, 9]
|
|
398
|
+
|
|
399
|
+
BIT tree (1-indexed):
|
|
400
|
+
T[1] = 1 (covers [1,1])
|
|
401
|
+
T[2] = 1+3 = 4 (covers [1,2])
|
|
402
|
+
T[3] = 5 (covers [3,3])
|
|
403
|
+
T[4] = 1+3+5+7=16 (covers [1,4])
|
|
404
|
+
T[5] = 9 (covers [5,5])
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Prefix sum uses bit tricks (`i -= i & -i`) to traverse only O(log n) nodes.
|
|
408
|
+
|
|
409
|
+
**SegmentTree vs BinaryIndexedTree:**
|
|
410
|
+
| | SegmentTree | BinaryIndexedTree |
|
|
411
|
+
|---|---|---|
|
|
412
|
+
| Operations | sum/min/max/any | sum only |
|
|
413
|
+
| Update | O(log n) | O(log n) |
|
|
414
|
+
| Query | O(log n) | O(log n) |
|
|
415
|
+
| Space | O(2n) | O(n) |
|
|
416
|
+
| Complexity | Higher | Lower |
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## V8 JIT Optimizations
|
|
421
|
+
|
|
422
|
+
### How V8 Makes This Fast
|
|
423
|
+
|
|
424
|
+
```javascript
|
|
425
|
+
// V8 JIT optimizes data structures that:
|
|
426
|
+
// 1. Have predictable shapes (hidden classes)
|
|
427
|
+
// 2. Use consistent types
|
|
428
|
+
// 3. Have stable method calls
|
|
429
|
+
|
|
430
|
+
// ✅ Good for V8 JIT:
|
|
431
|
+
class Node {
|
|
432
|
+
constructor(value) {
|
|
433
|
+
this.value = value; // Always same type
|
|
434
|
+
this.left = null; // Always null or Node
|
|
435
|
+
this.right = null; // Always null or Node
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
```javascript
|
|
441
|
+
// ❌ Bad for V8 JIT:
|
|
442
|
+
class BadNode {
|
|
443
|
+
constructor(value) {
|
|
444
|
+
this.value = value;
|
|
445
|
+
this.left = value; // Sometimes Node, sometimes number
|
|
446
|
+
this.meta = null; // Added dynamically later
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
// Our library uses strict typing for this reason!
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Performance Benefit
|
|
454
|
+
|
|
455
|
+
```javascript
|
|
456
|
+
// Predictable structure → V8 caches optimizations
|
|
457
|
+
// First call: Interpreted
|
|
458
|
+
// Subsequent calls: JIT compiled to native code
|
|
459
|
+
|
|
460
|
+
// Result: typically faster after warm-up (benchmarks should include warm-up runs)
|
|
461
|
+
|
|
462
|
+
const tree = new RedBlackTree();
|
|
463
|
+
for (let i = 0; i < 1000000; i++) {
|
|
464
|
+
tree.set(i, Math.random());
|
|
465
|
+
}
|
|
466
|
+
// Becomes near-native speed through JIT!
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## Method Chaining Architecture
|
|
472
|
+
|
|
473
|
+
### Design Pattern
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
class TreeStructure<K, V> {
|
|
477
|
+
// Methods return `this` for chaining
|
|
478
|
+
filter(predicate: (v: V, k: K) => boolean): this {
|
|
479
|
+
// ... filter logic ...
|
|
480
|
+
return this; // Return structure, not Array!
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
map(mapper: (v: V, k: K) => V): this {
|
|
484
|
+
// ... map logic ...
|
|
485
|
+
return this; // Chain continues!
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
reduce(reducer: (acc: any, v: V, k: K) => any, init: any) {
|
|
489
|
+
// ... reduce logic ...
|
|
490
|
+
return result; // Terminal operation
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Result: Chainable on any structure
|
|
495
|
+
tree
|
|
496
|
+
.filter(x => x > 5)
|
|
497
|
+
.map(x => x * 2)
|
|
498
|
+
.reduce((a, v) => a + v, 0);
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### Why This Matters
|
|
502
|
+
|
|
503
|
+
Traditional approach loses structure type:
|
|
504
|
+
|
|
505
|
+
```javascript
|
|
506
|
+
// ❌ Loses type information
|
|
507
|
+
const result = tree.toArray() // Now it's Array[]
|
|
508
|
+
.filter(x => x > 5) // Still Array
|
|
509
|
+
.map(x => x * 2); // Still Array
|
|
510
|
+
// Lost O(log n) properties!
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
```javascript
|
|
514
|
+
// ✅ Preserves structure
|
|
515
|
+
const result = tree
|
|
516
|
+
.filter(x => x > 5) // Still RedBlackTree
|
|
517
|
+
.map(x => x * 2) // Still RedBlackTree
|
|
518
|
+
.reduce((a, v) => a + v);
|
|
519
|
+
// Properties maintained!
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
---
|
|
523
|
+
|
|
524
|
+
## Memory Efficiency
|
|
525
|
+
|
|
526
|
+
### Comparison
|
|
527
|
+
|
|
528
|
+
| Structure | Overhead | Notes |
|
|
529
|
+
|------------|----------|---------------------|
|
|
530
|
+
| Array | Low | Fixed size |
|
|
531
|
+
| LinkedList | High | Pointer per node |
|
|
532
|
+
| BST | Medium | 2 pointers per node |
|
|
533
|
+
| Deque | Very Low | Chunked, batched |
|
|
534
|
+
| Heap | Very Low | Array-based |
|
|
535
|
+
|
|
536
|
+
### Deque Memory Strategy
|
|
537
|
+
|
|
538
|
+
```javascript
|
|
539
|
+
// Instead of one big array:
|
|
540
|
+
// [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
|
|
541
|
+
|
|
542
|
+
// Use chunks (buckets):
|
|
543
|
+
// bucket[0]: [1][2][3][4][5]
|
|
544
|
+
// bucket[1]: [6][7][8][9][10]
|
|
545
|
+
|
|
546
|
+
// Benefits:
|
|
547
|
+
// 1. Only allocate chunks needed
|
|
548
|
+
// 2. Reuse empty buckets
|
|
549
|
+
// 3. Better cache locality
|
|
550
|
+
// 4. Less fragmentation
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
---
|
|
554
|
+
|
|
555
|
+
## Type Safety Architecture
|
|
556
|
+
|
|
557
|
+
### Generic Type Parameters
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
// Custom object types
|
|
561
|
+
interface User {
|
|
562
|
+
id: number;
|
|
563
|
+
name: string;
|
|
564
|
+
age: number;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
const userTree = new RedBlackTree<number, User>();
|
|
568
|
+
userTree.set(1, { id: 1, name: 'Alice', age: 30 });
|
|
569
|
+
|
|
570
|
+
// Type inference works:
|
|
571
|
+
const user = userTree.get(1); // Type: User | undefined
|
|
572
|
+
user?.name; // Type-safe access
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Comparator Custom Logic
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
type CustomObject = {
|
|
579
|
+
name: string;
|
|
580
|
+
priority: number;
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
// Default comparator (ascending)
|
|
584
|
+
const ascTree = new RedBlackTree<number>();
|
|
585
|
+
|
|
586
|
+
// Reversed comparator (descending)
|
|
587
|
+
const descTree = new RedBlackTree<number>([], {
|
|
588
|
+
comparator: (a, b) => b - a // Reverse comparison
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
// Works with any type
|
|
592
|
+
const objectTree = new RedBlackTree<CustomObject>([], {
|
|
593
|
+
comparator: (a, b) => a.priority - b.priority,
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## Summary: Design Checklist
|
|
601
|
+
|
|
602
|
+
- ✅ Unified API across all structures
|
|
603
|
+
- ✅ Iterator protocol implementation
|
|
604
|
+
- ✅ Method chaining architecture
|
|
605
|
+
- ✅ Self-balancing guarantees
|
|
606
|
+
- ✅ V8 JIT-friendly code
|
|
607
|
+
- ✅ Memory-efficient algorithms
|
|
608
|
+
- ✅ Full TypeScript support
|
|
609
|
+
- ✅ Production-ready error handling
|
|
610
|
+
|
|
611
|
+
---
|
|
612
|
+
|
|
613
|
+
**Next:** [Check PERFORMANCE.md](/guide/performance.md) for benchmarks.
|
|
614
|
+
|
|
615
|
+
**Or:** [See GUIDES.md](/guide/guides.md) for implementation examples.
|