data-structure-typed 2.5.2 → 2.6.0
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/.husky/pre-commit +3 -0
- package/CHANGELOG.md +3 -1
- package/MIGRATION.md +217 -0
- package/README.md +80 -8
- package/README_CN.md +569 -143
- package/SPECIFICATION.md +44 -14
- package/SPECIFICATION.zh-CN.md +44 -14
- package/dist/cjs/binary-tree.cjs +5841 -1678
- package/dist/cjs/graph.cjs +422 -14
- package/dist/cjs/hash.cjs +95 -7
- package/dist/cjs/heap.cjs +174 -16
- package/dist/cjs/index.cjs +7751 -2449
- package/dist/cjs/linked-list.cjs +443 -2
- package/dist/cjs/matrix.cjs +56 -0
- package/dist/cjs/priority-queue.cjs +172 -14
- package/dist/cjs/queue.cjs +435 -0
- package/dist/cjs/stack.cjs +103 -4
- package/dist/cjs/trie.cjs +106 -0
- package/dist/cjs-legacy/binary-tree.cjs +5933 -1772
- package/dist/cjs-legacy/graph.cjs +422 -14
- package/dist/cjs-legacy/hash.cjs +95 -7
- package/dist/cjs-legacy/heap.cjs +174 -16
- package/dist/cjs-legacy/index.cjs +8154 -2854
- package/dist/cjs-legacy/linked-list.cjs +443 -2
- package/dist/cjs-legacy/matrix.cjs +56 -0
- package/dist/cjs-legacy/priority-queue.cjs +172 -14
- package/dist/cjs-legacy/queue.cjs +435 -0
- package/dist/cjs-legacy/stack.cjs +103 -4
- package/dist/cjs-legacy/trie.cjs +106 -0
- package/dist/esm/binary-tree.mjs +5841 -1678
- package/dist/esm/graph.mjs +422 -14
- package/dist/esm/hash.mjs +95 -7
- package/dist/esm/heap.mjs +174 -16
- package/dist/esm/index.mjs +7751 -2449
- package/dist/esm/linked-list.mjs +443 -2
- package/dist/esm/matrix.mjs +56 -0
- package/dist/esm/priority-queue.mjs +172 -14
- package/dist/esm/queue.mjs +435 -0
- package/dist/esm/stack.mjs +103 -4
- package/dist/esm/trie.mjs +106 -0
- package/dist/esm-legacy/binary-tree.mjs +5933 -1772
- package/dist/esm-legacy/graph.mjs +422 -14
- package/dist/esm-legacy/hash.mjs +95 -7
- package/dist/esm-legacy/heap.mjs +174 -16
- package/dist/esm-legacy/index.mjs +8154 -2854
- package/dist/esm-legacy/linked-list.mjs +443 -2
- package/dist/esm-legacy/matrix.mjs +56 -0
- package/dist/esm-legacy/priority-queue.mjs +172 -14
- package/dist/esm-legacy/queue.mjs +435 -0
- package/dist/esm-legacy/stack.mjs +103 -4
- package/dist/esm-legacy/trie.mjs +106 -0
- package/dist/types/data-structures/base/iterable-element-base.d.ts +17 -0
- package/dist/types/data-structures/base/linear-base.d.ts +6 -0
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +86 -2
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +98 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +191 -15
- package/dist/types/data-structures/binary-tree/bst.d.ts +171 -3
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +136 -8
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +42 -0
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +1061 -167
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +1232 -355
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +916 -194
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +1078 -141
- package/dist/types/data-structures/graph/directed-graph.d.ts +70 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +63 -0
- package/dist/types/data-structures/hash/hash-map.d.ts +84 -6
- package/dist/types/data-structures/heap/heap.d.ts +140 -12
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +150 -2
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +106 -1
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +126 -0
- package/dist/types/data-structures/matrix/matrix.d.ts +56 -0
- package/dist/types/data-structures/queue/deque.d.ts +171 -0
- package/dist/types/data-structures/queue/queue.d.ts +97 -0
- package/dist/types/data-structures/stack/stack.d.ts +72 -2
- package/dist/types/data-structures/trie/trie.d.ts +84 -0
- package/dist/types/interfaces/binary-tree.d.ts +2 -3
- package/dist/umd/data-structure-typed.js +7784 -2484
- package/dist/umd/data-structure-typed.min.js +4 -4
- package/docs-site-docusaurus/docs/api/classes/AVLTree.md +188 -200
- package/docs-site-docusaurus/docs/api/classes/AVLTreeNode.md +11 -11
- package/docs-site-docusaurus/docs/api/classes/AbstractGraph.md +62 -62
- package/docs-site-docusaurus/docs/api/classes/BST.md +183 -195
- package/docs-site-docusaurus/docs/api/classes/BSTNode.md +13 -13
- package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +15 -15
- package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +143 -155
- package/docs-site-docusaurus/docs/api/classes/BinaryTreeNode.md +13 -13
- package/docs-site-docusaurus/docs/api/classes/Deque.md +99 -85
- package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +73 -73
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +100 -70
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedListNode.md +8 -8
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +12 -12
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +1 -1
- package/docs-site-docusaurus/docs/api/classes/HashMap.md +38 -38
- package/docs-site-docusaurus/docs/api/classes/Heap.md +96 -85
- package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +25 -25
- package/docs-site-docusaurus/docs/api/classes/IterableEntryBase.md +23 -23
- package/docs-site-docusaurus/docs/api/classes/LinearBase.md +48 -48
- package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +52 -52
- package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +46 -42
- package/docs-site-docusaurus/docs/api/classes/LinkedListNode.md +6 -6
- package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +74 -74
- package/docs-site-docusaurus/docs/api/classes/MapGraph.md +73 -73
- package/docs-site-docusaurus/docs/api/classes/Matrix.md +31 -31
- package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +104 -89
- package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +104 -89
- package/docs-site-docusaurus/docs/api/classes/MinHeap.md +104 -89
- package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +104 -89
- package/docs-site-docusaurus/docs/api/classes/Navigator.md +5 -5
- package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +103 -88
- package/docs-site-docusaurus/docs/api/classes/Queue.md +111 -59
- package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +200 -212
- package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +10 -10
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +75 -75
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedListNode.md +6 -6
- package/docs-site-docusaurus/docs/api/classes/SkipList.md +37 -37
- package/docs-site-docusaurus/docs/api/classes/Stack.md +42 -42
- package/docs-site-docusaurus/docs/api/classes/TreeMap.md +107 -36
- package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +43 -43
- package/docs-site-docusaurus/docs/api/classes/TreeSet.md +106 -35
- package/docs-site-docusaurus/docs/api/classes/Trie.md +43 -43
- package/docs-site-docusaurus/docs/api/classes/TrieNode.md +8 -8
- package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +72 -72
- package/docs-site-docusaurus/docs/guide/architecture.md +75 -7
- package/docs-site-docusaurus/docs/guide/concepts.md +53 -34
- package/docs-site-docusaurus/docs/guide/faq.md +53 -0
- package/docs-site-docusaurus/docs/guide/guides.md +8 -9
- package/docs-site-docusaurus/docs/guide/integrations.md +74 -177
- package/docs-site-docusaurus/docs/guide/overview.md +131 -17
- package/docs-site-docusaurus/src/pages/index.tsx +4 -0
- package/docs-site-docusaurus/typedoc.json +1 -0
- package/jest.integration.config.js +1 -2
- package/package.json +10 -7
- package/src/data-structures/base/iterable-element-base.ts +32 -0
- package/src/data-structures/base/linear-base.ts +11 -0
- package/src/data-structures/binary-tree/avl-tree.ts +88 -5
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +98 -0
- package/src/data-structures/binary-tree/binary-tree.ts +242 -81
- package/src/data-structures/binary-tree/bst.ts +173 -7
- package/src/data-structures/binary-tree/red-black-tree.ts +139 -15
- package/src/data-structures/binary-tree/segment-tree.ts +42 -0
- package/src/data-structures/binary-tree/tree-map.ts +948 -36
- package/src/data-structures/binary-tree/tree-multi-map.ts +893 -13
- package/src/data-structures/binary-tree/tree-multi-set.ts +761 -33
- package/src/data-structures/binary-tree/tree-set.ts +1260 -251
- package/src/data-structures/graph/directed-graph.ts +71 -1
- package/src/data-structures/graph/undirected-graph.ts +64 -1
- package/src/data-structures/hash/hash-map.ts +100 -12
- package/src/data-structures/heap/heap.ts +149 -19
- package/src/data-structures/linked-list/doubly-linked-list.ts +178 -2
- package/src/data-structures/linked-list/singly-linked-list.ts +106 -1
- package/src/data-structures/linked-list/skip-linked-list.ts +126 -0
- package/src/data-structures/matrix/matrix.ts +56 -0
- package/src/data-structures/queue/deque.ts +187 -0
- package/src/data-structures/queue/queue.ts +109 -0
- package/src/data-structures/stack/stack.ts +75 -5
- package/src/data-structures/trie/trie.ts +84 -0
- package/src/interfaces/binary-tree.ts +1 -9
- package/.vitepress/cache/deps_temp_51f5f1b0/chunk-7OIKW5WK.js +0 -12984
- package/.vitepress/cache/deps_temp_51f5f1b0/package.json +0 -3
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vue_devtools-api.js +0 -4505
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vueuse_core.js +0 -9731
- package/.vitepress/cache/deps_temp_51f5f1b0/vue.js +0 -347
package/README_CN.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[English](./README.md) | 简体中文
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
一个生产就绪的 TypeScript 数据结构库,包含 **Heap、Linked List、Deque、Trie、Graph、Red-Black Tree、TreeMap、TreeSet、SkipList、Segment Tree** 等 — API 对齐 JavaScript 原生 **Array、Map 和 Set**。零依赖。类型安全。ES2025 Set 操作。O(log n) 排名和范围查询。
|
|
6
|
+
|
|
7
|
+
> **在 TypeScript/JavaScript 中寻找 TreeMap、TreeSet 或 PriorityQueue?** 熟悉的 API、集合操作、排名查询、有序访问 — 告别重复 `Array.sort()`。
|
|
6
8
|
|
|
7
9
|

