Refactor: Rename _defaultOneParamCallback to _DEFAULT_CALLBACK. Adopt early return code style in the ensureNode method. Rename some internal recursive method names.

This commit is contained in:
Revone 2024-01-15 12:12:01 +08:00
parent 46cdf2b668
commit 9915ce9a0d
15 changed files with 147 additions and 134 deletions

View file

@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
## [v1.50.9](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
## [v1.51.0](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
### Changes

View file

@ -104,7 +104,7 @@ Performance surpasses that of native JS/TS
### Conciseness and uniformity
In [java.utils](), you need to memorize a table for all sequential data structures(Queue, Deque, LinkedList),
<table>
<table style="display: table; width:100%; table-layout: fixed;">
<thead>
<tr>
<th>Java ArrayList</th>
@ -687,43 +687,43 @@ Version 11.7.9
[//]: # (No deletion!!! Start of Replace Section)
<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</td><td>6.58</td><td>152.07</td><td>3.13e-4</td></tr><tr><td>100,000 add & poll</td><td>35.67</td><td>28.03</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 add</td><td>6.36</td><td>157.24</td><td>1.88e-4</td></tr><tr><td>100,000 add & poll</td><td>32.56</td><td>30.72</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'>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>55.91</td><td>17.89</td><td>0.01</td></tr><tr><td>100,000 get</td><td>125.11</td><td>7.99</td><td>0.01</td></tr><tr><td>100,000 iterator</td><td>27.97</td><td>35.76</td><td>0.01</td></tr><tr><td>100,000 add & delete orderly</td><td>125.06</td><td>8.00</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>242.78</td><td>4.12</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 add</td><td>55.46</td><td>18.03</td><td>0.00</td></tr><tr><td>100,000 get</td><td>114.63</td><td>8.72</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>26.52</td><td>37.71</td><td>0.01</td></tr><tr><td>100,000 add & delete orderly</td><td>128.13</td><td>7.80</td><td>0.02</td></tr><tr><td>100,000 add & delete randomly</td><td>228.89</td><td>4.37</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'>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>44.81</td><td>22.32</td><td>0.01</td></tr><tr><td>100,000 push & shift</td><td>4.99</td><td>200.39</td><td>7.40e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2234.97</td><td>0.45</td><td>0.19</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>43.53</td><td>22.97</td><td>0.01</td></tr><tr><td>100,000 push & shift</td><td>4.80</td><td>208.14</td><td>5.81e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2201.64</td><td>0.45</td><td>0.11</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>24.34</td><td>41.08</td><td>0.01</td></tr><tr><td>1,000,000 push & pop</td><td>31.41</td><td>31.83</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>31.12</td><td>32.13</td><td>0.00</td></tr><tr><td>100,000 push & shift</td><td>3.27</td><td>306.17</td><td>2.62e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2362.95</td><td>0.42</td><td>0.12</td></tr><tr><td>100,000 unshift & shift</td><td>2.89</td><td>345.46</td><td>3.23e-4</td></tr><tr><td>Native JS Array 100,000 unshift & shift</td><td>4313.81</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>25.91</td><td>38.59</td><td>0.01</td></tr><tr><td>1,000,000 push & pop</td><td>30.71</td><td>32.57</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>30.59</td><td>32.69</td><td>0.00</td></tr><tr><td>100,000 push & shift</td><td>3.23</td><td>309.94</td><td>2.61e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2525.12</td><td>0.40</td><td>0.39</td></tr><tr><td>100,000 unshift & shift</td><td>2.87</td><td>347.92</td><td>2.86e-4</td></tr><tr><td>Native JS Array 100,000 unshift & shift</td><td>4400.38</td><td>0.23</td><td>0.14</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>118.81</td><td>8.42</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set</td><td>218.24</td><td>4.58</td><td>0.02</td></tr><tr><td>Native JS Set 1,000,000 add</td><td>180.64</td><td>5.54</td><td>0.03</td></tr><tr><td>1,000,000 set & get</td><td>121.23</td><td>8.25</td><td>0.01</td></tr><tr><td>Native JS Map 1,000,000 set & get</td><td>273.71</td><td>3.65</td><td>0.01</td></tr><tr><td>Native JS Set 1,000,000 add & has</td><td>173.69</td><td>5.76</td><td>0.01</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>331.89</td><td>3.01</td><td>0.04</td></tr><tr><td>Native JS Map 1,000,000 ObjKey set & get</td><td>331.49</td><td>3.02</td><td>0.05</td></tr><tr><td>Native JS Set 1,000,000 ObjKey add & has</td><td>308.15</td><td>3.25</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 set</td><td>113.02</td><td>8.85</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set</td><td>201.23</td><td>4.97</td><td>0.00</td></tr><tr><td>Native JS Set 1,000,000 add</td><td>168.53</td><td>5.93</td><td>0.01</td></tr><tr><td>1,000,000 set & get</td><td>118.49</td><td>8.44</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set & get</td><td>263.49</td><td>3.80</td><td>0.01</td></tr><tr><td>Native JS Set 1,000,000 add & has</td><td>168.28</td><td>5.94</td><td>0.01</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>309.88</td><td>3.23</td><td>0.01</td></tr><tr><td>Native JS Map 1,000,000 ObjKey set & get</td><td>282.50</td><td>3.54</td><td>0.04</td></tr><tr><td>Native JS Set 1,000,000 ObjKey add & has</td><td>268.42</td><td>3.73</td><td>0.03</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>58.78</td><td>17.01</td><td>0.02</td></tr><tr><td>100,000 getWords</td><td>95.99</td><td>10.42</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>44.85</td><td>22.30</td><td>0.01</td></tr><tr><td>100,000 getWords</td><td>84.84</td><td>11.79</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'>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>50.17</td><td>19.93</td><td>0.01</td></tr><tr><td>10,000 get</td><td>20.86</td><td>47.94</td><td>0.00</td></tr><tr><td>10,000 add & delete randomly</td><td>79.18</td><td>12.63</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>52.92</td><td>18.90</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>100,000 add</td><td>381.63</td><td>2.62</td><td>0.00</td></tr><tr><td>100,000 get</td><td>354.69</td><td>2.82</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>29.87</td><td>33.48</td><td>0.01</td></tr><tr><td>100,000 add & delete orderly</td><td>652.77</td><td>1.53</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>929.07</td><td>1.08</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'>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.69</td><td>175.82</td><td>5.70e-4</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>19.94</td><td>50.16</td><td>0.00</td></tr><tr><td>10,000 RBTree get</td><td>0.65</td><td>1543.77</td><td>1.81e-5</td></tr><tr><td>10,000 AVLTree add</td><td>44.46</td><td>22.49</td><td>0.00</td></tr><tr><td>10,000 AVLTree get</td><td>20.07</td><td>49.84</td><td>0.00</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>77.29</td><td>12.94</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>10,000 RBTree add</td><td>5.55</td><td>180.05</td><td>7.09e-5</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>19.06</td><td>52.46</td><td>1.94e-4</td></tr><tr><td>10,000 RBTree get</td><td>0.61</td><td>1647.37</td><td>6.11e-6</td></tr><tr><td>10,000 AVLTree add</td><td>32.03</td><td>31.22</td><td>7.32e-4</td></tr><tr><td>10,000 AVLTree get</td><td>19.65</td><td>50.89</td><td>3.12e-4</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>62.07</td><td>16.11</td><td>4.26e-4</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>9883.75</td><td>9.48e-7</td></tr><tr><td>1,000 addEdge</td><td>6.05</td><td>165.15</td><td>1.08e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.15e+4</td><td>5.74e-7</td></tr><tr><td>1,000 getEdge</td><td>23.58</td><td>42.41</td><td>0.00</td></tr><tr><td>tarjan</td><td>208.84</td><td>4.79</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>180.27</td><td>5.55</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.10</td><td>9939.30</td><td>9.29e-7</td></tr><tr><td>1,000 addEdge</td><td>6.15</td><td>162.54</td><td>8.71e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.18e+4</td><td>2.83e-7</td></tr><tr><td>1,000 getEdge</td><td>23.93</td><td>41.78</td><td>0.00</td></tr><tr><td>tarjan</td><td>207.83</td><td>4.81</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>181.91</td><td>5.50</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>208.91</td><td>4.79</td><td>0.07</td></tr><tr><td>1,000,000 unshift</td><td>202.73</td><td>4.93</td><td>0.03</td></tr><tr><td>1,000,000 unshift & shift</td><td>182.70</td><td>5.47</td><td>0.06</td></tr><tr><td>1,000,000 addBefore</td><td>314.16</td><td>3.18</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 push</td><td>210.21</td><td>4.76</td><td>0.03</td></tr><tr><td>1,000,000 unshift</td><td>218.63</td><td>4.57</td><td>0.05</td></tr><tr><td>1,000,000 unshift & shift</td><td>162.14</td><td>6.17</td><td>0.01</td></tr><tr><td>1,000,000 addBefore</td><td>319.75</td><td>3.13</td><td>0.06</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>207.94</td><td>4.81</td><td>0.05</td></tr><tr><td>10,000 push & pop</td><td>216.07</td><td>4.63</td><td>0.01</td></tr><tr><td>10,000 addBefore</td><td>246.19</td><td>4.06</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,000 push & shift</td><td>191.55</td><td>5.22</td><td>0.03</td></tr><tr><td>10,000 push & pop</td><td>215.95</td><td>4.63</td><td>0.01</td></tr><tr><td>10,000 addBefore</td><td>249.82</td><td>4.00</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'>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</td><td>27.00</td><td>37.04</td><td>2.43e-4</td></tr><tr><td>100,000 add & poll</td><td>77.16</td><td>12.96</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>100,000 add</td><td>27.54</td><td>36.31</td><td>2.55e-4</td></tr><tr><td>100,000 add & poll</td><td>75.88</td><td>13.18</td><td>4.27e-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>39.29</td><td>25.45</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>48.05</td><td>20.81</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,000 push</td><td>39.78</td><td>25.14</td><td>0.01</td></tr><tr><td>1,000,000 push & pop</td><td>46.90</td><td>21.32</td><td>0.01</td></tr></table></div>
</div>
[//]: # (No deletion!!! End of Replace Section)

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "data-structure-typed",
"version": "1.50.9",
"version": "1.51.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "data-structure-typed",
"version": "1.50.9",
"version": "1.51.0",
"license": "MIT",
"devDependencies": {
"@swc/core": "^1.3.96",

View file

@ -1,6 +1,6 @@
{
"name": "data-structure-typed",
"version": "1.50.9",
"version": "1.51.0",
"description": "Javascript Data Structure. Heap, Binary Tree, Red Black Tree, Linked List, Deque, Trie, HashMap, Directed Graph, Undirected Graph, Binary Search Tree(BST), AVL Tree, Priority Queue, Graph, Queue, Tree Multiset, Singly Linked List, Doubly Linked List, Max Heap, Max Priority Queue, Min Heap, Min Priority Queue, Stack. Benchmark compared with C++ STL. API aligned with ES6 and Java.util. Usability is comparable to Python",
"main": "dist/cjs/index.js",
"module": "dist/mjs/index.js",

View file

@ -240,7 +240,7 @@ export class AVLTreeMultiMap<
*/
override delete<C extends BTNCallback<NODE>>(
identifier: ReturnType<C>,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
ignoreCount = false
): BinaryTreeDeleteResult<NODE>[] {
const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];

View file

@ -164,13 +164,13 @@ export class AVLTree<
* `callback` function.
* @param {C} callback - The `callback` parameter is a function that will be called for each node
* that is deleted from the binary tree. It is an optional parameter and if not provided, it will
* default to the `_defaultOneParamCallback` function. The `callback` function should have a single
* default to the `_DEFAULT_CALLBACK` function. The `callback` function should have a single
* parameter of type `NODE
* @returns The method is returning an array of `BinaryTreeDeleteResult<NODE>`.
*/
override delete<C extends BTNCallback<NODE>>(
identifier: ReturnType<C>,
callback: C = this._defaultOneParamCallback as C
callback: C = this._DEFAULT_CALLBACK as C
): BinaryTreeDeleteResult<NODE>[] {
if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;
const deletedResults = super.delete(identifier, callback);

View file

@ -268,17 +268,17 @@ export class BinaryTree<
keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
iterationType: IterationType = 'ITERATIVE'
): NODE | null | undefined {
let res: NODE | null | undefined;
if (this.isRealNode(keyOrNodeOrEntry)) {
res = keyOrNodeOrEntry;
return keyOrNodeOrEntry;
} else if (this.isEntry(keyOrNodeOrEntry)) {
if (keyOrNodeOrEntry[0] === null) res = null;
else if (keyOrNodeOrEntry[0] !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
if (keyOrNodeOrEntry[0] === null) return null;
if (keyOrNodeOrEntry[0] === undefined) return;
return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
} else {
if (keyOrNodeOrEntry === null) res = null;
else if (keyOrNodeOrEntry !== undefined) res = this.getNodeByKey(keyOrNodeOrEntry, iterationType);
if (keyOrNodeOrEntry === null) return null;
if (keyOrNodeOrEntry === undefined) return;
return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
}
return res;
}
/**
@ -486,16 +486,16 @@ export class BinaryTree<
* specific node based on its value or object.
* @param {C} callback - The `callback` parameter is a function that is used to determine the
* identifier of the node to be deleted. It is optional and has a default value of
* `this._defaultOneParamCallback`. The `callback` function should return the identifier of the node.
* `this._DEFAULT_CALLBACK`. The `callback` function should return the identifier of the node.
* @returns an array of `BinaryTreeDeleteResult<NODE>`.
*/
delete<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C
callback: C = this._DEFAULT_CALLBACK as C
): BinaryTreeDeleteResult<NODE>[] {
const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
if (!this.root) return deletedResult;
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
const curr = this.getNode(identifier, callback);
@ -579,7 +579,7 @@ export class BinaryTree<
* specific value.
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
* input and returns a value of type `C`. It is used to determine if a node matches the given
* identifier. If no callback is provided, the `_defaultOneParamCallback` function is used as the
* identifier. If no callback is provided, the `_DEFAULT_CALLBACK` function is used as the
* default
* @param [onlyOne=false] - A boolean value indicating whether to only return the first node that
* matches the identifier. If set to true, the function will stop iterating once it finds a matching
@ -594,12 +594,12 @@ export class BinaryTree<
*/
getNodes<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
onlyOne = false,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
): NODE[] {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
beginRoot = this.ensureNode(beginRoot);
if (!beginRoot) return [];
@ -607,28 +607,28 @@ export class BinaryTree<
const ans: NODE[] = [];
if (iterationType === 'RECURSIVE') {
const _traverse = (cur: NODE) => {
const dfs = (cur: NODE) => {
if (callback(cur) === identifier) {
ans.push(cur);
if (onlyOne) return;
}
if (!cur.left && !cur.right) return;
cur.left && _traverse(cur.left);
cur.right && _traverse(cur.right);
cur.left && dfs(cur.left);
cur.right && dfs(cur.right);
};
_traverse(beginRoot);
dfs(beginRoot);
} else {
const queue = new Queue<NODE>([beginRoot]);
while (queue.size > 0) {
const cur = queue.shift();
const stack = [beginRoot];
while (stack.length > 0) {
const cur = stack.pop();
if (cur) {
if (callback(cur) === identifier) {
ans.push(cur);
if (onlyOne) return ans;
}
cur.left && queue.push(cur.left);
cur.right && queue.push(cur.right);
cur.left && stack.push(cur.left);
cur.right && stack.push(cur.right);
}
}
}
@ -685,11 +685,11 @@ export class BinaryTree<
*/
getNode<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
): NODE | null | undefined {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
@ -717,23 +717,23 @@ export class BinaryTree<
getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
if (!this.root) return undefined;
if (iterationType === 'RECURSIVE') {
const _dfs = (cur: NODE): NODE | undefined => {
const dfs = (cur: NODE): NODE | undefined => {
if (cur.key === key) return cur;
if (!cur.left && !cur.right) return;
if (cur.left) return _dfs(cur.left);
if (cur.right) return _dfs(cur.right);
if (cur.left) return dfs(cur.left);
if (cur.right) return dfs(cur.right);
};
return _dfs(this.root);
return dfs(this.root);
} else {
const queue = new Queue<NODE>([this.root]);
while (queue.size > 0) {
const cur = queue.shift();
const stack = [this.root];
while (stack.length > 0) {
const cur = stack.pop();
if (cur) {
if (cur.key === key) return cur;
cur.left && queue.push(cur.left);
cur.right && queue.push(cur.right);
cur.left && stack.push(cur.left);
cur.right && stack.push(cur.right);
}
}
}
@ -789,11 +789,11 @@ export class BinaryTree<
*/
override get<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
): V | undefined {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
@ -848,11 +848,11 @@ export class BinaryTree<
*/
override has<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
): boolean {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
if ((!callback || callback === this._DEFAULT_CALLBACK) && (identifier as any) instanceof BinaryTreeNode)
callback = (node => node) as C;
return this.getNodes(identifier, callback, true, beginRoot, iterationType).length > 0;
@ -1184,20 +1184,20 @@ export class BinaryTree<
if (!this.isRealNode(beginRoot)) return beginRoot;
if (iterationType === 'RECURSIVE') {
const _traverse = (cur: NODE): NODE => {
const dfs = (cur: NODE): NODE => {
if (!this.isRealNode(cur.left)) return cur;
return _traverse(cur.left);
return dfs(cur.left);
};
return _traverse(beginRoot);
return dfs(beginRoot);
} else {
// Indirect implementation of iteration using tail recursion optimization
const _traverse = trampoline((cur: NODE) => {
const dfs = trampoline((cur: NODE) => {
if (!this.isRealNode(cur.left)) return cur;
return _traverse.cont(cur.left);
return dfs.cont(cur.left);
});
return _traverse(beginRoot);
return dfs(beginRoot);
}
}
@ -1231,20 +1231,20 @@ export class BinaryTree<
if (!beginRoot) return beginRoot;
if (iterationType === 'RECURSIVE') {
const _traverse = (cur: NODE): NODE => {
const dfs = (cur: NODE): NODE => {
if (!this.isRealNode(cur.right)) return cur;
return _traverse(cur.right);
return dfs(cur.right);
};
return _traverse(beginRoot);
return dfs(beginRoot);
} else {
// Indirect implementation of iteration using tail recursion optimization
const _traverse = trampoline((cur: NODE) => {
const dfs = trampoline((cur: NODE) => {
if (!this.isRealNode(cur.right)) return cur;
return _traverse.cont(cur.right);
return dfs.cont(cur.right);
});
return _traverse(beginRoot);
return dfs(beginRoot);
}
}
@ -1351,7 +1351,7 @@ export class BinaryTree<
* @returns an array of values that are the return values of the callback function.
*/
dfs<C extends BTNCallback<NODE | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
pattern: DFSOrderPattern = 'IN',
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = 'ITERATIVE',
@ -1361,38 +1361,38 @@ export class BinaryTree<
if (!beginRoot) return [];
const ans: ReturnType<C>[] = [];
if (iterationType === 'RECURSIVE') {
const _traverse = (node: NODE | null | undefined) => {
const dfs = (node: NODE | null | undefined) => {
switch (pattern) {
case 'IN':
if (includeNull) {
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
this.isNodeOrNull(node) && ans.push(callback(node));
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
} else {
if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
this.isRealNode(node) && ans.push(callback(node));
if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
}
break;
case 'PRE':
if (includeNull) {
this.isNodeOrNull(node) && ans.push(callback(node));
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
} else {
this.isRealNode(node) && ans.push(callback(node));
if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
}
break;
case 'POST':
if (includeNull) {
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) _traverse(node.left);
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) _traverse(node.right);
if (this.isRealNode(node) && this.isNodeOrNull(node.left)) dfs(node.left);
if (this.isRealNode(node) && this.isNodeOrNull(node.right)) dfs(node.right);
this.isNodeOrNull(node) && ans.push(callback(node));
} else {
if (this.isRealNode(node) && this.isRealNode(node.left)) _traverse(node.left);
if (this.isRealNode(node) && this.isRealNode(node.right)) _traverse(node.right);
if (this.isRealNode(node) && this.isRealNode(node.left)) dfs(node.left);
if (this.isRealNode(node) && this.isRealNode(node.right)) dfs(node.right);
this.isRealNode(node) && ans.push(callback(node));
}
@ -1400,7 +1400,7 @@ export class BinaryTree<
}
};
_traverse(beginRoot);
dfs(beginRoot);
} else {
// 0: visit, 1: print
const stack: { opt: 0 | 1; node: NODE | null | undefined }[] = [{ opt: 0, node: beginRoot }];
@ -1486,7 +1486,7 @@ export class BinaryTree<
* the breadth-first traversal of a binary tree.
*/
bfs<C extends BTNCallback<NODE | null>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType,
includeNull = false
@ -1499,7 +1499,7 @@ export class BinaryTree<
if (iterationType === 'RECURSIVE') {
const queue: Queue<NODE | null | undefined> = new Queue<NODE | null | undefined>([beginRoot]);
const traverse = (level: number) => {
const dfs = (level: number) => {
if (queue.size === 0) return;
const current = queue.shift()!;
@ -1513,10 +1513,10 @@ export class BinaryTree<
if (this.isRealNode(current.right)) queue.push(current.right);
}
traverse(level + 1);
dfs(level + 1);
};
traverse(0);
dfs(0);
} else {
const queue = new Queue<NODE | null | undefined>([beginRoot]);
while (queue.size > 0) {
@ -1580,7 +1580,7 @@ export class BinaryTree<
* @returns The function `listLevels` returns a two-dimensional array of type `ReturnType<C>[][]`.
*/
listLevels<C extends BTNCallback<NODE | null>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType,
includeNull = false
@ -1651,7 +1651,7 @@ export class BinaryTree<
* by the return type of the `callback` function.
*/
morris<C extends BTNCallback<NODE>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
pattern: DFSOrderPattern = 'IN',
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root
): ReturnType<C>[] {
@ -1995,7 +1995,7 @@ export class BinaryTree<
}
}
protected _defaultOneParamCallback = (node: NODE | null | undefined) => (node ? node.key : undefined);
protected _DEFAULT_CALLBACK = (node: NODE | null | undefined) => (node ? node.key : undefined);
/**
* Swap the data of two nodes in the binary tree.

View file

@ -214,15 +214,15 @@ export class BST<
keyOrNodeOrEntry: KeyOrNodeOrEntry<K, V, NODE>,
iterationType: IterationType = 'ITERATIVE'
): NODE | undefined {
let res: NODE | undefined;
if (this.isRealNode(keyOrNodeOrEntry)) {
res = keyOrNodeOrEntry;
return keyOrNodeOrEntry;
} else if (this.isEntry(keyOrNodeOrEntry)) {
if (keyOrNodeOrEntry[0]) res = this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
if (keyOrNodeOrEntry[0] === null || keyOrNodeOrEntry[0] === undefined) return;
return this.getNodeByKey(keyOrNodeOrEntry[0], iterationType);
} else {
if (keyOrNodeOrEntry) res = this.getNodeByKey(keyOrNodeOrEntry, iterationType);
if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) return;
return this.getNodeByKey(keyOrNodeOrEntry, iterationType);
}
return res;
}
/**
@ -426,26 +426,26 @@ export class BST<
* found in the binary tree. If no node is found, it returns `undefined`.
*/
override getNodeByKey(key: K, iterationType: IterationType = 'ITERATIVE'): NODE | undefined {
// return this.getNodes(key, this._defaultOneParamCallback, true, this.root, iterationType)[0];
if (!this.isRealNode(this.root)) return undefined;
// return this.getNodes(key, this._DEFAULT_CALLBACK, true, this.root, iterationType)[0];
if (!this.isRealNode(this.root)) return;
if (iterationType === 'RECURSIVE') {
const _dfs = (cur: NODE): NODE | undefined => {
const dfs = (cur: NODE): NODE | undefined => {
if (cur.key === key) return cur;
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
if (this._compare(cur.key, key) === 'GT' && this.isRealNode(cur.left)) return _dfs(cur.left);
if (this._compare(cur.key, key) === 'LT' && this.isRealNode(cur.right)) return _dfs(cur.right);
if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') return dfs(cur.left);
if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') return dfs(cur.right);
};
return _dfs(this.root);
return dfs(this.root);
} else {
const queue = new Queue<NODE>([this.root]);
while (queue.size > 0) {
const cur = queue.shift();
const stack = [this.root];
while (stack.length > 0) {
const cur = stack.pop();
if (this.isRealNode(cur)) {
if (this._compare(cur.key, key) === 'EQ') return cur;
if (this._compare(cur.key, key) === 'GT') this.isRealNode(cur.left) && queue.push(cur.left);
if (this._compare(cur.key, key) === 'LT') this.isRealNode(cur.right) && queue.push(cur.right);
if (this.isRealNode(cur.left) && this._compare(cur.key, key) === 'GT') stack.push(cur.left);
if (this.isRealNode(cur.right) && this._compare(cur.key, key) === 'LT') stack.push(cur.right);
}
}
}
@ -481,7 +481,7 @@ export class BST<
*/
override getNodes<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | undefined,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
onlyOne = false,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
@ -491,7 +491,7 @@ export class BST<
const ans: NODE[] = [];
if (iterationType === 'RECURSIVE') {
const _traverse = (cur: NODE) => {
const dfs = (cur: NODE) => {
const callbackResult = callback(cur);
if (callbackResult === identifier) {
ans.push(cur);
@ -500,16 +500,16 @@ export class BST<
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
// TODO potential bug
if (callback === this._defaultOneParamCallback) {
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') _traverse(cur.left);
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') _traverse(cur.right);
if (callback === this._DEFAULT_CALLBACK) {
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') dfs(cur.left);
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') dfs(cur.right);
} else {
this.isRealNode(cur.left) && _traverse(cur.left);
this.isRealNode(cur.right) && _traverse(cur.right);
this.isRealNode(cur.left) && dfs(cur.left);
this.isRealNode(cur.right) && dfs(cur.right);
}
};
_traverse(beginRoot);
dfs(beginRoot);
} else {
const stack = [beginRoot];
while (stack.length > 0) {
@ -521,7 +521,7 @@ export class BST<
if (onlyOne) return ans;
}
// TODO potential bug
if (callback === this._defaultOneParamCallback) {
if (callback === this._DEFAULT_CALLBACK) {
if (this.isRealNode(cur.right) && this._compare(cur.key, identifier as K) === 'LT') stack.push(cur.right);
if (this.isRealNode(cur.left) && this._compare(cur.key, identifier as K) === 'GT') stack.push(cur.left);
@ -568,7 +568,7 @@ export class BST<
* @returns The method is returning an array of the return type of the callback function.
*/
override dfs<C extends BTNCallback<NODE>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
pattern: DFSOrderPattern = 'IN',
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = 'ITERATIVE'
@ -599,7 +599,7 @@ export class BST<
* @returns The method is returning an array of the return type of the callback function.
*/
override bfs<C extends BTNCallback<NODE>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
): ReturnType<C>[] {
@ -630,7 +630,7 @@ export class BST<
* function.
*/
override listLevels<C extends BTNCallback<NODE>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
): ReturnType<C>[][] {
@ -700,7 +700,7 @@ export class BST<
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
*/
lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
lesserOrGreater: CP = 'LT',
targetNode: KeyOrNodeOrEntry<K, V, NODE> = this.root,
iterationType: IterationType = this.iterationType
@ -713,15 +713,15 @@ export class BST<
const targetKey = targetNode.key;
if (iterationType === 'RECURSIVE') {
const _traverse = (cur: NODE) => {
const dfs = (cur: NODE) => {
const compared = this._compare(cur.key, targetKey);
if (compared === lesserOrGreater) ans.push(callback(cur));
if (this.isRealNode(cur.left)) _traverse(cur.left);
if (this.isRealNode(cur.right)) _traverse(cur.right);
if (this.isRealNode(cur.left)) dfs(cur.left);
if (this.isRealNode(cur.right)) dfs(cur.right);
};
_traverse(this.root);
dfs(this.root);
return ans;
} else {
const queue = new Queue<NODE>([this.root]);

View file

@ -231,7 +231,7 @@ export class RedBlackTree<
*/
override getNode<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | undefined,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
beginRoot: BSTNKeyOrNode<K, NODE> = this.root,
iterationType: IterationType = this.iterationType
): NODE | null | undefined {
@ -308,13 +308,13 @@ export class RedBlackTree<
* deleted is not found.
* @param {C} callback - The `callback` parameter is a function that is used to retrieve a node from
* the binary tree based on its identifier. It is an optional parameter and if not provided, the
* `_defaultOneParamCallback` function is used as the default callback. The callback function should
* `_DEFAULT_CALLBACK` function is used as the default callback. The callback function should
* return the identifier of the node to
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
*/
override delete<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C
callback: C = this._DEFAULT_CALLBACK as C
): BinaryTreeDeleteResult<NODE>[] {
if (identifier === null) return [];
const results: BinaryTreeDeleteResult<NODE>[] = [];

View file

@ -242,7 +242,7 @@ export class TreeMultiMap<
* function. It can also be null or undefined if no node needs to be deleted.
* @param {C} callback - The `callback` parameter is a function that takes a node of type `NODE` as
* input and returns a value of type `ReturnType<C>`. It is used to determine if a node matches the
* identifier for deletion. If no callback is provided, the `_defaultOneParamCallback` function is
* identifier for deletion. If no callback is provided, the `_DEFAULT_CALLBACK` function is
* used
* @param [ignoreCount=false] - A boolean value indicating whether to ignore the count of the target
* node when performing deletion. If set to true, the count of the target node will not be considered
@ -252,7 +252,7 @@ export class TreeMultiMap<
*/
override delete<C extends BTNCallback<NODE>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
callback: C = this._DEFAULT_CALLBACK as C,
ignoreCount = false
): BinaryTreeDeleteResult<NODE>[] {
if (identifier === null) return [];

View file

@ -1,4 +1,4 @@
import { AVLTree, CP } from 'avl-tree-typed';
import { AVLTree } from 'avl-tree-typed';
describe('AVL Tree Test', () => {
it('should perform various operations on a AVL Tree', () => {

View file

@ -1,4 +1,4 @@
import { BST, BSTNode, CP } from 'bst-typed';
import { BST, BSTNode } from 'bst-typed';
describe('Individual package BST operations test', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {

View file

@ -28,14 +28,14 @@
const n = 1000000;
const startEn = performance.now();
for (let i = 0; i < n; i++) {
queue.enqueue(i);
queue.push(i);
}
console.log((performance.now() - startEn).toFixed(2), `Queue ${n.toLocaleString()} enqueue `);
let last = 0;
const startTime = performance.now();
for (let i = 0; i < n; i++) {
last = queue.dequeue();
last = queue.shift();
}
console.log((performance.now() - startTime).toFixed(2), `Queue ${n.toLocaleString()} dequeue `);

View file

@ -45,6 +45,7 @@ describe('TreeMultiMap operations test1', () => {
expect(tmm.getMinHeight()).toBe(-1);
tmm.addMany([1, 6, 7, 2, 3, 4, 9, 11, 8, 5, 10, 12, 16, 14, 13, 15]);
// tmm.print()
expect(tmm.getHeight()).toBe(5);
expect(tmm.getMinHeight()).toBe(2);
});

View file

@ -205,3 +205,15 @@ export function logBigOMetrics(target: any, propertyKey: string, descriptor: Pro
return descriptor;
}
export const logPerf = function (fn: (...args: any[]) => any, args: any[], thisArg?: any) {
const start = performance.now();
if (thisArg) {
if (args && args.length > 0) fn.apply(thisArg, args);
else fn.apply(thisArg);
} else {
if (args && args.length > 0) fn(...args);
else fn();
}
console.log(`function running cost : ${(performance.now() - start).toFixed(2)} ms`);
};