refactor: Directly constrain the methods clear, map, and filter in the base class.

feat: Implement the clear method in DirectedGraph, UndirectedGraph, and Trie.
docs: Add SPECIFICATION.md, SPONSOR.md, and SPONSOR_zh-CN.md. Adjust badge order and add a new contributor count badge.
This commit is contained in:
Revone 2024-01-06 17:50:00 +08:00
parent ba16f311c3
commit e91970c09f
10 changed files with 287 additions and 21 deletions

View file

@ -1,12 +1,14 @@
# data-structure-typed
![npm](https://img.shields.io/npm/v/data-structure-typed)
![npm](https://img.shields.io/npm/dm/data-structure-typed)
![GitHub contributors](https://img.shields.io/github/contributors/zrwusa/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)
![GITHUB Star](https://img.shields.io/github/stars/zrwusa/data-structure-typed)
![eslint](https://aleen42.github.io/badges/src/eslint.svg)
![NPM](https://img.shields.io/npm/l/data-structure-typed)
![npm](https://img.shields.io/npm/v/data-structure-typed)
[//]: # (![npm bundle size](https://img.shields.io/bundlephobia/min/data-structure-typed))
@ -939,43 +941,43 @@ We strictly adhere to computer science theory and software development standards
[//]: # (No deletion!!! Start of Replace Section)
<div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>avl-tree</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>119.60</td><td>8.36</td><td>0.00</td></tr><tr><td>10,000 add & delete randomly</td><td>178.17</td><td>5.61</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>129.03</td><td>7.75</td><td>7.48e-4</td></tr><tr><td>10,000 get</td><td>48.79</td><td>20.49</td><td>3.13e-4</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>125.60</td><td>7.96</td><td>0.00</td></tr><tr><td>10,000 add & delete randomly</td><td>181.22</td><td>5.52</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>134.12</td><td>7.46</td><td>0.01</td></tr><tr><td>10,000 get</td><td>55.08</td><td>18.16</td><td>0.01</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>binary-tree-overall</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 RBTree add</td><td>5.80</td><td>172.50</td><td>7.88e-5</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>16.33</td><td>61.24</td><td>0.00</td></tr><tr><td>10,000 RBTree get</td><td>20.95</td><td>47.74</td><td>0.00</td></tr><tr><td>10,000 AVLTree add</td><td>131.91</td><td>7.58</td><td>0.01</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>202.75</td><td>4.93</td><td>0.04</td></tr><tr><td>10,000 AVLTree get</td><td>1.02</td><td>984.65</td><td>2.43e-4</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 RBTree add</td><td>6.17</td><td>161.95</td><td>0.00</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>16.07</td><td>62.22</td><td>2.62e-4</td></tr><tr><td>10,000 RBTree get</td><td>19.86</td><td>50.36</td><td>2.44e-4</td></tr><tr><td>10,000 AVLTree add</td><td>134.38</td><td>7.44</td><td>0.02</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>207.20</td><td>4.83</td><td>0.06</td></tr><tr><td>10,000 AVLTree get</td><td>0.98</td><td>1015.54</td><td>2.73e-5</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>rb-tree</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>88.57</td><td>11.29</td><td>0.01</td></tr><tr><td>100,000 add & delete randomly</td><td>266.59</td><td>3.75</td><td>0.06</td></tr><tr><td>100,000 getNode</td><td>201.81</td><td>4.96</td><td>0.03</td></tr><tr><td>100,000 add & iterator</td><td>116.38</td><td>8.59</td><td>0.02</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>86.65</td><td>11.54</td><td>0.02</td></tr><tr><td>100,000 add & delete randomly</td><td>221.02</td><td>4.52</td><td>0.03</td></tr><tr><td>100,000 getNode</td><td>190.54</td><td>5.25</td><td>0.00</td></tr><tr><td>100,000 add & iterator</td><td>122.10</td><td>8.19</td><td>0.01</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>directed-graph</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 addVertex</td><td>0.10</td><td>9751.73</td><td>1.85e-6</td></tr><tr><td>1,000 addEdge</td><td>6.08</td><td>164.61</td><td>1.04e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.17e+4</td><td>3.55e-7</td></tr><tr><td>1,000 getEdge</td><td>25.95</td><td>38.53</td><td>0.01</td></tr><tr><td>tarjan</td><td>228.15</td><td>4.38</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>187.15</td><td>5.34</td><td>0.00</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 addVertex</td><td>0.11</td><td>8896.51</td><td>2.63e-5</td></tr><tr><td>1,000 addEdge</td><td>6.53</td><td>153.21</td><td>0.00</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.08e+4</td><td>1.06e-5</td></tr><tr><td>1,000 getEdge</td><td>27.53</td><td>36.33</td><td>0.01</td></tr><tr><td>tarjan</td><td>224.53</td><td>4.45</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>184.02</td><td>5.43</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>hash-map</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 set</td><td>117.95</td><td>8.48</td><td>0.04</td></tr><tr><td>Native Map 1,000,000 set</td><td>217.09</td><td>4.61</td><td>0.03</td></tr><tr><td>Native Set 1,000,000 add</td><td>168.56</td><td>5.93</td><td>0.02</td></tr><tr><td>1,000,000 set & get</td><td>121.33</td><td>8.24</td><td>0.03</td></tr><tr><td>Native Map 1,000,000 set & get</td><td>268.81</td><td>3.72</td><td>0.02</td></tr><tr><td>Native Set 1,000,000 add & has</td><td>172.46</td><td>5.80</td><td>0.01</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>411.49</td><td>2.43</td><td>0.09</td></tr><tr><td>Native Map 1,000,000 ObjKey set & get</td><td>335.40</td><td>2.98</td><td>0.07</td></tr><tr><td>Native Set 1,000,000 ObjKey add & has</td><td>287.11</td><td>3.48</td><td>0.06</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 set</td><td>126.27</td><td>7.92</td><td>0.05</td></tr><tr><td>Native Map 1,000,000 set</td><td>229.80</td><td>4.35</td><td>0.03</td></tr><tr><td>Native Set 1,000,000 add</td><td>175.83</td><td>5.69</td><td>0.01</td></tr><tr><td>1,000,000 set & get</td><td>121.34</td><td>8.24</td><td>0.03</td></tr><tr><td>Native Map 1,000,000 set & get</td><td>290.80</td><td>3.44</td><td>0.03</td></tr><tr><td>Native Set 1,000,000 add & has</td><td>180.71</td><td>5.53</td><td>0.01</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>357.68</td><td>2.80</td><td>0.07</td></tr><tr><td>Native Map 1,000,000 ObjKey set & get</td><td>310.57</td><td>3.22</td><td>0.06</td></tr><tr><td>Native Set 1,000,000 ObjKey add & has</td><td>278.42</td><td>3.59</td><td>0.05</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>heap</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & poll</td><td>23.77</td><td>42.07</td><td>2.92e-4</td></tr><tr><td>100,000 add & dfs</td><td>36.94</td><td>27.07</td><td>0.01</td></tr><tr><td>10,000 fib add & pop</td><td>374.40</td><td>2.67</td><td>0.04</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & poll</td><td>24.85</td><td>40.24</td><td>0.00</td></tr><tr><td>100,000 add & dfs</td><td>33.14</td><td>30.17</td><td>0.00</td></tr><tr><td>10,000 fib add & pop</td><td>366.11</td><td>2.73</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>doubly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>235.15</td><td>4.25</td><td>0.05</td></tr><tr><td>1,000,000 unshift</td><td>221.59</td><td>4.51</td><td>0.08</td></tr><tr><td>1,000,000 unshift & shift</td><td>172.11</td><td>5.81</td><td>0.02</td></tr><tr><td>1,000,000 addBefore</td><td>322.82</td><td>3.10</td><td>0.04</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>217.98</td><td>4.59</td><td>0.07</td></tr><tr><td>1,000,000 unshift</td><td>223.20</td><td>4.48</td><td>0.08</td></tr><tr><td>1,000,000 unshift & shift</td><td>172.87</td><td>5.78</td><td>0.03</td></tr><tr><td>1,000,000 addBefore</td><td>387.13</td><td>2.58</td><td>0.20</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>singly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push & shift</td><td>212.64</td><td>4.70</td><td>0.07</td></tr><tr><td>10,000 push & pop</td><td>221.21</td><td>4.52</td><td>0.01</td></tr><tr><td>10,000 addBefore</td><td>251.81</td><td>3.97</td><td>0.01</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push & shift</td><td>225.13</td><td>4.44</td><td>0.07</td></tr><tr><td>10,000 push & pop</td><td>234.54</td><td>4.26</td><td>0.02</td></tr><tr><td>10,000 addBefore</td><td>252.62</td><td>3.96</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>priority-queue</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & poll</td><td>75.00</td><td>13.33</td><td>9.50e-4</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & poll</td><td>76.49</td><td>13.07</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>deque</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>13.26</td><td>75.43</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>21.24</td><td>47.08</td><td>1.57e-4</td></tr><tr><td>100,000 push & shift</td><td>2.20</td><td>453.65</td><td>5.13e-4</td></tr><tr><td>Native Array 100,000 push & shift</td><td>2165.42</td><td>0.46</td><td>0.19</td></tr><tr><td>100,000 unshift & shift</td><td>2.19</td><td>455.62</td><td>4.59e-4</td></tr><tr><td>Native Array 100,000 unshift & shift</td><td>4298.71</td><td>0.23</td><td>0.13</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>13.20</td><td>75.75</td><td>2.79e-4</td></tr><tr><td>1,000,000 push & pop</td><td>22.21</td><td>45.03</td><td>3.27e-4</td></tr><tr><td>100,000 push & shift</td><td>2.26</td><td>442.24</td><td>1.43e-4</td></tr><tr><td>Native Array 100,000 push & shift</td><td>2329.51</td><td>0.43</td><td>0.10</td></tr><tr><td>100,000 unshift & shift</td><td>2.16</td><td>463.83</td><td>8.20e-5</td></tr><tr><td>Native Array 100,000 unshift & shift</td><td>4590.64</td><td>0.22</td><td>0.33</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>queue</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>46.44</td><td>21.53</td><td>0.01</td></tr><tr><td>100,000 push & shift</td><td>5.00</td><td>199.87</td><td>1.37e-4</td></tr><tr><td>Native Array 100,000 push & shift</td><td>2276.16</td><td>0.44</td><td>0.12</td></tr><tr><td>Native Array 100,000 push & pop</td><td>4.33</td><td>230.72</td><td>1.58e-4</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>49.92</td><td>20.03</td><td>0.02</td></tr><tr><td>100,000 push & shift</td><td>5.07</td><td>197.28</td><td>5.86e-4</td></tr><tr><td>Native Array 100,000 push & shift</td><td>2315.78</td><td>0.43</td><td>0.13</td></tr><tr><td>Native Array 100,000 push & pop</td><td>4.37</td><td>228.72</td><td>1.32e-4</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>stack</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>47.43</td><td>21.08</td><td>0.02</td></tr><tr><td>1,000,000 push & pop</td><td>50.64</td><td>19.75</td><td>0.01</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>44.50</td><td>22.47</td><td>0.01</td></tr><tr><td>1,000,000 push & pop</td><td>53.57</td><td>18.67</td><td>0.02</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>trie</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 push</td><td>47.83</td><td>20.91</td><td>0.00</td></tr><tr><td>100,000 getWords</td><td>100.67</td><td>9.93</td><td>0.01</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 push</td><td>42.95</td><td>23.28</td><td>6.68e-4</td></tr><tr><td>100,000 getWords</td><td>92.11</td><td>10.86</td><td>0.01</td></tr></table></div>
</div>
[//]: # (No deletion!!! End of Replace Section)

56
SPECIFICATION.md Normal file
View file

@ -0,0 +1,56 @@
[NPM](https://www.npmjs.com/package/data-structure-typed)
[Github](https://github.com/zrwusa/data-structure-typed)
## Pain Points Addressed
### Enhancing the Performance of Simulated Data Structures in JS/TS
- `Queue`: While many resort to using Arrays to simulate Queues and Deques, the time complexity of Array.shift is O(n). We have tackled this challenge by implementing a Queue and Deque with O(1) time complexity for enqueue and dequeue operations.
- `HashMap`: Opting for a pure HashMap over the built-in Map (technically a LinkedHashMap) can boost algorithmic speed. However, the performance is compromised due to the necessity of considering insertion order. We have independently implemented an optimized HashMap.
- `Stack`: In JS, simulating a Stack with an Array is acceptable, and its performance is on par with a genuine Stack.
### Introducing Missing Native Data Structures in JS/TS
- `Heap / Priority Queue`: Algorithms with O(log n) time complexity have been pivotal in improving efficiency since the dawn of computers. A Heap supports insertion, deletion, and search with O(log n) time complexity, coupled with the ability to obtain the minimum / maximum value in O(1) time.
- `Red Black Tree`: Developers well-versed in databases, file systems, Linux virtual memory management, and network routing tables often have a nuanced understanding of Red-Black Trees. It stands out as the least operation-intensive among all balanced binary search trees, offering optimal performance balance in CRUD operations.
- `Linked List`: In scenarios where insertion or deletion of elements with O(1) time complexity is required at a specific index in an ordered collection, JS lacks a provided data structure. Hence, the need for a LinkedList to implement this functionality.
- `Trie`: Efficient for fast string queries and space-efficient string storage, yet not commonly found in the standard libraries of most programming languages.
- `Graph`: This data structure is not commonly found in the standard libraries of most languages, making it a non-issue in JS.
## Advantages
### Performance:
- The performance of some ours data structures has surpassed JS's built-in data structures (`Queue`, `Deque`, `HashMap`), while most are comparable to or even surpass those in other languages. Some are still undergoing refinement (`Graph`, `AVL Tree`).
### Uniformity
- 1. Implementation or constraint of `forEach`, `filter`, `map`, `every`, `some`, `reduce`, `find`, `has`, `hasValue`, `get`, `print`, `isEmpty`, `clear`, `clone` methods in the base class.
- 2. Use of generators to uniformly implement `[Symbol.iterator]`, `entries`, `keys`, `values`. Delaying iterator execution prevents performance loss and provides control during traversal.
- 3. All deletion methods uniformly use the widely adopted `delete` in ES6, while addition methods uniformly use `add`. Compatibility with some specifications in Java.
- 4. The first parameter for all constructors is data, and the second parameter is configuration, maintaining uniformity. The first parameter accepts any iterable type for seamless conversion between data structures.
- 5. Uniform return types, for example, the `add` method consistently returns a boolean.
### Convenience and Simplicity of APIs
- Inspired by ES6, Java, ESNext, TypeScript, Python, featuring methods like `forEach`, `filter`, `map`, `every`, `some`, `reduce`, `find`, `has`, `hasValue` and `get`.
### Use of Commonly Understood Industry Standard Naming
- `enqueue`, `dequeue`, `push`, `pop`, `poll`, `addLast`, `addFirst`, `pollFirst`, `pollLast`, `isEmpty`, `clear`, `print`, `clone`.
### Implementation of Customizable Features Whenever Possible
- Such as providing callback functions (lambda expressions) for all traversal methods.
### Comprehensive Documentation
- The documentation not only explains the purpose of methods but also annotates time and space complexity across the entire series.

90
SPONSOR-zh-CN.md Normal file
View file

@ -0,0 +1,90 @@
# 我是谁
我是一个拥有15年工作经验的软件开发工程师自大学毕业职于不同行业的软件公司其中也包括一些大厂。
# 目前现状
为了孩子得到正规教育移居到马来西亚持有10年居留签证但是这个签证不允许我被马来西亚公司雇佣。
由于自己酷爱编程又正逢JavaScript / TypeScript (以下简称`JS/TS`)没有标准库涵盖数据结构,便决定在开源社区自己实现一套数据结构 [data-structure-typed]()。
[NPM](https://www.npmjs.com/package/data-structure-typed)
[Github](https://github.com/zrwusa/data-structure-typed)
# 项目介绍
## 最终目标
- 成为JS/TS的标准库的一部分。
## 解决了的痛点
### 在JS / TS我们只能基于Array和Map来模拟一些数据结构例如QueueDequeStackHashMap
- `Queue`:大家使用Array来模拟Queue和Deque但是Array.shift方法的时间复杂度是O(n)的。我们实现了入队和出队时间复杂度为O(1)的QueueDeque。
- `HashMap`:如大家希望使用一个纯正的HashMap来加速自己的算法而不是使用内置的Map(严格来说是LinkedHashMap)由于需要顾及插入顺序所以性能上逊色于纯正的HashMap。我们单独实现了HashMap
- `Stack`: 在JS中用Array模拟Stack并没有什么不妥性能也不弱于真正的Stack。
### JS / TS内置数据结构的缺失。
- `Heap / Priority Queue`:
不得不提O(log n)这个算法时间复杂度是人类使用计算机以来最受欢迎的提高效率的方式。Heap本身就支持插入、删除、查找时间复杂度均为O(log n)
还顺带附赠一个动态随时以O(1)的时间复杂度获取最值的功能。
- `Red Black Tree`:
相信很多了解数据库、文件系统、Linux的虚拟内存管理和网络路由表底层的开发者都对红黑树有一定了解。
因为它是在所有平衡二叉搜索树中操作消耗量最少的而且在CRUD这4个操作上性能平衡得最好的实现。
- `Linked List`:
例如我们需要在一个有序集合中如果已经获取到某个元素的索引的情况下在这个索引处插入或者删除元素JS没有提供类似数据结构。我们需要LinkedList来实现。
- `Trie`:
字符串高速查询,字符串存储高效性方面有奇效,但是大多数编程语言的标准库中不常见。
- `Graph`:
这个数据结构在大多数的语言标准库中也不常见所以我们不把它作为JS的弱项。
## 优势
### 性能:
- 少部分数据结构的性能已经超越JS内置数据结构`Queue``Deque`, `HashMap` 大部分已接近或超越其它语言,部分还没达标(`Graph`, `AVL Tree`)
### 统一性
- 1、在基类中实现或约束 `forEach``filter`, `map``every``some``reduce``find``has``hasValue``get``print``isEmpty`, `clear``clone` 方法。
- 2、使用生成器统一实现`[Symbol.iterator]``entries`, `keys`, `values`。延迟执行遍历器以防止性能损失,并提供遍历时的可控性。
- 3、所有的删除方法都统一采用ES6标准中惯用的`delete`。添加方法统一使用`add`。同时兼容Java中的一些规范。
- 4、所有构造函数的第一个参数都是数据第二个参数是配置保持统一。第一个参数接受任意可遍历类型以实现数据结构间自由转换。
- 5、统一返回参数类型如`add`方法统一返回布尔值。
### APIs的便捷性和简洁性
- 受ES6, Java, ESNext, TypeScript, Python的启发如`forEach``filter`, `map``every``some``reduce``find``has``hasValue``get`
### 使用通俗易懂业界常用命名
- `enqueue`, `dequeue`, `push`, `pop`, `poll`, `addLast`, `addFirst`, `pollFirst`, `pollLast`, `isEmpty`, `clear`, `print`, `clone`
### 尽量实现可定制化功能
- 如所有遍历方法都提供回调函数(拉姆达表达式)的设计
### 完善的文档
- 文档不但阐述方法的用途,而且全系标注时间和空间复杂度
## 社区活跃度
- 从社区来说NPM下载量![npm](https://img.shields.io/npm/dm/data-structure-typed)
GitHub星星![GITHUB Star](https://img.shields.io/github/stars/zrwusa/data-structure-typed)
贡献者![GitHub contributors](https://img.shields.io/github/contributors/zrwusa/data-structure-typed)
## 赞助我们吧
- 以软件工程标准来说我们的项目目前已经达到至少75%的完整度我们相信我们在您的赞助下很快将这个项目的完成度提高到95%,这对我的家庭来说算一种援助,对我们项目组来说是一种鼓励,也希望尽早能够实现成为`JS/TS`标准库的目标。

54
SPONSOR.md Normal file
View file

@ -0,0 +1,54 @@
# Who am I
I am a seasoned software development engineer with 15 years of professional experience. Following my graduation from university, I have contributed my expertise to various software companies across diverse industries, including some prominent ones.
Of course, I have my flaws, I have a nerd-like attitude towards technology and could be described as a perfectionist. For instance, being excessively serious and having a penchant for studying the essence of things, I sometimes come across as a stern boss, which can be intimidating to my wife and daughter.
Fortunately, my outlook on life is broad-minded. when it comes to life and family, the keywords are love, loyalty, and appreciation of beauty. I also enjoy studying cultural differences in various regions. Deep down, I actually have a bit of an artistic flair. LOL, just writing this makes me want to laugh!
# Current Situation
My recent move to Malaysia was motivated by the desire to provide my daughter with a formal education(Yes, you read it correctly, it is the word 'formal', because the education system in some countries is not normal), and it comes alongside holding a 10-year residency visa(MM2H). However, this visa restricts my employment opportunities within Malaysian companies. Fueled by my passion for programming and recognizing the absence of a standardized data structures library in JavaScript/TypeScript, I embarked on the journey of implementing my own set of data structures - `data-structure-typed` within the open-source community.
# `data-structure-typed` Project Overview
## Ultimate Goal
- To seamlessly integrate into the standard library of JS/TS.
## Pain Points Addressed
### Enhanced the Performance of Simulated Data Structures in JS/TS
- `Queue`: While many resort to using Array to simulate Queue and Deque, the time complexity of Array.shift is O(n). We have tackled this by implementing a Queue and Deque with O(1) time complexity.
- `HashMap`: The built-in Map in JS is actually a LinkedHashMap, as it maintains the insertion order of elements, resulting in performance inferiority compared to a pure HashMap. We have implemented a pure HashMap.
### Introducing Missing Native Data Structures in JS/TS
- `Heap / Priority Queue`: Algorithms with O(log n) time complexity have been pivotal in improving efficiency since the dawn of computers. A Heap supports insertion, deletion, and search with O(log n) time complexity, coupled with the ability to obtain the minimum / maximum value in O(1) time.
- `Red Black Tree`: Developers well-versed in databases, file systems, Linux virtual memory management, and network routing tables often have a nuanced understanding of Red-Black Trees. It stands out as the least operation-intensive among all balanced binary search trees, offering optimal performance balance in CRUD operations.
## Advantages
### Performance:
- The performance of some ours data structures has surpassed JS's built-in data structures, such as `Queue`, `Deque` and `HashMap`, while most are comparable to or even surpass those in other languages. Some are still undergoing refinement, notably the `Graph` and `AVL Tree`.
### Uniformity
- 1. Concise and industry-standard namingImplementation or constraint of `forEach`, `filter`, `map`, `every`, `some`, `reduce`, `find`, `has`, `hasValue`, `get`, `print`, `isEmpty`, `clear`, `clone` methods in the base class.
- 2. Adhere to the ES6 specification: Use of generators to uniformly implement `[Symbol.iterator]`, `entries`, `keys`, `values`. Delaying iterator execution prevents performance loss and provides control during traversal. All deletion methods uniformly use the widely adopted `delete` in ES6, while addition methods uniformly use `add`. Compatibility with some specifications in Java.
- 3. ConstructorsThe first parameter for all constructors is data, and the second parameter is configuration, maintaining uniformity. The first parameter accepts any iterable type for seamless conversion between data structures.
- 4. Return typesfor example, the `add` method consistently returns a boolean.
We would like to provide a more detailed description of this project, but space is limited here. For specific technical details, please refer to the [README.md](https://github.com/zrwusa/data-structure-typed), [SPECIFICATION.md](https://github.com/zrwusa/data-structure-typed/blob/main/CODE_OF_CONDUCT.md), or [API Docs](https://data-structure-typed-docs.vercel.app/).
## Community Activity
- In terms of community engagement, we have noteworthy metrics including NPM download count ![npm](https://img.shields.io/npm/dm/data-structure-typed), GitHub stars ![GITHUB Star](https://img.shields.io/github/stars/zrwusa/data-structure-typed), and contributors ![GitHub contributors](https://img.shields.io/github/contributors/zrwusa/data-structure-typed).
## Sponsor Us
- From a software engineering standards perspective, our project has achieved at least 75% completeness. With your sponsorship, we believe we can swiftly elevate the project's completion to 95%, providing valuable assistance to my family and serving as encouragement to our project team. Additionally, we aspire to expedite the goal of becoming an integral part of the `JS/TS` standard library.

View file

@ -289,8 +289,14 @@ export abstract class IterableEntryBase<K = any, V = any> {
abstract isEmpty(): boolean;
abstract clear(): void;
abstract clone(): any;
abstract map(...args: any[]): any;
abstract filter(...args: any[]): any;
protected abstract _getIterator(...args: any[]): IterableIterator<[K, V]>;
}
@ -497,7 +503,13 @@ export abstract class IterableElementBase<E = any, C = any> {
abstract isEmpty(): boolean;
abstract clear(): void;
abstract clone(): C;
abstract map(...args: any[]): any;
abstract filter(...args: any[]): any;
protected abstract _getIterator(...args: any[]): IterableIterator<E>;
}

View file

@ -616,6 +616,23 @@ export class DirectedGraph<
return this.vertexMap.size === 0 && this.inEdgeMap.size === 0 && this.outEdgeMap.size === 0;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The clear function resets the vertex map, in-edge map, and out-edge map.
*/
clear() {
this._vertexMap = new Map<VertexKey, VO>();
this._inEdgeMap = new Map<VO, EO[]>();
this._outEdgeMap = new Map<VO, EO[]>();
}
/**
* The clone function creates a new DirectedGraph object with the same vertices and edges as the original.
*

View file

@ -377,6 +377,22 @@ export class UndirectedGraph<
return this.vertexMap.size === 0 && this.edgeMap.size === 0;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The clear function resets the vertex and edge maps to empty maps.
*/
clear() {
this._vertexMap = new Map<VertexKey, VO>();
this._edgeMap = new Map<VO, EO[]>();
}
/**
* The clone function creates a new UndirectedGraph object and copies the
* vertexMap and edgeMap from this graph to the new one. This is done by

View file

@ -15,10 +15,10 @@ export class TreeNode<V = any> {
this._children = children || [];
}
private _key: string;
protected _key: string;
/**
* The function returns the value of the private variable _key.
* The function returns the value of the protected variable _key.
* @returns The value of the `_key` property, which is a string.
*/
get key(): string {
@ -26,7 +26,7 @@ export class TreeNode<V = any> {
}
/**
* The above function sets the value of a private variable called "key".
* The above function sets the value of a protected variable called "key".
* @param {string} value - The value parameter is a string that represents the value to be assigned
* to the key.
*/
@ -34,7 +34,7 @@ export class TreeNode<V = any> {
this._key = value;
}
private _value?: V | undefined;
protected _value?: V | undefined;
/**
* The function returns the value stored in a variable, or undefined if the variable is empty.
@ -53,7 +53,7 @@ export class TreeNode<V = any> {
this._value = value;
}
private _children?: TreeNode<V>[] | undefined;
protected _children?: TreeNode<V>[] | undefined;
/**
* The function returns an array of TreeNode objects or undefined.

View file

@ -22,7 +22,7 @@ export class TrieNode {
protected _key: string;
/**
* The function returns the value of the private variable _key.
* The function returns the value of the protected variable _key.
* @returns The value of the `_key` property, which is a string.
*/
get key(): string {
@ -30,7 +30,7 @@ export class TrieNode {
}
/**
* The above function sets the value of a private variable called "key".
* The above function sets the value of a protected variable called "key".
* @param {string} value - The value parameter is a string that represents the value to be assigned
* to the key.
*/
@ -214,6 +214,22 @@ export class Trie extends IterableElementBase<string, Trie> {
return this.size === 0;
}
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*/
/**
* Time Complexity: O(1)
* Space Complexity: O(1)
*
* The clear function resets the size of the Trie to 0 and creates a new root TrieNode.
*/
clear(): void {
this._size = 0;
this._root = new TrieNode('');
}
/**
* Time Complexity: O(l), where l is the length of the word being deleted.
* Space Complexity: O(n) - Due to the recursive DFS approach.

View file

@ -81,6 +81,9 @@ class MyGraph<
return true;
}
clear(): void {
}
clone(): any {
return {};
}