|
|
8
10
|

|
|
@@ -12,92 +14,178 @@
|
|
|
12
14
|

|
|
13
15
|

|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
**📦 [安装](#-安装) • 🎮 [Playground](#-playground) • ⚡ [快速开始](#-快速开始-30-秒) • 📖 [文档](#-文档) • 📋 [API](https://data-structure-typed-docs.vercel.app/) • 💡 [示例](./docs/GUIDES_CN.md) • ❓ [FAQ](#-faq)**
|
|
16
18
|
|
|
17
19
|
---
|
|
18
20
|
|
|
19
21
|
## 目录
|
|
20
22
|
|
|
21
|
-
1. [
|
|
22
|
-
2. [
|
|
23
|
-
3. [
|
|
24
|
-
4. [
|
|
25
|
-
5. [
|
|
26
|
-
6. [
|
|
27
|
-
7. [
|
|
23
|
+
1. [安装](#-安装)
|
|
24
|
+
2. [Playground](#-playground)
|
|
25
|
+
3. [快速开始](#-快速开始-30-秒)
|
|
26
|
+
4. [谁应该使用本库?](#-谁应该使用本库)
|
|
27
|
+
5. [为什么不直接用 Array 或 Map?](#-为什么不直接用-array-或-map)
|
|
28
|
+
6. [核心特性](#-核心特性)
|
|
29
|
+
7. [数据结构](#-可用的数据结构)
|
|
30
|
+
8. [文档](#-文档)
|
|
31
|
+
9. [FAQ](#-faq)
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 📦 安装
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm i data-structure-typed
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
yarn add data-structure-typed
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pnpm add data-structure-typed
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 子路径导入(支持 Tree-Shaking)
|
|
50
|
+
|
|
51
|
+
只导入你需要的 — 打包器会自动移除未使用的代码:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// 完整包 — 所有功能可用
|
|
55
|
+
import { RedBlackTree, Deque, HashMap } from 'data-structure-typed';
|
|
56
|
+
|
|
57
|
+
// 子路径 — 更小的包体积,只加载你需要的类别
|
|
58
|
+
import { RedBlackTree, TreeMap, AVLTree } from 'data-structure-typed/binary-tree';
|
|
59
|
+
import { Deque, Queue } from 'data-structure-typed/queue';
|
|
60
|
+
import { HashMap } from 'data-structure-typed/hash';
|
|
61
|
+
import { Heap, MinHeap } from 'data-structure-typed/heap';
|
|
62
|
+
import { Trie } from 'data-structure-typed/trie';
|
|
63
|
+
import { Stack } from 'data-structure-typed/stack';
|
|
64
|
+
import { DoublyLinkedList } from 'data-structure-typed/linked-list';
|
|
65
|
+
import { DirectedGraph } from 'data-structure-typed/graph';
|
|
66
|
+
import { Matrix } from 'data-structure-typed/matrix';
|
|
67
|
+
import { MinPriorityQueue } from 'data-structure-typed/priority-queue';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> **注意:** 使用 `"sideEffects": false` 和现代打包器(Vite、Webpack 5、Rollup),即使是完整导入 `from 'data-structure-typed'` 也会进行 tree-shake。子路径导入让你拥有明确的控制权和更快的 IDE 自动补全。
|
|
71
|
+
|
|
72
|
+
### 独立包
|
|
73
|
+
|
|
74
|
+
也提供独立的 NPM 包:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npm i avl-tree-typed bst-typed heap-typed
|
|
78
|
+
```
|
|
28
79
|
|
|
29
80
|
---
|
|
30
81
|
|
|
31
|
-
##
|
|
82
|
+
## 🎮 Playground
|
|
32
83
|
|
|
33
|
-
|
|
34
|
-
**考虑使用 `data-structure-typed` 而不是手工编写的 Array 或 Map。**
|
|
84
|
+
立即尝试:
|
|
35
85
|
|
|
36
|
-
|
|
86
|
+
- [Node.js TypeScript](https://stackblitz.com/github/zrwusa/dst-playgrounds/tree/main/apps/nodejs-ts?file=src%2Findex.ts&title=data-structure-typed%20%E2%80%94%20Node.js%20TypeScript)
|
|
87
|
+
- [Node.js JavaScript](https://stackblitz.com/github/zrwusa/dst-playgrounds/tree/main/apps/nodejs-js?file=src%2Findex.js&title=data-structure-typed%20%E2%80%94%20Node.js%20JavaScript)
|
|
88
|
+
- [React TypeScript](https://stackblitz.com/github/zrwusa/dst-playgrounds/tree/main/apps/reactjs?file=src%2FApp.tsx&title=data-structure-typed%20%E2%80%94%20React%20Playground)
|
|
89
|
+
- [NestJS](https://stackblitz.com/github/zrwusa/dst-playgrounds/tree/main/apps/nestjs?file=src%2Fproduct%2Fservices%2Fproduct-price-index.service.ts&title=data-structure-typed%20%E2%80%94%20NestJS%20Product%20API)
|
|
90
|
+
|
|
91
|
+
---
|
|
37
92
|
|
|
38
|
-
|
|
93
|
+
## 🎯 谁应该使用本库?
|
|
94
|
+
|
|
95
|
+
**如果你正在用 TypeScript 构建排名集合、调度队列或排序数据结构,**
|
|
96
|
+
**请考虑使用 `data-structure-typed` 而不是手工编写的 Array 或 Map。**
|
|
97
|
+
|
|
98
|
+
### 适用场景:
|
|
99
|
+
|
|
100
|
+
- **排行榜与排名** — 高效维护 top-K,无需重复排序
|
|
39
101
|
- **任务调度** — 优先级队列、有序执行、基于时间的操作
|
|
40
|
-
- **实时仪表板** — Grafana
|
|
41
|
-
- **时间序列数据** —
|
|
42
|
-
-
|
|
43
|
-
- **图论问题** —
|
|
102
|
+
- **实时仪表板** — Grafana 风格的工作负载,即时查询
|
|
103
|
+
- **时间序列数据** — 有序插入 + 快速范围查询
|
|
104
|
+
- **搜索与自动补全** — 大规模前缀匹配
|
|
105
|
+
- **图论问题** — 路径查找、环检测、拓扑排序
|
|
44
106
|
|
|
45
107
|
---
|
|
46
108
|
|
|
47
|
-
## ⚡ 为什么不直接用 Array 或 Map
|
|
109
|
+
## ⚡ 为什么不直接用 Array 或 Map?
|
|
48
110
|
|
|
49
111
|
| 使用场景 | Array | Map | data-structure-typed |
|
|
50
112
|
|------------------------|----------------------|------------------|:--------------------:|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
113
|
+
| **有序查找** | ❌ O(n) | ❌ 无序 | ✅ **O(log n)** |
|
|
114
|
+
| **指定位置插入** | ❌ O(n) shift | ❌ 无位置 | ✅ **O(log n)** |
|
|
115
|
+
| **排行榜 Top-K** | ❌ 重排序 O(n log n) | ❌ 手动排序 | ✅ **即时** |
|
|
116
|
+
| **从前端移除** | ❌ O(n) | ❌ 无出队 | ✅ **O(1)** |
|
|
55
117
|
| **前缀搜索** | ❌ O(n*m) | ❌ 不适用 | ✅ **O(m + k)** |
|
|
56
|
-
| **熟悉的 API** | ✅
|
|
118
|
+
| **熟悉的 API** | ✅ 有 | ✅ 有 | ✅ **相同** |
|
|
57
119
|
|
|
58
|
-
###
|
|
120
|
+
### 真实痛点
|
|
59
121
|
|
|
60
122
|
```javascript
|
|
61
123
|
// ❌ 不使用 data-structure-typed
|
|
62
|
-
const queue = [1, 2, 3, ..., 100000
|
|
124
|
+
const queue = [1, 2, 3, ..., 100000
|
|
125
|
+
]
|
|
126
|
+
;
|
|
63
127
|
for (let i = 0; i < 100000; i++) {
|
|
64
|
-
queue.shift(); // O(n) -
|
|
128
|
+
queue.shift(); // O(n) - 重新索引每个元素!
|
|
65
129
|
}
|
|
66
130
|
// 耗时: 2829ms ❌
|
|
67
131
|
```
|
|
68
132
|
|
|
69
133
|
```javascript
|
|
70
134
|
// ✅ 使用 data-structure-typed (Deque)
|
|
71
|
-
const deque = new Deque([1, 2, 3, ..., 100000])
|
|
135
|
+
const deque = new Deque([1, 2, 3, ..., 100000])
|
|
136
|
+
;
|
|
72
137
|
for (let i = 0; i < 100000; i++) {
|
|
73
|
-
deque.shift(); // O(1) -
|
|
138
|
+
deque.shift(); // O(1) - 只移动指针
|
|
74
139
|
}
|
|
75
140
|
// 耗时: 5.83ms ✅
|
|
76
|
-
//
|
|
141
|
+
// **快 484 倍!**
|
|
77
142
|
```
|
|
78
143
|
|
|
79
144
|
---
|
|
80
145
|
|
|
81
|
-
## 🚀 性能 (
|
|
146
|
+
## 🚀 性能 (TL;DR)
|
|
82
147
|
|
|
83
|
-
- **针对 V8
|
|
148
|
+
- **针对 V8 热路径优化** (查看 [PERFORMANCE_CN.md](./docs/PERFORMANCE_CN.md) 了解实测基准)
|
|
84
149
|
- 重复 Array.shift() O(n) → Deque O(1)
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
|
|
88
|
-
- **针对 V8 JIT 优化** (Node.js 18
|
|
89
|
-
|
|
90
|
-
- **Tree-shakable** ESM / CJS /
|
|
91
|
-
|
|
92
|
-
|
|
150
|
+
- 频繁更新 + 保持有序的工作流 → RedBlackTree O(log n) 操作
|
|
151
|
+
- 如果每次更新后都必须保持有序,避免重复 `Array.sort()`
|
|
152
|
+
|
|
153
|
+
- **针对 V8 JIT 优化** (Node.js 18+, 现代浏览器)
|
|
154
|
+
|
|
155
|
+
- **Tree-shakable** ESM / CJS / legacy 构建
|
|
156
|
+
|
|
157
|
+
[//]: # (No deletion!!! Start of README Performance Section)
|
|
158
|
+
|
|
159
|
+
| 数据结构 | 测试用例 | DST (ms) | Native (ms) | C++ (ms) | js-sdsl (ms) |
|
|
160
|
+
|----------------|-----------|----------|-------------|----------|---------------|
|
|
161
|
+
| Queue | 1M push | 26.93 | 23.83 | 1.70 | 27.59 |
|
|
162
|
+
| Deque | 1M push | 9.77 | 26.81 | 1.76 | 7.79 |
|
|
163
|
+
| DoublyLinkedList | 100k push | 5.70 | 2.40 | 5.70 | 1.90 |
|
|
164
|
+
| SinglyLinkedList | 100K unshift & shift | 3.77 | 1958.39 | 4.80 | - |
|
|
165
|
+
| PriorityQueue | 100K add | 4.00 | - | 1.05 | 4.96 |
|
|
166
|
+
| TreeSet | 1M add | 995.72 | - | 462.00 | 677.58 |
|
|
167
|
+
| TreeMap | 1M set | 978.72 | - | 512.00 | 623.23 |
|
|
168
|
+
| TreeMultiSet | 1M add (TreeMultiSet expanded iteration) | 217.73 | - | 752.00 | - |
|
|
169
|
+
| TreeMultiMap | 1M add (TreeMultiMap bucketed) | 366.19 | - | 731.00 | - |
|
|
170
|
+
| RedBlackTree | 1M get | 99.24 | - | 52.97 | - |
|
|
171
|
+
| BST | 10K add randomly | 5.50 | - | - | - |
|
|
172
|
+
| BinaryTree | 1K add randomly | 9.77 | - | - | - |
|
|
173
|
+
| HashMap | 1M set | 146.17 | 144.83 | 76.26 | 94.16 |
|
|
174
|
+
| Trie | 100K add | 141.10 | - | - | - |
|
|
175
|
+
| DirectedGraph | 1K addVertex | 0.05 | - | - | - |
|
|
176
|
+
| Stack | 1M push | 46.38 | 30.28 | 1.65 | 32.38 |
|
|
177
|
+
|
|
178
|
+
[//]: # (No deletion!!! End of README Performance Section)
|
|
179
|
+
|
|
180
|
+
📊 [完整基准测试 →](./docs/PERFORMANCE_CN.md) | [交互式报告 →](./docs/benchmark.html)
|
|
93
181
|
|
|
94
182
|
---
|
|
95
183
|
|
|
96
|
-
## ✨
|
|
184
|
+
## ✨ 核心特性
|
|
97
185
|
|
|
98
|
-
### 🏠
|
|
186
|
+
### 🏠 统一 API
|
|
99
187
|
|
|
100
|
-
|
|
188
|
+
无需学习新 API。到处都使用 `push`、`pop`、`map`、`filter` 和 `reduce`。
|
|
101
189
|
|
|
102
190
|
```javascript
|
|
103
191
|
// 所有线性结构使用相同的 4 个方法
|
|
@@ -106,10 +194,10 @@ const queue = new Queue([1, 2, 3]);
|
|
|
106
194
|
const doublyLinkeList = new DoublyLinkedList([1, 2, 3]);
|
|
107
195
|
const singlyLinkedList = new SinglyLinkedList([1, 2, 3]);
|
|
108
196
|
|
|
109
|
-
//
|
|
197
|
+
// 它们都支持:
|
|
110
198
|
structure.push(item); // 添加到末尾
|
|
111
|
-
structure.pop(); //
|
|
112
|
-
structure.shift(); //
|
|
199
|
+
structure.pop(); // 从末尾移除
|
|
200
|
+
structure.shift(); // 从开头移除
|
|
113
201
|
structure.unshift(item); // 添加到开头
|
|
114
202
|
```
|
|
115
203
|
|
|
@@ -128,94 +216,138 @@ const value = tree.get(1); // 类型: string | undefined
|
|
|
128
216
|
|
|
129
217
|
### ✨ 零摩擦
|
|
130
218
|
|
|
131
|
-
|
|
219
|
+
随处可用。展开它 `[...]`,循环它 `for..of`,即时转换。使用 `toEntryFn`/`toElementFn` 传入原始数据 — 无需预处理。
|
|
132
220
|
|
|
133
221
|
```javascript
|
|
134
222
|
// 所有数据结构都支持迭代器协议
|
|
135
223
|
const tree = new RedBlackTree([5, 2, 8]);
|
|
136
|
-
const sorted = [...tree]; //
|
|
224
|
+
const sorted = [...tree]; // 展开运算符
|
|
137
225
|
for (const item of tree) {
|
|
138
226
|
} // for...of 循环
|
|
139
227
|
const set = new Set(tree); // Set 构造器
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
---
|
|
143
228
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
pnpm add data-structure-typed
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
npm i data-structure-typed --save
|
|
229
|
+
// 直接传入原始数据
|
|
230
|
+
const map = new TreeMap(users, { toEntryFn: u => [u.id, u.name] });
|
|
152
231
|
```
|
|
153
232
|
|
|
154
|
-
|
|
155
|
-
yarn add data-structure-typed
|
|
156
|
-
```
|
|
233
|
+
### 🔄 处理原始数据
|
|
157
234
|
|
|
158
|
-
|
|
235
|
+
有原始对象?三种使用方式 — 根据你想存储的内容选择:
|
|
159
236
|
|
|
160
|
-
|
|
237
|
+
```typescript
|
|
238
|
+
interface User {
|
|
239
|
+
id: number;
|
|
240
|
+
name: string;
|
|
241
|
+
}
|
|
161
242
|
|
|
162
|
-
|
|
163
|
-
|
|
243
|
+
const users: User[] = [
|
|
244
|
+
{ id: 3, name: 'Charlie' },
|
|
245
|
+
{ id: 1, name: 'Alice' },
|
|
246
|
+
{ id: 2, name: 'Bob' }
|
|
247
|
+
];
|
|
248
|
+
|
|
249
|
+
// 1. 提取字段 — 仅存储该字段
|
|
250
|
+
const ids = new TreeSet<number, User>(
|
|
251
|
+
users,
|
|
252
|
+
{ toElementFn: u => u.id }
|
|
253
|
+
);
|
|
254
|
+
// [1, 2, 3] — 仅数字,不保留原始对象
|
|
255
|
+
|
|
256
|
+
// 2. 存储完整对象 — 按字段排序
|
|
257
|
+
const fullSet = new TreeSet<User>(
|
|
258
|
+
users,
|
|
259
|
+
{ comparator: (a, b) => a.id - b.id }
|
|
260
|
+
);
|
|
261
|
+
// [{ id: 1, name: 'Alice' }, { id: 2, ... }, { id: 3, ... }]
|
|
262
|
+
|
|
263
|
+
// 3. 拆分为键值对 — 字段作为键,任意值
|
|
264
|
+
const map = new TreeMap<number, User, User>(
|
|
265
|
+
users,
|
|
266
|
+
{ toEntryFn: u => [u.id, u] }
|
|
267
|
+
);
|
|
268
|
+
// map.get(1) → { id: 1, name: 'Alice' }
|
|
164
269
|
```
|
|
165
270
|
|
|
271
|
+
适用于所有数据结构 — 单值类型使用 `toElementFn` (Heap、Queue、Stack、LinkedList、Trie),键值类型使用 `toEntryFn` (TreeMap、HashMap、SkipList),任何排序结构使用 `comparator`。
|
|
272
|
+
|
|
166
273
|
---
|
|
167
274
|
|
|
168
|
-
## 💡
|
|
275
|
+
## 💡 我应该何时考虑本库?
|
|
169
276
|
|
|
170
|
-
✅
|
|
277
|
+
✅ **当你需要:**
|
|
171
278
|
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
279
|
+
- Top-K / 排行榜查询而无需重复排序
|
|
280
|
+
- 同时实现插入顺序 + 查找性能
|
|
281
|
+
- 带快速位置访问的优先级队列
|
|
175
282
|
- 支持范围查询的时间序列数据
|
|
176
|
-
-
|
|
283
|
+
- Red-Black Tree / Heap 性能而无需学习新 API
|
|
284
|
+
- **直接传入原始对象** — 无需 `.map()` 预处理(JS/TS 中本库独有)
|
|
177
285
|
|
|
178
|
-
✅
|
|
286
|
+
✅ **当你的代码有:**
|
|
179
287
|
|
|
180
|
-
-
|
|
288
|
+
- 热路径中的 `array.sort()`(请求处理器、循环)
|
|
181
289
|
- 插入后的手动索引跟踪
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
290
|
+
- 大列表上的 `Array.shift()`(队列)
|
|
291
|
+
- 跨文件重复的自定义排序逻辑
|
|
292
|
+
- 需要有序的 Map
|
|
293
|
+
- 仅为重塑数据才调用 `.map()`,然后放入集合
|
|
185
294
|
|
|
186
295
|
---
|
|
187
296
|
|
|
188
|
-
## 🚀
|
|
297
|
+
## 🚀 快速开始: 30 秒
|
|
189
298
|
|
|
190
|
-
###
|
|
299
|
+
### 排行榜(排名集合)
|
|
191
300
|
|
|
192
301
|
```typescript
|
|
193
302
|
import { RedBlackTree } from 'data-structure-typed';
|
|
194
303
|
|
|
195
|
-
|
|
304
|
+
// 降序比较器 — 最高分在前
|
|
305
|
+
const leaderboard = new RedBlackTree<number, string>([
|
|
196
306
|
[100, 'Alice'],
|
|
197
307
|
[85, 'Bob'],
|
|
198
308
|
[92, 'Charlie']
|
|
199
|
-
]);
|
|
309
|
+
], { comparator: (a, b) => b - a });
|
|
200
310
|
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
205
|
-
// 输出:
|
|
206
|
-
// Alice: 100
|
|
207
|
-
// Charlie: 92
|
|
208
|
-
// Bob: 85
|
|
311
|
+
// 通过惰性迭代器获取 Top-2 — O(k log n),无数组拷贝
|
|
312
|
+
const iter = leaderboard.entries();
|
|
313
|
+
const { value: [topScore, topPlayer] } = iter.next();
|
|
314
|
+
console.log(`${topScore}: ${topPlayer}`); // 100: Alice
|
|
209
315
|
|
|
210
|
-
// 更新分数
|
|
316
|
+
// 更新分数 — O(log n)
|
|
211
317
|
leaderboard.delete(85);
|
|
212
|
-
leaderboard.set(95, 'Bob');
|
|
318
|
+
leaderboard.set(95, 'Bob');
|
|
319
|
+
|
|
320
|
+
// 范围查询 — 分数 90~100 的玩家, O(log n + k)
|
|
321
|
+
const scores90to100 = leaderboard.rangeSearch([90, 100]);
|
|
322
|
+
// [100, 95, 92] — 自动遵循树的顺序
|
|
323
|
+
|
|
324
|
+
// 对于 O(log n) top-k、排名和分页 → 参见下面的 Order-Statistic Tree
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Order-Statistic Tree(排名查询)
|
|
328
|
+
|
|
329
|
+
```typescript
|
|
330
|
+
import { RedBlackTree } from 'data-structure-typed';
|
|
331
|
+
|
|
332
|
+
const tree = new RedBlackTree<number, string>([
|
|
333
|
+
[100, 'Alice'], [85, 'Bob'], [92, 'Charlie'],
|
|
334
|
+
[78, 'Diana'], [95, 'Eve']
|
|
335
|
+
], { comparator: (a, b) => b - a, enableOrderStatistic: true });
|
|
336
|
+
|
|
337
|
+
// select(k) — 查找第 k 个元素, O(log n)
|
|
338
|
+
tree.getByRank(0); // 100 (树顺序的第 1 个)
|
|
339
|
+
tree.getByRank(2); // 92 (树顺序的第 3 个)
|
|
340
|
+
|
|
341
|
+
// rank(key) — 统计树顺序中 key 之前的元素数量, O(log n)
|
|
342
|
+
tree.getRank(92); // 2 (树顺序中 92 之前有 2 个元素)
|
|
213
343
|
|
|
214
|
-
//
|
|
215
|
-
|
|
344
|
+
// rangeByRank — 分页, O(log n + k)
|
|
345
|
+
tree.rangeByRank(0, 2); // [100, 95, 92] — 前 3 个
|
|
346
|
+
|
|
347
|
+
// 也适用于 TreeMap、TreeSet、TreeMultiMap、TreeMultiSet
|
|
216
348
|
```
|
|
217
349
|
|
|
218
|
-
###
|
|
350
|
+
### 任务队列(调度)
|
|
219
351
|
|
|
220
352
|
```typescript
|
|
221
353
|
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
@@ -227,7 +359,25 @@ const taskQueue = new MaxPriorityQueue<{priority: number; task: string}>([], {
|
|
|
227
359
|
taskQueue.add({ priority: 5, task: 'Email' });
|
|
228
360
|
taskQueue.add({ priority: 9, task: 'Alert' }); // 即时优先级处理
|
|
229
361
|
|
|
230
|
-
const nextTask = taskQueue.
|
|
362
|
+
const nextTask = taskQueue.pop(); // { priority: 9, task: 'Alert' }
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### 集合操作 (ES2025)
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
import { TreeSet } from 'data-structure-typed';
|
|
369
|
+
|
|
370
|
+
const a = new TreeSet([1, 2, 3, 4, 5]);
|
|
371
|
+
const b = new TreeSet([3, 4, 5, 6, 7]);
|
|
372
|
+
|
|
373
|
+
[...a.union(b)]; // [1,2,3,4,5,6,7]
|
|
374
|
+
[...a.intersection(b)]; // [3,4,5]
|
|
375
|
+
[...a.difference(b)]; // [1,2]
|
|
376
|
+
[...a.symmetricDifference(b)]; // [1,2,6,7]
|
|
377
|
+
a.isSubsetOf(b); // false
|
|
378
|
+
|
|
379
|
+
// 支持任意 Iterable — 原生 Set、数组、生成器
|
|
380
|
+
a.intersection(new Set([2, 4, 6])); // TreeSet [2, 4]
|
|
231
381
|
```
|
|
232
382
|
|
|
233
383
|
### 快速队列 (FIFO)
|
|
@@ -236,74 +386,303 @@ const nextTask = taskQueue.poll(); // { priority: 9, task: 'Alert' }
|
|
|
236
386
|
import { Deque } from 'data-structure-typed';
|
|
237
387
|
|
|
238
388
|
const queue = new Deque([1, 2, 3, 4, 5]);
|
|
239
|
-
queue.shift(); //
|
|
240
|
-
queue.push(6); //
|
|
389
|
+
queue.shift(); // 从前端移除: O(1) 而非 O(n)
|
|
390
|
+
queue.push(6); // 添加到后端: O(1)
|
|
241
391
|
```
|
|
242
392
|
|
|
243
393
|
---
|
|
244
394
|
|
|
245
395
|
## 📊 可用的数据结构
|
|
246
396
|
|
|
247
|
-
| 结构
|
|
248
|
-
|
|
249
|
-
| **
|
|
250
|
-
| **
|
|
251
|
-
| **
|
|
252
|
-
| **
|
|
253
|
-
| **
|
|
254
|
-
| **
|
|
255
|
-
| **
|
|
256
|
-
| **
|
|
257
|
-
| **
|
|
258
|
-
| **
|
|
259
|
-
| **
|
|
397
|
+
| 结构 | 使用场景 | 时间复杂度 | NPM |
|
|
398
|
+
|--------------------------|-----------------------------------|-----------------|-----------------------------------------------------------|
|
|
399
|
+
| **RedBlackTree** | 有序集合、范围查询 | O(log n) | [npm](https://www.npmjs.com/package/red-black-tree-typed) |
|
|
400
|
+
| **Heap / PriorityQueue** | 任务调度、top-K 元素 | O(log n) | [npm](https://www.npmjs.com/package/heap-typed) |
|
|
401
|
+
| **Deque** | 快速前后操作 | O(1) | [npm](https://www.npmjs.com/package/deque-typed) |
|
|
402
|
+
| **Trie** | 自动补全、前缀搜索 | O(m+k) | [npm](https://www.npmjs.com/package/trie-typed) |
|
|
403
|
+
| **DirectedGraph** | 路径查找、DAG 算法 | O(V+E) | [npm](https://www.npmjs.com/package/directed-graph-typed) |
|
|
404
|
+
| **Stack** | 撤销/重做、表达式解析 | O(1) | [npm](https://www.npmjs.com/package/stack-typed) |
|
|
405
|
+
| **LinkedList** | 动态大小、无索引移位 | O(1)* | [npm](https://www.npmjs.com/package/linked-list-typed) |
|
|
406
|
+
| **AVLTree** | 比 RB-Tree 更严格的平衡 | O(log n) | [npm](https://www.npmjs.com/package/avl-tree-typed) |
|
|
407
|
+
| **SkipList** | 有序 KV、TreeMap 替代 | O(log n) avg | — |
|
|
408
|
+
| **SegmentTree** | 范围 sum/min/max/自定义查询 | O(log n) | — |
|
|
409
|
+
| **BinaryIndexedTree** | 前缀和、频率计数 | O(log n) | — |
|
|
410
|
+
| **Matrix** | 2D 网格运算 | O(n²) add | — |
|
|
411
|
+
|
|
412
|
+
👉 [查看全部 20+ 结构 →](./docs/OVERVIEW_CN.md) | [完整 API 文档 →](https://data-structure-typed-docs.vercel.app/)
|
|
260
413
|
|
|
261
414
|
---
|
|
262
415
|
|
|
263
|
-
##
|
|
416
|
+
## 📖 文档
|
|
417
|
+
|
|
418
|
+
### 不同使用场景
|
|
419
|
+
|
|
420
|
+
| 你的目标 | 从这里开始 | 下一步 |
|
|
421
|
+
|---------------------------|-------------------------------------------|-----------------------------------------|
|
|
422
|
+
| **学习概念** | [CONCEPTS_CN.md](./docs/CONCEPTS_CN.md) | [GUIDES_CN.md](./docs/GUIDES_CN.md) |
|
|
423
|
+
| **在项目中使用** | [GUIDES_CN.md](./docs/GUIDES_CN.md) | [OVERVIEW_CN.md](./docs/OVERVIEW_CN.md) |
|
|
424
|
+
| **查找 API** | [API 文档](https://data-structure-typed-docs.vercel.app/) | [PERFORMANCE_CN.md](./docs/PERFORMANCE_CN.md) |
|
|
425
|
+
| **性能问题** | [PERFORMANCE_CN.md](./docs/PERFORMANCE_CN.md) | [ARCHITECTURE_CN.md](./docs/ARCHITECTURE_CN.md) |
|
|
426
|
+
| **框架集成** | [INTEGRATIONS_CN.md](./docs/INTEGRATIONS_CN.md) | [GUIDES_CN.md](./docs/GUIDES_CN.md) |
|
|
427
|
+
| **理解设计** | [ARCHITECTURE_CN.md](./docs/ARCHITECTURE_CN.md) | [CONCEPTS_CN.md](./docs/CONCEPTS_CN.md) |
|
|
428
|
+
|
|
429
|
+
### 文档文件
|
|
430
|
+
|
|
431
|
+
1. **[CONCEPTS_CN.md](./docs/CONCEPTS_CN.md)** - 核心基础与理论
|
|
432
|
+
- 三大核心概念 (BST、平衡树、Heap)
|
|
433
|
+
- 13 个通俗语言解释
|
|
434
|
+
- 迭代器协议设计
|
|
435
|
+
- 5 个与原生 JavaScript 的对比
|
|
436
|
+
- 完整决策指南
|
|
437
|
+
|
|
438
|
+
2. **[API 文档](https://data-structure-typed-docs.vercel.app/)** - 完整 API 参考 (TypeDoc)
|
|
439
|
+
- 完整的方法签名、参数、返回类型
|
|
440
|
+
- 每个方法的真实 `@example` 代码
|
|
441
|
+
- 继承层次和类型详情
|
|
442
|
+
|
|
443
|
+
3. **[OVERVIEW_CN.md](./docs/OVERVIEW_CN.md)** - 数据结构概览
|
|
444
|
+
- 快速参考表
|
|
445
|
+
- 全部 20+ 结构及示例
|
|
446
|
+
- CRUD 操作
|
|
447
|
+
- 常用方法
|
|
448
|
+
- TypeScript 支持
|
|
449
|
+
|
|
450
|
+
4. **[ARCHITECTURE_CN.md](./docs/ARCHITECTURE_CN.md)** - 设计与实现
|
|
451
|
+
- 设计理念与原则
|
|
452
|
+
- 解决的 3 大痛点
|
|
453
|
+
- 为什么 Deque 快 484 倍
|
|
454
|
+
- 迭代器协议设计
|
|
455
|
+
- 自平衡策略
|
|
456
|
+
- V8 JIT 优化
|
|
457
|
+
|
|
458
|
+
5. **[PERFORMANCE_CN.md](./docs/PERFORMANCE_CN.md)** - 基准测试与对比
|
|
459
|
+
- 性能总结
|
|
460
|
+
- 3 个真实场景
|
|
461
|
+
- 详细基准测试
|
|
462
|
+
- 何时使用什么
|
|
463
|
+
- 优化技巧
|
|
464
|
+
|
|
465
|
+
6. **[GUIDES_CN.md](./docs/GUIDES_CN.md)** - 真实案例
|
|
466
|
+
- 4 种设计模式
|
|
467
|
+
- 5 个生产代码示例
|
|
468
|
+
- 常见错误
|
|
469
|
+
- 最佳实践
|
|
470
|
+
|
|
471
|
+
7. **[INTEGRATIONS_CN.md](./docs/INTEGRATIONS_CN.md)** - 框架集成
|
|
472
|
+
- React 集成 (状态管理、排行榜)
|
|
473
|
+
- Express 集成 (LRU 缓存、限流)
|
|
474
|
+
- Nest.js 集成 (排名服务、任务队列)
|
|
475
|
+
- TypeScript 配置
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## 💻 真实案例
|
|
480
|
+
|
|
481
|
+
### LRU 缓存
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
class LRUCache<K, V> {
|
|
485
|
+
private cache = new Map<K, V>();
|
|
486
|
+
private order = new DoublyLinkedList<K>();
|
|
487
|
+
|
|
488
|
+
get(key: K): V | null {
|
|
489
|
+
if (!this.cache.has(key)) return null;
|
|
490
|
+
// 移到末尾 (最近使用)
|
|
491
|
+
// 利用 O(1) 操作实现高效
|
|
492
|
+
return this.cache.get(key)!;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### 排行榜
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
|
|
501
|
+
type Player = {
|
|
502
|
+
id: string;
|
|
503
|
+
name: string;
|
|
504
|
+
score: number;
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const seedPlayers: Player[] = [
|
|
508
|
+
{ id: 'player_01HZX4E8Q2K8Y3J9M7T1A6B3C4', name: 'Pablo', score: 65 },
|
|
509
|
+
{ id: 'player_01HZX4E9R6V2D8K1P0N5S4T7U8', name: 'Bunny', score: 10 },
|
|
510
|
+
{ id: 'player_01HZX4EA3M9Q7W1E2R8T6Y5U0I', name: 'Jeff', score: 99 },
|
|
511
|
+
];
|
|
512
|
+
|
|
513
|
+
class ScoreLeaderboard {
|
|
514
|
+
private readonly byScore: RedBlackTree<number, Player, Player>;
|
|
515
|
+
|
|
516
|
+
constructor(initialPlayers: Player[]) {
|
|
517
|
+
this.byScore = new RedBlackTree<number, Player, Player>(initialPlayers, {
|
|
518
|
+
isMapMode: false,// 使用"节点值"存储而非 Map 风格。
|
|
519
|
+
toEntryFn: (player) => [player.score, player], // 将玩家对象转换为树条目: key = score, value = player.
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* 返回分数在给定范围内的玩家。
|
|
525
|
+
* 支持元组 [min, max] 或 Range 对象以实现包含/排除边界。
|
|
526
|
+
*/
|
|
527
|
+
public findPlayersByScoreRange(range: [number, number] | Range<number>): (Player | undefined)[] {
|
|
528
|
+
return this.byScore.rangeSearch(range, (node) => node.value);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
public upsertPlayer(player: Player) {
|
|
532
|
+
return this.byScore.set(player.score, player);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
const leaderboard = new ScoreLeaderboard(seedPlayers);
|
|
537
|
+
|
|
538
|
+
console.log(leaderboard.findPlayersByScoreRange([65, 100]));
|
|
539
|
+
|
|
540
|
+
leaderboard.upsertPlayer({
|
|
541
|
+
id: 'player_01HZX4EB7C4N2M9Q8R1T3Y6U5I',
|
|
542
|
+
name: 'Alex',
|
|
543
|
+
score: 80,
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
console.log(leaderboard.findPlayersByScoreRange(new Range(65, 100, true, true)));
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### 消息队列
|
|
550
|
+
|
|
551
|
+
```typescript
|
|
552
|
+
type Message = {
|
|
553
|
+
id: string;
|
|
554
|
+
type: string;
|
|
555
|
+
payload: unknown;
|
|
556
|
+
priority: 'urgent' | 'normal';
|
|
557
|
+
createdAt: number;
|
|
558
|
+
retryCount?: number;
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
class MessageQueue {
|
|
562
|
+
private urgent = new Deque<Message>();
|
|
563
|
+
private normal = new Deque<Message>();
|
|
564
|
+
|
|
565
|
+
dequeue(): Message | null {
|
|
566
|
+
return this.urgent.shift() || this.normal.shift();
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
```
|
|
264
570
|
|
|
265
|
-
|
|
571
|
+
👉 [更多示例在 GUIDES_CN.md](./docs/GUIDES_CN.md)
|
|
266
572
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
573
|
+
---
|
|
574
|
+
|
|
575
|
+
## 🎯 行业使用场景
|
|
576
|
+
|
|
577
|
+
### 📊 金融
|
|
578
|
+
|
|
579
|
+
- 价格排序的订单簿
|
|
580
|
+
- 实时投资组合排名
|
|
581
|
+
- 期权链排序
|
|
582
|
+
|
|
583
|
+
### 🎮 游戏
|
|
584
|
+
|
|
585
|
+
- 玩家排行榜
|
|
586
|
+
- 敌人优先级队列
|
|
587
|
+
- 游戏事件调度
|
|
588
|
+
|
|
589
|
+
### 📱 社交媒体
|
|
590
|
+
|
|
591
|
+
- 热门帖子 (top-K)
|
|
592
|
+
- 信息流排序
|
|
593
|
+
- 通知调度
|
|
594
|
+
|
|
595
|
+
### 🏥 医疗
|
|
596
|
+
|
|
597
|
+
- 患者优先级队列
|
|
598
|
+
- 预约调度
|
|
599
|
+
- 医疗记录组织
|
|
271
600
|
|
|
272
|
-
###
|
|
601
|
+
### 🛒 电商
|
|
273
602
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
603
|
+
- 产品价格范围
|
|
604
|
+
- 库存管理
|
|
605
|
+
- 订单调度
|
|
277
606
|
|
|
278
607
|
---
|
|
279
608
|
|
|
609
|
+
## ✨ 开发者喜爱的原因
|
|
610
|
+
|
|
611
|
+
| 痛点 | 解决方案 |
|
|
612
|
+
|------------------------------------|-------------------------------------------|
|
|
613
|
+
| 重复排序拖慢代码 | TreeSet 自动维护顺序 |
|
|
614
|
+
| 循环中 Array.shift 超时 | Deque O(1) shift 而非 O(n) |
|
|
615
|
+
| 学习不同 API | 所有结构都使用 push/pop/shift/unshift |
|
|
616
|
+
| 类型安全噩梦 | 完整 TypeScript 泛型支持 |
|
|
617
|
+
| 浏览器兼容性问题 | 随处可用: Node、浏览器、CDN |
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## 📦 你将获得
|
|
622
|
+
|
|
623
|
+
✅ **20+ 数据结构** (生产就绪)
|
|
624
|
+
✅ **50+ 代码示例** (真实模式)
|
|
625
|
+
✅ **完整 TypeScript 支持** (严格类型)
|
|
626
|
+
✅ **性能基准测试** (484 倍加速)
|
|
627
|
+
✅ **框架集成** (React、Express、Nest.js)
|
|
628
|
+
✅ **6 个核心文档文件** (2500+ 行)
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## 🚀 开始使用
|
|
633
|
+
|
|
634
|
+
### 步骤 1: 安装
|
|
635
|
+
|
|
636
|
+
```bash
|
|
637
|
+
npm i data-structure-typed
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### 步骤 2: 导入
|
|
641
|
+
|
|
642
|
+
```typescript
|
|
643
|
+
import { RedBlackTree, Deque, MaxPriorityQueue } from 'data-structure-typed';
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
### 步骤 3: 使用
|
|
647
|
+
|
|
648
|
+
```typescript
|
|
649
|
+
const tree = new RedBlackTree([5, 2, 8]);
|
|
650
|
+
console.log([...tree]); // [2, 5, 8] - 自动排序!
|
|
651
|
+
```
|
|
652
|
+
|
|
280
653
|
## 📊 对比图表
|
|
281
654
|
|
|
282
655
|
```
|
|
283
|
-
|
|
656
|
+
需要频繁头/尾操作?
|
|
284
657
|
→ Deque (O(1) shift/unshift/push/pop)
|
|
285
658
|
|
|
286
|
-
需要排序 +
|
|
659
|
+
需要排序 + 快速查找?
|
|
287
660
|
→ RedBlackTree (O(log n) 保证)
|
|
288
661
|
|
|
289
|
-
|
|
290
|
-
→ Heap/PriorityQueue (O(log n)
|
|
662
|
+
需要最高/最低优先级?
|
|
663
|
+
→ Heap/PriorityQueue (O(log n) add/remove)
|
|
291
664
|
|
|
292
|
-
|
|
665
|
+
需要前缀/文本匹配?
|
|
293
666
|
→ Trie (O(m+k) 其中 m=前缀)
|
|
294
667
|
|
|
295
|
-
|
|
668
|
+
需要图论操作?
|
|
296
669
|
→ DirectedGraph/UndirectedGraph
|
|
297
670
|
|
|
298
|
-
|
|
299
|
-
→
|
|
671
|
+
需要数组上的范围查询 (sum/min/max)?
|
|
672
|
+
→ SegmentTree (任意合并操作) 或 BinaryIndexedTree (仅前缀和)
|
|
673
|
+
|
|
674
|
+
需要有序键值对且 API 与 TreeMap 相同?
|
|
675
|
+
→ SkipList (O(log n) avg, 概率平衡)
|
|
676
|
+
|
|
677
|
+
否则?
|
|
678
|
+
→ 使用 Array (最简单的情况)
|
|
300
679
|
```
|
|
301
680
|
|
|
302
681
|
---
|
|
303
682
|
|
|
304
683
|
## 🤝 贡献
|
|
305
684
|
|
|
306
|
-
|
|
685
|
+
发现 bug?有建议? [提出 issue](https://github.com/zrwusa/data-structure-typed/issues)
|
|
307
686
|
|
|
308
687
|
---
|
|
309
688
|
|
|
@@ -319,34 +698,81 @@ MIT
|
|
|
319
698
|
README.md (本文件)
|
|
320
699
|
docs/
|
|
321
700
|
├── CONCEPTS_CN.md (理论与基础)
|
|
322
|
-
├──
|
|
701
|
+
├── OVERVIEW_CN.md (数据结构概览)
|
|
323
702
|
├── ARCHITECTURE_CN.md (设计原则)
|
|
324
|
-
├── ARCHITECTURE_CN.md (设计细节)
|
|
325
703
|
├── PERFORMANCE_CN.md (基准测试)
|
|
326
|
-
├──
|
|
327
|
-
|
|
328
|
-
├── INTEGRATIONS_CN.md (框架指南)
|
|
329
|
-
└── INTEGRATIONS_CN.md (完整集成)
|
|
704
|
+
├── GUIDES_CN.md (真实案例)
|
|
705
|
+
└── INTEGRATIONS_CN.md (框架指南)
|
|
330
706
|
```
|
|
331
707
|
|
|
332
708
|
---
|
|
333
709
|
|
|
334
710
|
## 🎓 了解更多
|
|
335
711
|
|
|
336
|
-
|
|
712
|
+
**刚开始?** → [快速开始](#-快速开始-30-秒)
|
|
337
713
|
|
|
338
|
-
|
|
714
|
+
**需要概念?** → [CONCEPTS_CN.md](./docs/CONCEPTS_CN.md)
|
|
339
715
|
|
|
340
|
-
|
|
716
|
+
**想构建?** → [GUIDES_CN.md](./docs/GUIDES_CN.md)
|
|
341
717
|
|
|
342
|
-
**需要 API
|
|
718
|
+
**需要 API?** → [API 文档](https://data-structure-typed-docs.vercel.app/) | [概览](./docs/OVERVIEW_CN.md)
|
|
343
719
|
|
|
344
|
-
|
|
720
|
+
**关心性能?** → [PERFORMANCE_CN.md](./docs/PERFORMANCE_CN.md)
|
|
345
721
|
|
|
346
|
-
|
|
722
|
+
**框架问题?** → [INTEGRATIONS_CN.md](./docs/INTEGRATIONS_CN.md)
|
|
347
723
|
|
|
348
|
-
|
|
724
|
+
---
|
|
725
|
+
|
|
726
|
+
**准备好加速你的 TypeScript 数据结构了吗? [现在开始 →](#-快速开始-30-秒)**
|
|
349
727
|
|
|
350
728
|
---
|
|
351
729
|
|
|
352
|
-
|
|
730
|
+
## ❓ FAQ
|
|
731
|
+
|
|
732
|
+
### JavaScript 有 TreeMap 或 TreeSet 吗?
|
|
733
|
+
|
|
734
|
+
原生没有。JavaScript 的 `Map` 和 `Set` 是基于哈希的(无序)。本库提供由 Red-Black Tree 支持的 `TreeMap` 和 `TreeSet` — 提供有序迭代、`floor`/`ceiling`/`higher`/`lower` 查找,以及 `getRank`/`getByRank`/`rangeByRank` 查询。
|
|
735
|
+
|
|
736
|
+
### 何时应该使用 Heap 而不是排序数组?
|
|
737
|
+
|
|
738
|
+
当你需要重复访问最小或最大元素时。排序数组每次都是 O(n log n); Heap 提供 O(log n) 插入和 O(1) 访问顶部元素。对于优先级队列、top-k 问题和调度,使用 `Heap`、`MinHeap` 或 `MaxHeap`。
|
|
739
|
+
|
|
740
|
+
### 本库支持排名和范围查询吗?
|
|
741
|
+
|
|
742
|
+
是的。在任何基于树的结构(RedBlackTree、TreeMap、TreeSet 等)上启用 `{ enableOrderStatistic: true }`:
|
|
743
|
+
- `getRank(key)` — 树顺序中这个 key 之前有多少元素
|
|
744
|
+
- `getByRank(k)` — 获取位置 k 的元素
|
|
745
|
+
- `rangeByRank(start, end)` — 获取两个位置之间的所有元素
|
|
746
|
+
|
|
747
|
+
### 对于有序操作,它比原生数组快吗?
|
|
748
|
+
|
|
749
|
+
对于有序插入 + 查找: 是的。数组插入到有序位置是 O(n) (移动元素)。Red-Black Tree 插入是 O(log n)。对于 10,000+ 元素,差异显著。查看 [PERFORMANCE_CN.md](./docs/PERFORMANCE_CN.md) 了解基准测试。
|
|
750
|
+
|
|
751
|
+
### 我可以在 React / Node.js / 浏览器中使用吗?
|
|
752
|
+
|
|
753
|
+
可以。本库提供 ESM、CJS 和 UMD 构建。它可在 Node.js、浏览器、React、Vue、Angular、Next.js 和任何 JavaScript 运行时中使用。零依赖意味着无兼容性问题。
|
|
754
|
+
|
|
755
|
+
### 包含哪些数据结构?
|
|
756
|
+
|
|
757
|
+
Heap、MinHeap、MaxHeap、Priority Queue、Deque、Queue、Stack、Linked List (Singly / Doubly)、Red-Black Tree、AVL Tree、BST、TreeMap、TreeSet、TreeMultiMap、TreeMultiSet、SkipList、Trie、HashMap、Graph (Directed / Undirected)、Segment Tree、Binary Indexed Tree (Fenwick Tree)、Matrix。查看[完整列表](#-可用的数据结构)。
|
|
758
|
+
|
|
759
|
+
### 本库生产就绪吗?
|
|
760
|
+
|
|
761
|
+
是的。2600+ 测试,99%+ 代码覆盖率,零依赖,并在生产环境中使用。每次发布都通过类型检查、lint 和完整测试套件。
|
|
762
|
+
|
|
763
|
+
### 与 js-sdsl 或其他库相比如何?
|
|
764
|
+
|
|
765
|
+
`data-structure-typed` 提供更多数据结构(20+)、跨所有结构的统一类似 Array 的 API、tree-shakeable 子路径导出和积极维护。查看 [PERFORMANCE_CN.md](./docs/PERFORMANCE_CN.md) 了解基准对比。
|
|
766
|
+
|
|
767
|
+
### 我可以在不先转换的情况下传入原始数据吗?
|
|
768
|
+
|
|
769
|
+
可以。三种模式:
|
|
770
|
+
- **`toElementFn`** — 提取字段,仅存储该字段 (TreeSet、Heap、Queue、Stack、LinkedList、Trie)
|
|
771
|
+
- **`comparator`** — 存储完整对象,按字段排序 (所有排序结构)
|
|
772
|
+
- **`toEntryFn`** — 拆分为键值对 (TreeMap、HashMap、SkipList)
|
|
773
|
+
|
|
774
|
+
查看[原始数据部分](#-处理原始数据)了解示例。
|
|
775
|
+
|
|
776
|
+
### 包体积是多少?
|
|
777
|
+
|
|
778
|
+
UMD bundle: ~143KB minified。使用子路径导入(如 `data-structure-typed/heap`),你只加载需要的 — Stack 小至 18KB,Heap 30KB。`sideEffects: false` 启用完整 tree-shaking。
|