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,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Get started with data-structure-typed in 30 seconds. Create trees, queues, and maps with a familiar JavaScript API."
|
|
3
|
+
title: "Quick Start — Get Running in 30 Seconds"
|
|
4
|
+
sidebar_label: "QUICK START"keywords: [data-structure-typed tutorial, typescript data structures getting started, treemap example, heap example]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Quick Start
|
|
8
|
+
|
|
9
|
+
## Leaderboard (Ranked Collections)
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { RedBlackTree } from 'data-structure-typed';
|
|
13
|
+
|
|
14
|
+
// Descending comparator — highest scores first
|
|
15
|
+
const leaderboard = new RedBlackTree<number, string>([
|
|
16
|
+
[100, 'Alice'],
|
|
17
|
+
[85, 'Bob'],
|
|
18
|
+
[92, 'Charlie']
|
|
19
|
+
], { comparator: (a, b) => b - a });
|
|
20
|
+
|
|
21
|
+
// Top-2 via lazy iterator — O(2 log n), no full traversal
|
|
22
|
+
const iter = leaderboard.entries();
|
|
23
|
+
for (let i = 0; i < 2; i++) {
|
|
24
|
+
const { value: [score, player] } = iter.next();
|
|
25
|
+
console.log(`${score}: ${player}`);
|
|
26
|
+
}
|
|
27
|
+
// Output: 100: Alice → 92: Charlie
|
|
28
|
+
|
|
29
|
+
// Update score — O(log n)
|
|
30
|
+
leaderboard.delete(85);
|
|
31
|
+
leaderboard.set(95, 'Bob');
|
|
32
|
+
|
|
33
|
+
// Range query — players scoring 90~100, O(log n + k)
|
|
34
|
+
const scores90to100 = leaderboard.rangeSearch([90, 100]);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Order-Statistic Tree (Rank Queries)
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import { RedBlackTree } from 'data-structure-typed';
|
|
41
|
+
|
|
42
|
+
// Enable order-statistic for O(log n) rank operations
|
|
43
|
+
const tree = new RedBlackTree<number, string>([
|
|
44
|
+
[100, 'Alice'],
|
|
45
|
+
[85, 'Bob'],
|
|
46
|
+
[92, 'Charlie'],
|
|
47
|
+
[78, 'Diana'],
|
|
48
|
+
[95, 'Eve']
|
|
49
|
+
], { comparator: (a, b) => b - a, enableOrderStatistic: true });
|
|
50
|
+
|
|
51
|
+
// select(k) — find k-th element (0-indexed)
|
|
52
|
+
console.log(tree.getByRank(0)); // 100 (1st in tree order)
|
|
53
|
+
console.log(tree.getByRank(2)); // 92 (3rd in tree order)
|
|
54
|
+
|
|
55
|
+
// rank(key) — how many elements before this key?
|
|
56
|
+
console.log(tree.getRank(92)); // 2 (2 elements before 92 in tree order)
|
|
57
|
+
|
|
58
|
+
// rangeByRank(start, end) — pagination
|
|
59
|
+
console.log(tree.rangeByRank(0, 2)); // [100, 95, 92] — top 3
|
|
60
|
+
|
|
61
|
+
// Inverse property: getByRank(getRank(key)) === key
|
|
62
|
+
const k = tree.getRank(85);
|
|
63
|
+
console.log(tree.getByRank(k)); // 85
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Task Queue (Scheduling)
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { MinPriorityQueue } from 'data-structure-typed';
|
|
70
|
+
|
|
71
|
+
const tasks = new MinPriorityQueue<{ task: string; priority: number }>(
|
|
72
|
+
[], { comparator: (a, b) => a.priority - b.priority }
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
tasks.add({ task: 'Send email', priority: 3 });
|
|
76
|
+
tasks.add({ task: 'Fix critical bug', priority: 1 });
|
|
77
|
+
tasks.add({ task: 'Update docs', priority: 2 });
|
|
78
|
+
|
|
79
|
+
// Process in priority order
|
|
80
|
+
while (!tasks.isEmpty()) {
|
|
81
|
+
const next = tasks.poll();
|
|
82
|
+
console.log(next?.task);
|
|
83
|
+
}
|
|
84
|
+
// Fix critical bug → Update docs → Send email
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Fast Autocomplete (Trie)
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
import { Trie } from 'data-structure-typed';
|
|
91
|
+
|
|
92
|
+
const trie = new Trie();
|
|
93
|
+
trie.addMany(['apple', 'application', 'app', 'apex']);
|
|
94
|
+
|
|
95
|
+
console.log(trie.getWords('app')); // ['app', 'apple', 'application']
|
|
96
|
+
console.log(trie.hasPrefix('ap')); // true
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Next Steps
|
|
100
|
+
|
|
101
|
+
- 📖 [Core Concepts](/guide/concepts) — understand the Big Three
|
|
102
|
+
- 📋 [API Reference](/api/) — full method signatures and examples
|
|
103
|
+
- 💡 [Real-World Examples](/guide/guides) — patterns for production
|
|
104
|
+
- ⚡ [Performance](/guide/performance) — benchmarks and comparisons
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: When Array + Sort Becomes Too Slow
|
|
3
|
+
description: Stop re-sorting arrays after every insert. Use TreeMap, TreeSet, or Heap for O(log n) ordered operations in JavaScript and TypeScript.
|
|
4
|
+
keywords: [javascript sorted insert, array sort performance, sorted array alternative, binary search insert javascript, ordered collection typescript]
|
|
5
|
+
sidebar_label: Array + Sort Alternatives
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# When Array + Sort Becomes Too Slow
|
|
9
|
+
|
|
10
|
+
A common pattern in JavaScript:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
const items: number[] = [];
|
|
14
|
+
|
|
15
|
+
function addSorted(value: number) {
|
|
16
|
+
items.push(value);
|
|
17
|
+
items.sort((a, b) => a - b); // O(n log n) every time!
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This works fine for 100 elements. At 10,000, it's noticeably slow. At 100,000, it's a bottleneck.
|
|
22
|
+
|
|
23
|
+
## Why This Is Slow
|
|
24
|
+
|
|
25
|
+
| Elements | Array push + sort | Tree insert |
|
|
26
|
+
|----------|------------------|-------------|
|
|
27
|
+
| 100 | ~0.01ms | ~0.01ms |
|
|
28
|
+
| 10,000 | ~5ms | ~0.1ms |
|
|
29
|
+
| 100,000 | ~80ms | ~0.2ms |
|
|
30
|
+
| 1,000,000 | ~1200ms | ~0.5ms |
|
|
31
|
+
|
|
32
|
+
Array.sort is O(n log n). Tree insert is O(log n). The gap grows with data size.
|
|
33
|
+
|
|
34
|
+
## Choose the Right Alternative
|
|
35
|
+
|
|
36
|
+
### Need sorted key-value pairs → TreeMap
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { TreeMap } from 'data-structure-typed';
|
|
40
|
+
|
|
41
|
+
const prices = new TreeMap<string, number>();
|
|
42
|
+
prices.set('apple', 1.2);
|
|
43
|
+
prices.set('banana', 0.5);
|
|
44
|
+
prices.set('cherry', 2.5);
|
|
45
|
+
|
|
46
|
+
// Always sorted by key
|
|
47
|
+
for (const [fruit, price] of prices) {
|
|
48
|
+
console.log(fruit, price);
|
|
49
|
+
}
|
|
50
|
+
// apple 1.2, banana 0.5, cherry 2.5
|
|
51
|
+
|
|
52
|
+
// Find nearest
|
|
53
|
+
prices.floor('blueberry'); // ['banana', 0.5]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Need sorted unique values → TreeSet
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { TreeSet } from 'data-structure-typed';
|
|
60
|
+
|
|
61
|
+
const uniqueScores = new TreeSet<number>();
|
|
62
|
+
uniqueScores.add(85);
|
|
63
|
+
uniqueScores.add(92);
|
|
64
|
+
uniqueScores.add(78);
|
|
65
|
+
uniqueScores.add(85); // duplicate ignored
|
|
66
|
+
|
|
67
|
+
[...uniqueScores]; // [78, 85, 92] — sorted, unique
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Only need min or max → Heap
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { MinHeap } from 'data-structure-typed';
|
|
74
|
+
|
|
75
|
+
const heap = new MinHeap<number>();
|
|
76
|
+
heap.add(5);
|
|
77
|
+
heap.add(2);
|
|
78
|
+
heap.add(8);
|
|
79
|
+
|
|
80
|
+
heap.peek(); // 2 — O(1)
|
|
81
|
+
heap.poll(); // 2 — O(log n), removes and returns min
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Heap is lighter than TreeMap when you only need the top element.
|
|
85
|
+
|
|
86
|
+
## Decision Guide
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Do you need...
|
|
90
|
+
├── Only the min or max? → Heap / MinHeap / MaxHeap
|
|
91
|
+
├── Sorted iteration of all elements?
|
|
92
|
+
│ ├── Key-value pairs? → TreeMap
|
|
93
|
+
│ └── Values only? → TreeSet
|
|
94
|
+
├── Floor / ceiling / range queries? → TreeMap / TreeSet
|
|
95
|
+
├── Rank queries (kth element)? → TreeMap/TreeSet with enableOrderStatistic
|
|
96
|
+
└── Just fast lookup by key? → HashMap (or native Map)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Before and After
|
|
100
|
+
|
|
101
|
+
### Task queue (before)
|
|
102
|
+
```typescript
|
|
103
|
+
// ❌ O(n log n) per insert
|
|
104
|
+
const tasks: { priority: number; name: string }[] = [];
|
|
105
|
+
tasks.push({ priority: 3, name: 'email' });
|
|
106
|
+
tasks.push({ priority: 1, name: 'bugfix' });
|
|
107
|
+
tasks.sort((a, b) => a.priority - b.priority);
|
|
108
|
+
const next = tasks.shift(); // O(n) shift
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Task queue (after)
|
|
112
|
+
```typescript
|
|
113
|
+
// ✅ O(log n) per insert, O(log n) per poll
|
|
114
|
+
import { MinPriorityQueue } from 'data-structure-typed';
|
|
115
|
+
|
|
116
|
+
const tasks = new MinPriorityQueue<{ priority: number; name: string }>({
|
|
117
|
+
comparator: (a, b) => a.priority - b.priority
|
|
118
|
+
});
|
|
119
|
+
tasks.add({ priority: 3, name: 'email' });
|
|
120
|
+
tasks.add({ priority: 1, name: 'bugfix' });
|
|
121
|
+
const next = tasks.poll(); // { priority: 1, name: 'bugfix' }
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Leaderboard (before)
|
|
125
|
+
```typescript
|
|
126
|
+
// ❌ Re-sort after every score update
|
|
127
|
+
const scores: [string, number][] = [];
|
|
128
|
+
scores.push(['Alice', 100]);
|
|
129
|
+
scores.push(['Bob', 250]);
|
|
130
|
+
scores.sort((a, b) => b[1] - a[1]);
|
|
131
|
+
const top3 = scores.slice(0, 3); // O(n log n) + O(k)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Leaderboard (after)
|
|
135
|
+
```typescript
|
|
136
|
+
// ✅ O(log n) insert, O(log n + k) for top-k
|
|
137
|
+
import { TreeMap } from 'data-structure-typed';
|
|
138
|
+
|
|
139
|
+
const board = new TreeMap<number, string>(
|
|
140
|
+
[[100, 'Alice'], [250, 'Bob']],
|
|
141
|
+
{ comparator: (a, b) => b - a, enableOrderStatistic: true }
|
|
142
|
+
);
|
|
143
|
+
board.rangeByRank(0, 2); // Top 3 in O(log n + k)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Complexity Cheat Sheet
|
|
147
|
+
|
|
148
|
+
| Operation | Array + sort | TreeMap/TreeSet | Heap |
|
|
149
|
+
|-----------|-------------|----------------|------|
|
|
150
|
+
| Insert (maintain order) | O(n log n) | O(log n) | O(log n) |
|
|
151
|
+
| Get min/max | O(1) | O(log n) | O(1) |
|
|
152
|
+
| Delete min/max | O(n) | O(log n) | O(log n) |
|
|
153
|
+
| Find by key | O(log n) | O(log n) | O(n) |
|
|
154
|
+
| Floor/Ceiling | O(log n) | O(log n) | ❌ |
|
|
155
|
+
| Range query | O(log n + k) | O(log n + k) | ❌ |
|
|
156
|
+
| Sorted iteration | O(1)* | O(n) | O(n log n) |
|
|
157
|
+
|
|
158
|
+
*Array is already sorted, so iteration is free — but maintaining that sort is expensive.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Heap vs Sorting an Array — When to Use Which
|
|
3
|
+
description: Compare Heap and Array.sort for priority queues, top-k, and streaming data in JavaScript/TypeScript. Performance analysis and code examples.
|
|
4
|
+
keywords: [heap vs sort, array sort performance, priority queue vs sort, top k javascript, heap javascript, when to use heap]
|
|
5
|
+
sidebar_label: Heap vs Sorting
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Heap vs Sorting an Array
|
|
9
|
+
|
|
10
|
+
Both can give you ordered data. But they're optimized for different access patterns.
|
|
11
|
+
|
|
12
|
+
## Quick Answer
|
|
13
|
+
|
|
14
|
+
- **Need all elements sorted** → sort the array once
|
|
15
|
+
- **Need only the min/max repeatedly** → use a Heap
|
|
16
|
+
- **Streaming data (elements arrive over time)** → use a Heap
|
|
17
|
+
- **Static data, one-time sort** → use Array.sort
|
|
18
|
+
|
|
19
|
+
## Performance Comparison
|
|
20
|
+
|
|
21
|
+
| Operation | Array.sort | Heap |
|
|
22
|
+
|-----------|-----------|------|
|
|
23
|
+
| Sort all elements | O(n log n) | O(n log n) |
|
|
24
|
+
| Insert 1 element (keep sorted) | O(n log n) or O(n)* | O(log n) |
|
|
25
|
+
| Get min/max | O(1) | O(1) |
|
|
26
|
+
| Remove min/max | O(n) | O(log n) |
|
|
27
|
+
| Get top-k from n elements | O(n log n) | O(n log k) |
|
|
28
|
+
|
|
29
|
+
*O(n) if you binary-search + splice; O(n log n) if you push + re-sort.
|
|
30
|
+
|
|
31
|
+
## Example: Top-K Scores
|
|
32
|
+
|
|
33
|
+
### Array approach
|
|
34
|
+
```typescript
|
|
35
|
+
// ❌ Sort everything, take first k
|
|
36
|
+
function topK_array(scores: number[], k: number): number[] {
|
|
37
|
+
return scores.sort((a, b) => b - a).slice(0, k);
|
|
38
|
+
// O(n log n) — sorts ALL elements even if k is small
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Heap approach
|
|
43
|
+
```typescript
|
|
44
|
+
import { MinHeap } from 'data-structure-typed';
|
|
45
|
+
|
|
46
|
+
// ✅ Only maintain k elements in the heap
|
|
47
|
+
function topK_heap(scores: number[], k: number): number[] {
|
|
48
|
+
const heap = new MinHeap<number>();
|
|
49
|
+
for (const score of scores) {
|
|
50
|
+
heap.add(score);
|
|
51
|
+
if (heap.size > k) heap.poll();
|
|
52
|
+
}
|
|
53
|
+
return heap.toArray().sort((a, b) => b - a);
|
|
54
|
+
// O(n log k) — much faster when k << n
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
For 1,000,000 elements with k=10: array sorts all 1M elements. Heap only maintains 10.
|
|
59
|
+
|
|
60
|
+
## Example: Streaming Data
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { MinHeap } from 'data-structure-typed';
|
|
64
|
+
|
|
65
|
+
// New scores arrive continuously
|
|
66
|
+
const liveScores = new MinHeap<number>();
|
|
67
|
+
|
|
68
|
+
// Each insert: O(log n)
|
|
69
|
+
liveScores.add(85);
|
|
70
|
+
liveScores.add(92);
|
|
71
|
+
liveScores.add(78);
|
|
72
|
+
|
|
73
|
+
// Current lowest: O(1)
|
|
74
|
+
liveScores.peek(); // 78
|
|
75
|
+
|
|
76
|
+
// Process lowest: O(log n)
|
|
77
|
+
liveScores.poll(); // 78
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
With an array, you'd re-sort after every insert — O(n log n) each time.
|
|
81
|
+
|
|
82
|
+
## When to Use Each
|
|
83
|
+
|
|
84
|
+
| Scenario | Use Array.sort | Use Heap |
|
|
85
|
+
|----------|---------------|----------|
|
|
86
|
+
| One-time sort of static data | ✅ | ❌ |
|
|
87
|
+
| Repeated insert + get min/max | ❌ | ✅ |
|
|
88
|
+
| Top-k from large dataset | ❌ (k << n) | ✅ |
|
|
89
|
+
| Streaming / real-time data | ❌ | ✅ |
|
|
90
|
+
| Need sorted iteration of ALL elements | ✅ | ❌ |
|
|
91
|
+
| Dijkstra / A* algorithm | ❌ | ✅ |
|
|
92
|
+
| Simple, small dataset (< 100) | ✅ | Either |
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Map vs TreeMap — When Native Map Isn't Enough
|
|
3
|
+
description: Compare JavaScript's native Map with TreeMap for sorted collections, range queries, and ordered iteration. Code examples and performance analysis.
|
|
4
|
+
keywords: [map vs treemap, javascript map alternative, sorted map javascript, ordered map typescript, treemap performance, when to use treemap]
|
|
5
|
+
sidebar_label: Map vs TreeMap
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Map vs TreeMap
|
|
9
|
+
|
|
10
|
+
JavaScript's `Map` is excellent for key-value lookup. But it has no concept of order, range, or proximity. When you need those, use `TreeMap`.
|
|
11
|
+
|
|
12
|
+
## Feature Comparison
|
|
13
|
+
|
|
14
|
+
| Feature | Map | TreeMap |
|
|
15
|
+
|---------|-----|---------|
|
|
16
|
+
| Key-value lookup | O(1) avg | O(log n) |
|
|
17
|
+
| Insert / delete | O(1) avg | O(log n) |
|
|
18
|
+
| Sorted iteration | ❌ | ✅ |
|
|
19
|
+
| Floor (largest key ≤ x) | ❌ | O(log n) |
|
|
20
|
+
| Ceiling (smallest key ≥ x) | ❌ | O(log n) |
|
|
21
|
+
| Range query | ❌ | O(log n + k) |
|
|
22
|
+
| getRank / getByRank | ❌ | O(log n) |
|
|
23
|
+
| First / last key | ❌ | O(log n) |
|
|
24
|
+
| Memory | Lower | Higher |
|
|
25
|
+
|
|
26
|
+
## When Map Is the Right Choice
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// User lookup by ID — order doesn't matter
|
|
30
|
+
const users = new Map<string, User>();
|
|
31
|
+
users.set('abc123', { name: 'Alice' });
|
|
32
|
+
users.get('abc123'); // O(1)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Use `Map` when:
|
|
36
|
+
- You only need get/set/delete by exact key
|
|
37
|
+
- Order doesn't matter
|
|
38
|
+
- Performance on individual lookups is critical (O(1) vs O(log n))
|
|
39
|
+
|
|
40
|
+
## When TreeMap Is the Right Choice
|
|
41
|
+
|
|
42
|
+
### Sorted iteration
|
|
43
|
+
```typescript
|
|
44
|
+
import { TreeMap } from 'data-structure-typed';
|
|
45
|
+
|
|
46
|
+
const config = new TreeMap<string, string>();
|
|
47
|
+
config.set('database.host', 'localhost');
|
|
48
|
+
config.set('app.name', 'MyApp');
|
|
49
|
+
config.set('database.port', '5432');
|
|
50
|
+
|
|
51
|
+
for (const [key, value] of config) {
|
|
52
|
+
console.log(key, value);
|
|
53
|
+
}
|
|
54
|
+
// app.name MyApp
|
|
55
|
+
// database.host localhost
|
|
56
|
+
// database.port 5432
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Finding nearest keys
|
|
60
|
+
```typescript
|
|
61
|
+
const prices = new TreeMap<number, string>();
|
|
62
|
+
prices.set(10, 'cheap');
|
|
63
|
+
prices.set(50, 'medium');
|
|
64
|
+
prices.set(100, 'expensive');
|
|
65
|
+
|
|
66
|
+
// "What's the price tier for $35?"
|
|
67
|
+
prices.floor(35); // [10, 'cheap'] — largest key ≤ 35
|
|
68
|
+
prices.ceiling(35); // [50, 'medium'] — smallest key ≥ 35
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Range queries
|
|
72
|
+
```typescript
|
|
73
|
+
const events = new TreeMap<number, string>();
|
|
74
|
+
events.set(1000, 'login');
|
|
75
|
+
events.set(2000, 'click');
|
|
76
|
+
events.set(3000, 'purchase');
|
|
77
|
+
events.set(4000, 'logout');
|
|
78
|
+
|
|
79
|
+
// Events between t=1500 and t=3500
|
|
80
|
+
events.rangeSearch([1500, 3500]); // [[2000, 'click'], [3000, 'purchase']]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Rank queries
|
|
84
|
+
```typescript
|
|
85
|
+
const leaderboard = new TreeMap<number, string>(
|
|
86
|
+
[[100, 'Alice'], [250, 'Bob'], [180, 'Charlie']],
|
|
87
|
+
{ enableOrderStatistic: true }
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
leaderboard.getRank(180); // 1 — Charlie is at position 1
|
|
91
|
+
leaderboard.getByRank(0); // [100, 'Alice'] — first in tree order
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Performance: When Does TreeMap Win?
|
|
95
|
+
|
|
96
|
+
For pure get/set, Map is faster (O(1) vs O(log n)). TreeMap wins when you need **ordered operations**:
|
|
97
|
+
|
|
98
|
+
| 10,000 entries | Map | TreeMap |
|
|
99
|
+
|----------------|-----|---------|
|
|
100
|
+
| set() | ~0.5μs | ~2μs |
|
|
101
|
+
| get() | ~0.3μs | ~1.5μs |
|
|
102
|
+
| floor() | N/A (manual O(n)) | ~1.5μs |
|
|
103
|
+
| rangeSearch() | N/A (manual O(n log n)) | ~5μs + O(k) |
|
|
104
|
+
| Sorted iteration | O(n log n) sort first | O(n) |
|
|
105
|
+
|
|
106
|
+
If you're calling `.floor()` or `.rangeSearch()` frequently, TreeMap is orders of magnitude faster than manually sorting Map keys every time.
|
|
107
|
+
|
|
108
|
+
## Set vs TreeSet — Same Story
|
|
109
|
+
|
|
110
|
+
| Feature | Set | TreeSet |
|
|
111
|
+
|---------|-----|---------|
|
|
112
|
+
| Membership check | O(1) avg | O(log n) |
|
|
113
|
+
| Sorted iteration | ❌ | ✅ |
|
|
114
|
+
| Floor / ceiling | ❌ | O(log n) |
|
|
115
|
+
| Range queries | ❌ | O(log n + k) |
|
|
116
|
+
| First / last | ❌ | O(log n) |
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { TreeSet } from 'data-structure-typed';
|
|
120
|
+
|
|
121
|
+
const timestamps = new TreeSet<number>([1000, 3000, 2000, 5000]);
|
|
122
|
+
[...timestamps]; // [1000, 2000, 3000, 5000]
|
|
123
|
+
timestamps.floor(2500); // 2000
|
|
124
|
+
timestamps.ceiling(2500); // 3000
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Migration Guide: Map → TreeMap
|
|
128
|
+
|
|
129
|
+
TreeMap implements the same interface patterns as Map:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// Map
|
|
133
|
+
const map = new Map<string, number>();
|
|
134
|
+
map.set('a', 1);
|
|
135
|
+
map.get('a');
|
|
136
|
+
map.has('a');
|
|
137
|
+
map.delete('a');
|
|
138
|
+
map.size;
|
|
139
|
+
for (const [k, v] of map) { ... }
|
|
140
|
+
|
|
141
|
+
// TreeMap — same API, plus ordered operations
|
|
142
|
+
const tree = new TreeMap<string, number>();
|
|
143
|
+
tree.set('a', 1);
|
|
144
|
+
tree.get('a');
|
|
145
|
+
tree.has('a');
|
|
146
|
+
tree.delete('a');
|
|
147
|
+
tree.size;
|
|
148
|
+
for (const [k, v] of tree) { ... } // sorted!
|
|
149
|
+
tree.floor('b'); // bonus
|
|
150
|
+
tree.rangeSearch(['a', 'z']); // bonus
|
|
151
|
+
```
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Priority Queue in TypeScript — Complete Guide
|
|
3
|
+
description: How to implement a priority queue in TypeScript using Heap, MinHeap, and MaxHeap. Covers task scheduling, top-k problems, and Dijkstra's algorithm.
|
|
4
|
+
keywords: [priority queue typescript, heap typescript, min heap javascript, max heap javascript, task scheduler, top-k]
|
|
5
|
+
sidebar_label: Priority Queue
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Priority Queue in TypeScript
|
|
9
|
+
|
|
10
|
+
A **priority queue** processes elements by priority, not insertion order. In TypeScript, there is no built-in priority queue — but you can use a **Heap** to get O(log n) insert and O(1) access to the highest-priority element.
|
|
11
|
+
|
|
12
|
+
## The Problem
|
|
13
|
+
|
|
14
|
+
You have tasks with different priorities. Using a sorted array:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// ❌ Array approach — O(n) insert to maintain sorted order
|
|
18
|
+
const tasks: [number, string][] = [];
|
|
19
|
+
|
|
20
|
+
function addTask(priority: number, name: string) {
|
|
21
|
+
tasks.push([priority, name]);
|
|
22
|
+
tasks.sort((a, b) => a[0] - b[0]); // O(n log n) every time!
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
With 10,000 tasks, this gets slow fast.
|
|
27
|
+
|
|
28
|
+
## The Solution
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { MinPriorityQueue } from 'data-structure-typed';
|
|
32
|
+
|
|
33
|
+
// O(log n) insert, O(1) peek, O(log n) poll
|
|
34
|
+
const tasks = new MinPriorityQueue<[number, string]>({
|
|
35
|
+
comparator: (a, b) => a[0] - b[0]
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
tasks.add([3, 'Send email']);
|
|
39
|
+
tasks.add([1, 'Fix critical bug']);
|
|
40
|
+
tasks.add([2, 'Review PR']);
|
|
41
|
+
|
|
42
|
+
tasks.poll(); // [1, 'Fix critical bug'] — highest priority first
|
|
43
|
+
tasks.poll(); // [2, 'Review PR']
|
|
44
|
+
tasks.poll(); // [3, 'Send email']
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## When to Use a Priority Queue
|
|
48
|
+
|
|
49
|
+
| Scenario | Why Heap? |
|
|
50
|
+
|----------|-----------|
|
|
51
|
+
| Task scheduling | Process highest-priority task first |
|
|
52
|
+
| Top-k elements | Find k largest/smallest in O(n log k) |
|
|
53
|
+
| Dijkstra's algorithm | Always expand the nearest unvisited node |
|
|
54
|
+
| Event simulation | Process next event by timestamp |
|
|
55
|
+
| Median finding | Two heaps (min + max) for O(log n) median |
|
|
56
|
+
|
|
57
|
+
## MinHeap vs MaxHeap vs Custom
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { MinHeap, MaxHeap, Heap } from 'data-structure-typed';
|
|
61
|
+
|
|
62
|
+
// Numbers — built-in comparison
|
|
63
|
+
const minHeap = new MinHeap<number>([5, 3, 8, 1]);
|
|
64
|
+
minHeap.peek(); // 1
|
|
65
|
+
|
|
66
|
+
const maxHeap = new MaxHeap<number>([5, 3, 8, 1]);
|
|
67
|
+
maxHeap.peek(); // 8
|
|
68
|
+
|
|
69
|
+
// Objects — custom comparator
|
|
70
|
+
const taskHeap = new Heap<{ priority: number; name: string }>({
|
|
71
|
+
comparator: (a, b) => a.priority - b.priority
|
|
72
|
+
});
|
|
73
|
+
taskHeap.add({ priority: 2, name: 'Review PR' });
|
|
74
|
+
taskHeap.add({ priority: 1, name: 'Fix bug' });
|
|
75
|
+
taskHeap.peek(); // { priority: 1, name: 'Fix bug' }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Top-K Problem
|
|
79
|
+
|
|
80
|
+
Find the 3 highest scores from a stream:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { MinHeap } from 'data-structure-typed';
|
|
84
|
+
|
|
85
|
+
function topK(stream: number[], k: number): number[] {
|
|
86
|
+
const heap = new MinHeap<number>();
|
|
87
|
+
for (const val of stream) {
|
|
88
|
+
heap.add(val);
|
|
89
|
+
if (heap.size > k) heap.poll(); // remove smallest
|
|
90
|
+
}
|
|
91
|
+
return heap.toArray().sort((a, b) => b - a);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
topK([3, 1, 4, 1, 5, 9, 2, 6, 5], 3); // [9, 6, 5]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Time: O(n log k) — much better than sorting the entire array.
|
|
98
|
+
|
|
99
|
+
## Complexity
|
|
100
|
+
|
|
101
|
+
| Operation | Array (sorted) | Heap |
|
|
102
|
+
|-----------|---------------|------|
|
|
103
|
+
| Insert | O(n) | O(log n) |
|
|
104
|
+
| Get min/max | O(1) | O(1) |
|
|
105
|
+
| Remove min/max | O(1) | O(log n) |
|
|
106
|
+
| Search | O(log n) | O(n) |
|
|
107
|
+
|
|
108
|
+
## When NOT to Use a Heap
|
|
109
|
+
|
|
110
|
+
- You need to search for arbitrary elements → use a Tree or HashMap
|
|
111
|
+
- You need sorted iteration of all elements → use TreeMap/TreeSet
|
|
112
|
+
- Your data is small (< 100 elements) → array sort is fine
|
|
113
|
+
- You need both min and max → use two heaps or a TreeMap
|