# data-structure-typed ![npm](https://img.shields.io/npm/v/data-structure-typed) ![npm](https://img.shields.io/npm/dm/data-structure-typed) ![npm package minimized gzipped size (select exports)](https://img.shields.io/bundlejs/size/data-structure-typed) ![GitHub top language](https://img.shields.io/github/languages/top/zrwusa/data-structure-typed) ![eslint](https://aleen42.github.io/badges/src/eslint.svg) ![NPM](https://img.shields.io/npm/l/data-structure-typed) [//]: # (![npm bundle size](https://img.shields.io/bundlephobia/min/data-structure-typed))

English | 简体中文

## 为什么 JavaScript和TypeScript的数据结构。 是否羡慕C++ [STL]() (std::)、Python的 [collections]() 和Java的 [java.util]()? 不再需要羡慕了!JavaScript和TypeScript现在拥有 [data-structure-typed]()。 **`基准测试`** 与C++ STL相比。**`API 标准`** 与ES6和Java对齐。**`易用性`** 可与Python媲美。 ### 提供了JS/TS中没有的数据结构 Heap, Binary Tree, RedBlack Tree, Linked List, Deque, Trie, Directed Graph, Undirected Graph, BST, AVL Tree, Priority Queue, Queue, Tree Multiset, Linked List. ### 性能超越原生JS/TS
方法名 耗时(毫秒) 数据规模 所属标准库
Queue.push & shift 5.83 100,000 data-structure-typed
Array.push & shift 2829.59 100,000 原生JS
Deque.unshift & shift 2.44 100,000 data-structure-typed
Array.unshift & shift 4750.37 100,000 原生JS
HashMap.set 122.51 1,000,000 data-structure-typed
Map.set 223.80 1,000,000 原生JS
Set.add 185.06 1,000,000 原生JS
[//]: # (![Branches](https://img.shields.io/badge/branches-55.47%25-red.svg?style=flat)) [//]: # (![Statements](https://img.shields.io/badge/statements-67%25-red.svg?style=flat)) [//]: # (![Functions](https://img.shields.io/badge/functions-66.38%25-red.svg?style=flat)) [//]: # (![Lines](https://img.shields.io/badge/lines-68.6%25-red.svg?style=flat)) ## 安装和使用 现在你可以在 Node.js 和浏览器环境中使用它 CommonJS:**`require export.modules =`** ESModule:   **`import export`** Typescript:   **`import export`** UMD:           **`var Deque = dataStructureTyped.Deque`** ### npm ```bash npm i data-structure-typed --save ``` ### yarn ```bash yarn add data-structure-typed ``` ```js import { BinaryTree, Graph, Queue, Stack, PriorityQueue, BST, Trie, DoublyLinkedList, AVLTree, MinHeap, SinglyLinkedList, DirectedGraph, TreeMultimap, DirectedVertex, AVLTreeNode } from 'data-structure-typed'; ``` ### CDN 将下面的代码复制到 HTML 文档的头标签中。 #### 开发环境 ```html ``` #### 生产环境 ```html ``` 将下面的代码复制到你的 HTML 的 script 标签中,你就可以开始你的开发了。 ```js const {Heap} = dataStructureTyped; const { BinaryTree, Graph, Queue, Stack, PriorityQueue, BST, Trie, DoublyLinkedList, AVLTree, MinHeap, SinglyLinkedList, DirectedGraph, TreeMultimap, DirectedVertex, AVLTreeNode } = dataStructureTyped; ``` ## 生动示例 ### Binary Tree(二叉树) [试一下](https://vivid-algorithm.vercel.app/),或者你可以使用我们的可视化工具运行自己的代码 [visual tool](https://github.com/zrwusa/vivid-algorithm) ![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/binary-tree-array-to-binary-tree.webp) ### Binary Tree DFS (二叉搜索树深度遍历) [试一下](https://vivid-algorithm.vercel.app/) ![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/binary-tree-dfs-in-order.webp) ### AVL Tree(AVL树) [试一下](https://vivid-algorithm.vercel.app/) ![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/avl-tree-test.webp) ### Tree Multi Map [试一下](https://vivid-algorithm.vercel.app/) ![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/tree-multiset-test.webp) ### Matrix [试一下](https://vivid-algorithm.vercel.app/algorithm/graph/) ![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/matrix-cut-off-tree-for-golf.webp) ### 有向图 [试一下](https://vivid-algorithm.vercel.app/algorithm/graph/) ![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/directed-graph-test.webp) ### 地图 [试一下](https://vivid-algorithm.vercel.app/algorithm/graph/) ![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/map-graph-test.webp) ## 代码片段 ### 二叉搜索树 (BST) 代码示例 #### TS ```ts import {BST, BSTNode} from 'data-structure-typed'; const bst = new BST(); bst.add(11); bst.add(3); bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]); bst.size === 16; // true bst.has(6); // true const node6 = bst.getNode(6); // BSTNode bst.getHeight(6) === 2; // true bst.getHeight() === 5; // true bst.getDepth(6) === 3; // true bst.getLeftMost()?.key === 1; // true bst.delete(6); bst.get(6); // undefined bst.isAVLBalanced(); // true bst.bfs()[0] === 11; // true bst.print() // ______________11_____ // / \ // ___3_______ _13_____ // / \ / \ // 1_ _____8____ 12 _15__ // \ / \ / \ // 2 4_ _10 14 16 // \ / // 5_ 9 // \ // 7 const objBST = new BST(); objBST.add(11, { "name": "Pablo", "age": 15 }); objBST.add(3, { "name": "Kirk", "age": 1 }); objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [ { "name": "Alice", "age": 15 }, { "name": "Bob", "age": 1 }, { "name": "Charlie", "age": 8 }, { "name": "David", "age": 13 }, { "name": "Emma", "age": 16 }, { "name": "Frank", "age": 2 }, { "name": "Grace", "age": 6 }, { "name": "Hannah", "age": 9 }, { "name": "Isaac", "age": 12 }, { "name": "Jack", "age": 14 }, { "name": "Katie", "age": 4 }, { "name": "Liam", "age": 7 }, { "name": "Mia", "age": 10 }, { "name": "Noah", "age": 5 } ] ); objBST.delete(11); ``` #### JS ```js const {BST, BSTNode} = require('data-structure-typed'); const bst = new BST(); bst.add(11); bst.add(3); bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]); bst.size === 16; // true bst.has(6); // true const node6 = bst.getNode(6); bst.getHeight(6) === 2; // true bst.getHeight() === 5; // true bst.getDepth(6) === 3; // true const leftMost = bst.getLeftMost(); leftMost?.key === 1; // true bst.delete(6); bst.get(6); // undefined bst.isAVLBalanced(); // true or false const bfsIDs = bst.bfs(); bfsIDs[0] === 11; // true ``` ### AVL树 代码示例 ```ts import {AVLTree} from 'data-structure-typed'; const avlTree = new AVLTree(); avlTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) avlTree.isAVLBalanced(); // true avlTree.delete(10); avlTree.isAVLBalanced(); // true ``` ### 红黑树 代码示例 ```ts import {RedBlackTree} from 'data-structure-typed'; const rbTree = new RedBlackTree(); rbTree.addMany([11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5]) rbTree.isAVLBalanced(); // true rbTree.delete(10); rbTree.isAVLBalanced(); // true rbTree.print() // ___6________ // / \ // ___4_ ___11________ // / \ / \ // _2_ 5 _8_ ____14__ // / \ / \ / \ // 1 3 7 9 12__ 15__ // \ \ // 13 16 ``` ### 有向图代码示例 ```ts import {DirectedGraph} from 'data-structure-typed'; const graph = new DirectedGraph(); graph.addVertex('A'); graph.addVertex('B'); graph.hasVertex('A'); // true graph.hasVertex('B'); // true graph.hasVertex('C'); // false graph.addEdge('A', 'B'); graph.hasEdge('A', 'B'); // true graph.hasEdge('B', 'A'); // false graph.deleteEdgeSrcToDest('A', 'B'); graph.hasEdge('A', 'B'); // false graph.addVertex('C'); graph.addEdge('A', 'B'); graph.addEdge('B', 'C'); const topologicalOrderKeys = graph.topologicalSort(); // ['A', 'B', 'C'] ``` ### 无向图代码示例 ```ts import {UndirectedGraph} from 'data-structure-typed'; const graph = new UndirectedGraph(); graph.addVertex('A'); graph.addVertex('B'); graph.addVertex('C'); graph.addVertex('D'); graph.deleteVertex('C'); graph.addEdge('A', 'B'); graph.addEdge('B', 'D'); const dijkstraResult = graph.dijkstra('A'); Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.key) // ['A', 'B', 'D'] ``` ### 不同数据结构之间互相转换 ```js const orgArr = [6, 1, 2, 7, 5, 3, 4, 9, 8]; const orgStrArr = ["trie", "trial", "trick", "trip", "tree", "trend", "triangle", "track", "trace", "transmit"]; const entries = [[6, 6], [1, 1], [2, 2], [7, 7], [5, 5], [3, 3], [4, 4], [9, 9], [8, 8]]; const queue = new Queue(orgArr); queue.print(); // [6, 1, 2, 7, 5, 3, 4, 9, 8] const deque = new Deque(orgArr); deque.print(); // [6, 1, 2, 7, 5, 3, 4, 9, 8] const sList = new SinglyLinkedList(orgArr); sList.print(); // [6, 1, 2, 7, 5, 3, 4, 9, 8] const dList = new DoublyLinkedList(orgArr); dList.print(); // [6, 1, 2, 7, 5, 3, 4, 9, 8] const stack = new Stack(orgArr); stack.print(); // [6, 1, 2, 7, 5, 3, 4, 9, 8] const minHeap = new MinHeap(orgArr); minHeap.print(); // [1, 5, 2, 7, 6, 3, 4, 9, 8] const maxPQ = new MaxPriorityQueue(orgArr); maxPQ.print(); // [9, 8, 4, 7, 5, 2, 3, 1, 6] const biTree = new BinaryTree(entries); biTree.print(); // ___6___ // / \ // ___1_ _2_ // / \ / \ // _7_ 5 3 4 // / \ // 9 8 const bst = new BST(entries); bst.print(); // _____5___ // / \ // _2_ _7_ // / \ / \ // 1 3_ 6 8_ // \ \ // 4 9 const rbTree = new RedBlackTree(entries); rbTree.print(); // ___4___ // / \ // _2_ _6___ // / \ / \ // 1 3 5 _8_ // / \ // 7 9 const avl = new AVLTree(entries); avl.print(); // ___4___ // / \ // _2_ _6___ // / \ / \ // 1 3 5 _8_ // / \ // 7 9 const treeMulti = new TreeMultimap(entries); treeMulti.print(); // ___4___ // / \ // _2_ _6___ // / \ / \ // 1 3 5 _8_ // / \ // 7 9 const hm = new HashMap(entries); hm.print() // [[6, 6], [1, 1], [2, 2], [7, 7], [5, 5], [3, 3], [4, 4], [9, 9], [8, 8]] const rbTreeH = new RedBlackTree(hm); rbTreeH.print(); // ___4___ // / \ // _2_ _6___ // / \ / \ // 1 3 5 _8_ // / \ // 7 9 const pq = new MinPriorityQueue(orgArr); pq.print(); // [1, 5, 2, 7, 6, 3, 4, 9, 8] const bst1 = new BST(pq); bst1.print(); // _____5___ // / \ // _2_ _7_ // / \ / \ // 1 3_ 6 8_ // \ \ // 4 9 const dq1 = new Deque(orgArr); dq1.print(); // [6, 1, 2, 7, 5, 3, 4, 9, 8] const rbTree1 = new RedBlackTree(dq1); rbTree1.print(); // _____5___ // / \ // _2___ _7___ // / \ / \ // 1 _4 6 _9 // / / // 3 8 const trie2 = new Trie(orgStrArr); trie2.print(); // ['trie', 'trial', 'triangle', 'trick', 'trip', 'tree', 'trend', 'track', 'trace', 'transmit'] const heap2 = new Heap(trie2, { comparator: (a, b) => Number(a) - Number(b) }); heap2.print(); // ['transmit', 'trace', 'tree', 'trend', 'track', 'trial', 'trip', 'trie', 'trick', 'triangle'] const dq2 = new Deque(heap2); dq2.print(); // ['transmit', 'trace', 'tree', 'trend', 'track', 'trial', 'trip', 'trie', 'trick', 'triangle'] const entries2 = dq2.map((el, i) => [i, el]); const avl2 = new AVLTree(entries2); avl2.print(); // ___3_______ // / \ // _1_ ___7_ // / \ / \ // 0 2 _5_ 8_ // / \ \ // 4 6 9 ``` ## API 文档 & 演示 [API 文档](https://data-structure-typed-docs.vercel.app) [在线演示](https://vivid-algorithm.vercel.app) 演示项目代码仓库 ## 包含的数据结构
Data Structure Unit Test Performance Test API Docs
Binary Tree View
Binary Search Tree (BST) View
AVL Tree View
Red Black Tree View
Tree Multimap View
Heap View
Priority Queue View
Max Priority Queue View
Min Priority Queue View
Trie View
Graph View
Directed Graph View
Undirected Graph View
Queue View
Deque View
Hash Map View
Linked List View
Singly Linked List View
Doubly Linked List View
Stack View
Segment Tree View
Binary Indexed Tree View
## 不同编程语言中的数据结构对应关系
Data Structure Typed C++ STL java.util Python collections
Heap<E> priority_queue<T> PriorityQueue<E> heapq
Deque<E> deque<T> ArrayDeque<E> deque
Queue<E> queue<T> Queue<E> -
HashMap<K, V> unordered_map<K, V> HashMap<K, V> defaultdict
DoublyLinkedList<E> list<T> LinkedList<E> -
SinglyLinkedList<E> - - -
BinaryTree<K, V> - - -
BST<K, V> - - -
RedBlackTree<E> set<T> TreeSet<E> -
RedBlackTree<K, V> map<K, V> TreeMap<K, V> -
TreeMultimap<K, V> multimap<K, V> - -
TreeMultimap<E> multiset<T> - -
Trie - - -
DirectedGraph<V, E> - - -
UndirectedGraph<V, E> - - -
PriorityQueue<E> priority_queue<T> PriorityQueue<E> -
Array<E> vector<T> ArrayList<E> list
Stack<E> stack<T> Stack<E> -
HashMap<E> unordered_set<T> HashSet<E> set
- unordered_multiset - Counter
LinkedHashMap<K, V> - LinkedHashMap<K, V> OrderedDict
- unordered_multimap<K, V> - -
- bitset<N> - -
## 基准测试 [//]: # (No deletion!!! Start of Replace Section)
avl-tree
test nametime taken (ms)executions per secsample deviation
10,000 add randomly72.4813.800.03
10,000 add & delete randomly144.146.940.03
10,000 addMany69.7114.350.02
10,000 get54.2118.450.01
binary-tree
test nametime taken (ms)executions per secsample deviation
1,000 add randomly15.8463.140.00
1,000 add & delete randomly24.6240.620.00
1,000 addMany17.8556.010.00
1,000 get20.8348.000.00
1,000 has20.7848.130.00
1,000 dfs186.065.370.02
1,000 bfs66.5815.020.02
1,000 morris298.233.350.02
bst
test nametime taken (ms)executions per secsample deviation
10,000 add randomly55.0418.170.01
10,000 add & delete randomly129.857.700.01
10,000 addMany50.4019.840.01
10,000 get63.3915.780.01
rb-tree
test nametime taken (ms)executions per secsample deviation
100,000 add113.258.830.02
100,000 add & delete randomly305.283.280.03
100,000 getNode73.2013.660.03
100,000 add & iterator159.806.260.06
comparison
test nametime taken (ms)executions per secsample deviation
SRC PQ 10,000 add0.175872.024.08e-5
CJS PQ 10,000 add0.204961.221.14e-4
MJS PQ 10,000 add0.741351.472.98e-4
SRC PQ 10,000 add & pop4.62216.490.00
CJS PQ 10,000 add & pop4.36229.400.00
MJS PQ 10,000 add & pop3.92255.230.00
directed-graph
test nametime taken (ms)executions per secsample deviation
1,000 addVertex0.128557.702.46e-5
1,000 addEdge7.37135.700.00
1,000 getVertex0.051.91e+41.12e-5
1,000 getEdge22.7543.960.00
tarjan196.985.080.01
tarjan all217.254.600.03
topologicalSort177.305.640.02
hash-map
test nametime taken (ms)executions per secsample deviation
1,000,000 set153.746.500.07
1,000,000 Map set330.023.030.16
1,000,000 Set add258.643.870.06
1,000,000 set & get138.807.200.06
1,000,000 Map set & get352.632.840.05
1,000,000 Set add & has217.974.590.02
1,000,000 ObjKey set & get414.872.410.06
1,000,000 Map ObjKey set & get389.172.570.07
1,000,000 Set ObjKey add & has352.672.840.03
heap
test nametime taken (ms)executions per secsample deviation
100,000 add & pop90.6711.030.02
100,000 add & dfs40.3024.810.01
10,000 fib add & pop414.942.410.02
doubly-linked-list
test nametime taken (ms)executions per secsample deviation
1,000,000 push290.623.440.10
1,000,000 unshift253.883.940.10
1,000,000 unshift & shift259.653.850.14
1,000,000 insertBefore463.162.160.10
singly-linked-list
test nametime taken (ms)executions per secsample deviation
1,000,000 push & shift250.274.000.08
10,000 push & pop261.133.830.03
10,000 insertBefore282.463.540.02
max-priority-queue
test nametime taken (ms)executions per secsample deviation
10,000 refill & poll10.4995.290.00
priority-queue
test nametime taken (ms)executions per secsample deviation
100,000 add & pop110.639.040.01
deque
test nametime taken (ms)executions per secsample deviation
1,000,000 push15.8962.920.00
1,000,000 push & pop26.4537.810.01
1,000,000 push & shift27.5236.340.00
1,000,000 unshift & shift28.8234.700.01
queue
test nametime taken (ms)executions per secsample deviation
1,000,000 push51.2119.530.02
1,000,000 push & shift105.569.470.05
stack
test nametime taken (ms)executions per secsample deviation
1,000,000 push43.5722.950.01
1,000,000 push & pop55.1818.120.01
trie
test nametime taken (ms)executions per secsample deviation
100,000 push54.0818.490.01
100,000 getWords77.7712.860.02
[//]: # (No deletion!!! End of Replace Section) ## 内建的经典算法
算法 功能描述 迭代类型
二叉树深度优先搜索(DFS) 以深度优先的方式遍历二叉树,从根节点开始,首先访问左子树,然后是右子树,使用递归。 递归 + 迭代
二叉树广度优先搜索(BFS) 以广度优先的方式遍历二叉树,从根节点开始,逐层从左到右访问节点。 迭代
图的深度优先搜索 以深度优先的方式遍历图,从给定节点开始,尽可能深地沿一条路径探索,然后回溯以探索其他路径。用于寻找连通分量、路径等。 递归 + 迭代
二叉树Morris遍历 Morris遍历是一种中序遍历二叉树的算法,空间复杂度为O(1)。它允许在没有额外栈或递归的情况下遍历树。 迭代
图的广度优先搜索 以广度优先的方式遍历图,从给定节点开始,首先访问与起始节点直接相连的节点,然后逐层扩展。用于寻找最短路径等。 递归 + 迭代
图的Tarjan算法 在图中找到强连通分量,通常使用深度优先搜索实现。 递归
图的Bellman-Ford算法 从单一源点找到最短路径,可以处理负权边 迭代
图的Dijkstra算法 从单一源点找到最短路径,不能处理负权边 迭代
图的Floyd-Warshall算法 找到所有节点对之间的最短路径 迭代
图的getCycles 在图中找到所有循环或检测循环的存在。 递归
图的getCutVertexes 在图中找到切点,这些是移除后会增加图中连通分量数量的节点。 递归
图的getSCCs 在图中找到强连通分量,这些是任意两个节点都可以相互到达的子图。 递归
图的getBridges 在图中找到桥,这些是移除后会增加图中连通分量数量的边。 递归
图的拓扑排序 对有向无环图(DAG)进行拓扑排序,以找到节点的线性顺序,使得所有有向边都从较早的节点指向较晚的节点。 递归
## 软件工程标准
原则 描述
实用性 遵循ES6和ESNext标准,提供统一且考虑周到的可选参数,简化方法名称。
可扩展性 遵循OOP(面向对象编程)原则,允许所有数据结构继承。
模块化 包括数据结构模块化和独立的NPM包。
效率 所有方法都提供时间和空间复杂度,可与原生JS性能相媲美。
可维护性 遵循开源社区开发标准,完整文档,持续集成,并遵循TDD(测试驱动开发)模式。
可测试性 自动化和定制单元测试、性能测试和集成测试。
可移植性 计划移植到Java、Python和C++,目前已完成80%。
可复用性 完全解耦,最小化副作用,遵循OOP。
安全性 精心设计的成员变量和方法的安全性。读写分离。数据结构软件不需要考虑其他安全方面。
可扩展性 数据结构软件不涉及负载问题。