mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
style: reformated codebase
This commit is contained in:
parent
bac0964ac2
commit
dd2701dab7
|
@ -3,12 +3,12 @@
|
|||
root=true # represents the top-level EditorConfig configuration file
|
||||
|
||||
[*] # means applicable to all files
|
||||
charset = utf-8 #Set the file character set to utf-8
|
||||
indent_style = space #Indent style (tab | space)
|
||||
charset = utf-8 # Set the file character set to utf-8
|
||||
indent_style = space # Indent style (tab | space)
|
||||
indent_size = 2 # indent size
|
||||
end_of_line = lf # Control line break type (lf | cr | crlf)
|
||||
trim_trailing_whitespace = true # Remove any whitespace characters at the beginning of the line
|
||||
insert_final_newline = true #Always insert a new line at the end of the file
|
||||
insert_final_newline = true # Always insert a new line at the end of the file
|
||||
|
||||
[*.md] # Indicates that only md files apply the following rules
|
||||
max_line_length = off
|
||||
|
|
|
@ -43,8 +43,8 @@ module.exports = {
|
|||
}
|
||||
}
|
||||
],
|
||||
"brace-style": ["error", "1tbs", {"allowSingleLine": true}],
|
||||
"object-curly-spacing": ["error", "never"]
|
||||
// "brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
||||
"object-curly-spacing": ["warn", "always"]
|
||||
},
|
||||
"settings": {
|
||||
"import/parsers": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
module.exports = {
|
||||
"arrowParens": "avoid",
|
||||
"bracketSpacing": false,
|
||||
"bracketSpacing": true,
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"insertPragma": false,
|
||||
"bracketSameLine": false,
|
||||
|
|
|
@ -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.44.1](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
|
||||
## [v1.45.0](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
|
||||
|
||||
### Changes
|
||||
|
||||
|
|
30
README.md
30
README.md
|
@ -735,49 +735,49 @@ optimal approach to data structure design.
|
|||
[//]: # (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>36.59</td><td>27.33</td><td>0.02</td></tr><tr><td>10,000 add & delete randomly</td><td>71.18</td><td>14.05</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>45.45</td><td>22.00</td><td>0.01</td></tr><tr><td>10,000 get</td><td>28.08</td><td>35.62</td><td>9.19e-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>33.34</td><td>29.99</td><td>0.00</td></tr><tr><td>10,000 add & delete randomly</td><td>72.30</td><td>13.83</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>49.50</td><td>20.20</td><td>0.00</td></tr><tr><td>10,000 get</td><td>27.23</td><td>36.73</td><td>7.19e-4</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</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 add randomly</td><td>12.48</td><td>80.10</td><td>3.98e-4</td></tr><tr><td>1,000 add & delete randomly</td><td>16.91</td><td>59.15</td><td>0.00</td></tr><tr><td>1,000 addMany</td><td>10.66</td><td>93.85</td><td>4.57e-4</td></tr><tr><td>1,000 get</td><td>18.32</td><td>54.60</td><td>5.16e-4</td></tr><tr><td>1,000 dfs</td><td>155.40</td><td>6.44</td><td>0.00</td></tr><tr><td>1,000 bfs</td><td>57.64</td><td>17.35</td><td>0.01</td></tr><tr><td>1,000 morris</td><td>296.45</td><td>3.37</td><td>0.11</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 add randomly</td><td>12.20</td><td>81.97</td><td>8.36e-5</td></tr><tr><td>1,000 add & delete randomly</td><td>15.93</td><td>62.77</td><td>2.09e-4</td></tr><tr><td>1,000 addMany</td><td>10.36</td><td>96.56</td><td>2.01e-4</td></tr><tr><td>1,000 get</td><td>18.43</td><td>54.26</td><td>4.67e-4</td></tr><tr><td>1,000 dfs</td><td>154.61</td><td>6.47</td><td>0.00</td></tr><tr><td>1,000 bfs</td><td>57.73</td><td>17.32</td><td>0.01</td></tr><tr><td>1,000 morris</td><td>258.47</td><td>3.87</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'>bst</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>28.79</td><td>34.73</td><td>5.70e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>71.20</td><td>14.04</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>32.45</td><td>30.81</td><td>0.01</td></tr><tr><td>10,000 get</td><td>30.81</td><td>32.46</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>10,000 add randomly</td><td>29.44</td><td>33.96</td><td>3.99e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>72.35</td><td>13.82</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>29.76</td><td>33.60</td><td>0.00</td></tr><tr><td>10,000 get</td><td>28.53</td><td>35.05</td><td>5.76e-4</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>100.90</td><td>9.91</td><td>0.01</td></tr><tr><td>100,000 competitor add</td><td>46.94</td><td>21.31</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>226.33</td><td>4.42</td><td>0.02</td></tr><tr><td>100,000 getNode</td><td>39.13</td><td>25.55</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>90.42</td><td>11.06</td><td>0.01</td></tr><tr><td>100,000 add & delete randomly</td><td>223.52</td><td>4.47</td><td>0.02</td></tr><tr><td>100,000 getNode</td><td>38.67</td><td>25.86</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'>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>9661.78</td><td>7.45e-7</td></tr><tr><td>1,000 addEdge</td><td>6.19</td><td>161.53</td><td>3.24e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.03e+4</td><td>8.46e-6</td></tr><tr><td>1,000 getEdge</td><td>24.52</td><td>40.78</td><td>0.00</td></tr><tr><td>tarjan</td><td>218.05</td><td>4.59</td><td>0.01</td></tr><tr><td>tarjan all</td><td>219.89</td><td>4.55</td><td>0.00</td></tr><tr><td>topologicalSort</td><td>179.79</td><td>5.56</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 addVertex</td><td>0.11</td><td>9499.56</td><td>5.09e-6</td></tr><tr><td>1,000 addEdge</td><td>6.37</td><td>157.04</td><td>8.13e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.15e+4</td><td>1.20e-6</td></tr><tr><td>1,000 getEdge</td><td>22.44</td><td>44.56</td><td>0.00</td></tr><tr><td>tarjan</td><td>213.53</td><td>4.68</td><td>0.01</td></tr><tr><td>tarjan all</td><td>215.75</td><td>4.63</td><td>0.00</td></tr><tr><td>topologicalSort</td><td>175.51</td><td>5.70</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'>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>10,000 set</td><td>0.78</td><td>1275.91</td><td>8.70e-5</td></tr><tr><td>10,000 competitor set</td><td>0.59</td><td>1694.57</td><td>1.30e-5</td></tr><tr><td>10,000 set & get</td><td>1.04</td><td>960.33</td><td>2.28e-5</td></tr><tr><td>10,000 competitor set & get</td><td>0.68</td><td>1474.34</td><td>1.08e-5</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 set</td><td>0.76</td><td>1308.63</td><td>1.65e-5</td></tr><tr><td>10,000 set & get</td><td>1.03</td><td>966.59</td><td>2.21e-5</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>10,000 add & pop</td><td>4.63</td><td>215.97</td><td>6.56e-5</td></tr><tr><td>10,000 fib add & pop</td><td>358.14</td><td>2.79</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>10,000 add & pop</td><td>4.65</td><td>214.92</td><td>1.18e-4</td></tr><tr><td>10,000 fib add & pop</td><td>367.35</td><td>2.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'>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 unshift</td><td>212.23</td><td>4.71</td><td>0.03</td></tr><tr><td>1,000,000 competitor unshift</td><td>78.93</td><td>12.67</td><td>0.02</td></tr><tr><td>1,000,000 unshift & shift</td><td>166.32</td><td>6.01</td><td>0.01</td></tr><tr><td>1,000,000 insertBefore</td><td>332.92</td><td>3.00</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 unshift</td><td>222.80</td><td>4.49</td><td>0.06</td></tr><tr><td>1,000,000 unshift & shift</td><td>174.60</td><td>5.73</td><td>0.04</td></tr><tr><td>1,000,000 insertBefore</td><td>309.21</td><td>3.23</td><td>0.07</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>10,000 push & pop</td><td>222.69</td><td>4.49</td><td>0.01</td></tr><tr><td>10,000 insertBefore</td><td>250.47</td><td>3.99</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 push & pop</td><td>214.75</td><td>4.66</td><td>0.01</td></tr><tr><td>10,000 insertBefore</td><td>250.45</td><td>3.99</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'>max-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>10,000 refill & poll</td><td>11.61</td><td>86.12</td><td>2.65e-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 refill & poll</td><td>11.44</td><td>87.43</td><td>1.80e-4</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>10,000 add & pop</td><td>12.58</td><td>79.46</td><td>3.35e-4</td></tr><tr><td>10,000 competitor add & pop</td><td>2.15</td><td>464.55</td><td>3.30e-5</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 & pop</td><td>12.41</td><td>80.57</td><td>1.56e-4</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>206.22</td><td>4.85</td><td>0.04</td></tr><tr><td>1,000,000 competitor push</td><td>22.29</td><td>44.87</td><td>0.00</td></tr><tr><td>1,000,000 shift</td><td>26.65</td><td>37.52</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>219.15</td><td>4.56</td><td>0.04</td></tr><tr><td>1,000,000 shift</td><td>26.76</td><td>37.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>46.76</td><td>21.39</td><td>0.02</td></tr><tr><td>1,000,000 competitor push</td><td>48.74</td><td>20.52</td><td>0.01</td></tr><tr><td>1,000,000 push & shift</td><td>80.87</td><td>12.36</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>45.17</td><td>22.14</td><td>0.01</td></tr><tr><td>1,000,000 push & shift</td><td>80.41</td><td>12.44</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'>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>43.03</td><td>23.24</td><td>0.01</td></tr><tr><td>1,000,000 competitor push</td><td>72.29</td><td>13.83</td><td>0.05</td></tr><tr><td>1,000,000 push & pop</td><td>49.55</td><td>20.18</td><td>0.01</td></tr><tr><td>1,000,000 competitor push & pop</td><td>51.10</td><td>19.57</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>43.67</td><td>22.90</td><td>0.01</td></tr><tr><td>1,000,000 push & pop</td><td>48.18</td><td>20.76</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'>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>57.67</td><td>17.34</td><td>0.03</td></tr><tr><td>100,000 getWords</td><td>118.82</td><td>8.42</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 push</td><td>60.46</td><td>16.54</td><td>0.00</td></tr><tr><td>100,000 getWords</td><td>83.13</td><td>12.03</td><td>0.00</td></tr></table></div>
|
||||
</div>
|
||||
|
||||
[//]: # (No deletion!!! End of Replace Section)
|
|
@ -32,7 +32,7 @@
|
|||
"format:src": "prettier --write 'src/**/*.{js,ts}'",
|
||||
"format:test": "prettier --write 'test/**/*.{js,ts}'",
|
||||
"format": "npm run format:src && npm run format:test",
|
||||
"ci": "env && git fetch --tags && npm run check && npm run lint && npm run build && npm run test:unit && npm run changelog",
|
||||
"ci": "env && git fetch --tags && npm run inspect && npm run lint && npm run build && npm run test:unit && npm run changelog",
|
||||
"update:subs": "npm i avl-tree-typed binary-tree-typed bst-typed heap-typed data-structure-typed --save-dev",
|
||||
"install:all-subs": "npm i avl-tree-typed binary-tree-typed bst-typed deque-typed directed-graph-typed doubly-linked-list-typed graph-typed heap-typed linked-list-typed max-heap-typed max-priority-queue-typed min-heap-typed min-priority-queue-typed priority-queue-typed singly-linked-list-typed stack-typed tree-multimap-typed trie-typed undirected-graph-typed queue-typed --save-dev",
|
||||
"changelog": "auto-changelog",
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {BST, BSTNode} from './bst';
|
||||
import type {AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey} from '../../types';
|
||||
import {BTNCallback} from '../../types';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import { BST, BSTNode } from './bst';
|
||||
import type { AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey } from '../../types';
|
||||
import { BTNCallback } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
|
||||
export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNested<V>> extends BSTNode<V, N> {
|
||||
height: number;
|
||||
|
@ -21,7 +21,8 @@ export class AVLTreeNode<V = any, N extends AVLTreeNode<V, N> = AVLTreeNodeNeste
|
|||
|
||||
export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTreeNodeNested<V>>>
|
||||
extends BST<V, N>
|
||||
implements IBinaryTree<V, N> {
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
/**
|
||||
* This is a constructor function for an AVL tree data structure in TypeScript.
|
||||
* @param {AVLTreeOptions} [options] - The `options` parameter is an optional object that can be passed to the
|
||||
|
@ -95,7 +96,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
): BiTreeDeleteResult<N>[] {
|
||||
if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;
|
||||
const deletedResults = super.delete(identifier, callback);
|
||||
for (const {needBalanced} of deletedResults) {
|
||||
for (const { needBalanced } of deletedResults) {
|
||||
if (needBalanced) {
|
||||
this._balancePath(needBalanced);
|
||||
}
|
||||
|
@ -118,7 +119,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
destNode = this.ensureNotKey(destNode);
|
||||
|
||||
if (srcNode && destNode) {
|
||||
const {key, value, height} = destNode;
|
||||
const { key, value, height } = destNode;
|
||||
const tempNode = this.createNode(key, value);
|
||||
|
||||
if (tempNode) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {getMSB} from '../../utils';
|
||||
import { getMSB } from '../../utils';
|
||||
|
||||
export class BinaryIndexedTree {
|
||||
protected readonly _freq: number;
|
||||
|
@ -17,10 +17,10 @@ export class BinaryIndexedTree {
|
|||
* @param - - `frequency`: The default frequency value. It is optional and has a default
|
||||
* value of 0.
|
||||
*/
|
||||
constructor({frequency = 0, max}: {frequency?: number; max: number}) {
|
||||
constructor({ frequency = 0, max }: { frequency?: number; max: number }) {
|
||||
this._freq = frequency;
|
||||
this._max = max;
|
||||
this._freqMap = {0: 0};
|
||||
this._freqMap = { 0: 0 };
|
||||
this._msb = getMSB(max);
|
||||
this._negativeCount = frequency < 0 ? max : 0;
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import type {BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey} from '../../types';
|
||||
import {BiTreeDeleteResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {trampoline} from '../../utils';
|
||||
import {Queue} from '../queue';
|
||||
import type { BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey } from '../../types';
|
||||
import { BiTreeDeleteResult, DFSOrderPattern, FamilyPosition, IterationType } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { trampoline } from '../../utils';
|
||||
import { Queue } from '../queue';
|
||||
|
||||
/**
|
||||
* Represents a node in a binary tree.
|
||||
|
@ -107,7 +107,9 @@ export class BinaryTreeNode<V = any, N extends BinaryTreeNode<V, N> = BinaryTree
|
|||
* Represents a binary tree data structure.
|
||||
* @template N - The type of the binary tree's nodes.
|
||||
*/
|
||||
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>> implements IBinaryTree<V, N> {
|
||||
export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode<V, BinaryTreeNodeNested<V>>>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
iterationType: IterationType = IterationType.ITERATIVE;
|
||||
|
||||
/**
|
||||
|
@ -116,7 +118,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
*/
|
||||
constructor(options?: BinaryTreeOptions) {
|
||||
if (options) {
|
||||
const {iterationType = IterationType.ITERATIVE} = options;
|
||||
const { iterationType = IterationType.ITERATIVE } = options;
|
||||
this.iterationType = iterationType;
|
||||
}
|
||||
this._size = 0;
|
||||
|
@ -315,7 +317,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
// Handle the case when there's only one root node
|
||||
this._setRoot(null);
|
||||
} else {
|
||||
const {familyPosition: fp} = curr;
|
||||
const { familyPosition: fp } = curr;
|
||||
if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {
|
||||
parent.left = curr.right;
|
||||
} else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {
|
||||
|
@ -330,7 +332,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
const parentOfLeftSubTreeMax = leftSubTreeRightMost.parent;
|
||||
orgCurrent = this._swap(curr, leftSubTreeRightMost);
|
||||
if (parentOfLeftSubTreeMax) {
|
||||
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost) parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
||||
if (parentOfLeftSubTreeMax.right === leftSubTreeRightMost)
|
||||
parentOfLeftSubTreeMax.right = leftSubTreeRightMost.left;
|
||||
else parentOfLeftSubTreeMax.left = leftSubTreeRightMost.left;
|
||||
needBalanced = parentOfLeftSubTreeMax;
|
||||
}
|
||||
|
@ -339,7 +342,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
}
|
||||
this._size = this.size - 1;
|
||||
|
||||
deletedResult.push({deleted: orgCurrent, needBalanced});
|
||||
deletedResult.push({ deleted: orgCurrent, needBalanced });
|
||||
return deletedResult;
|
||||
}
|
||||
|
||||
|
@ -409,14 +412,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
|
||||
return _getMaxHeight(beginRoot);
|
||||
} else {
|
||||
const stack: {node: N; depth: number}[] = [{node: beginRoot, depth: 0}];
|
||||
const stack: { node: N; depth: number }[] = [{ node: beginRoot, depth: 0 }];
|
||||
let maxHeight = 0;
|
||||
|
||||
while (stack.length > 0) {
|
||||
const {node, depth} = stack.pop()!;
|
||||
const { node, depth } = stack.pop()!;
|
||||
|
||||
if (node.left) stack.push({node: node.left, depth: depth + 1});
|
||||
if (node.right) stack.push({node: node.right, depth: depth + 1});
|
||||
if (node.left) stack.push({ node: node.left, depth: depth + 1 });
|
||||
if (node.right) stack.push({ node: node.right, depth: depth + 1 });
|
||||
|
||||
maxHeight = Math.max(maxHeight, depth);
|
||||
}
|
||||
|
@ -912,7 +915,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @returns The function `getLeftMost` returns the leftmost node (`N`) in the binary tree. If there
|
||||
* is no leftmost node, it returns `null` or `undefined` depending on the input.
|
||||
*/
|
||||
getLeftMost(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
|
||||
getLeftMost(
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
|
||||
if (!beginRoot) return beginRoot;
|
||||
|
@ -955,7 +961,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If there
|
||||
* is no rightmost node, it returns `null` or `undefined`, depending on the input.
|
||||
*/
|
||||
getRightMost(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
|
||||
getRightMost(
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
// TODO support get right most by passing key in
|
||||
beginRoot = this.ensureNotKey(beginRoot);
|
||||
if (!beginRoot) return beginRoot;
|
||||
|
@ -1284,7 +1293,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
_traverse(beginRoot);
|
||||
} else {
|
||||
// 0: visit, 1: print
|
||||
const stack: {opt: 0 | 1; node: N | null | undefined}[] = [{opt: 0, node: beginRoot}];
|
||||
const stack: { opt: 0 | 1; node: N | null | undefined }[] = [{ opt: 0, node: beginRoot }];
|
||||
|
||||
while (stack.length > 0) {
|
||||
const cur = stack.pop();
|
||||
|
@ -1299,24 +1308,24 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
} else {
|
||||
switch (pattern) {
|
||||
case 'in':
|
||||
cur.node && stack.push({opt: 0, node: cur.node.right});
|
||||
stack.push({opt: 1, node: cur.node});
|
||||
cur.node && stack.push({opt: 0, node: cur.node.left});
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.right });
|
||||
stack.push({ opt: 1, node: cur.node });
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.left });
|
||||
break;
|
||||
case 'pre':
|
||||
cur.node && stack.push({opt: 0, node: cur.node.right});
|
||||
cur.node && stack.push({opt: 0, node: cur.node.left});
|
||||
stack.push({opt: 1, node: cur.node});
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.right });
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.left });
|
||||
stack.push({ opt: 1, node: cur.node });
|
||||
break;
|
||||
case 'post':
|
||||
stack.push({opt: 1, node: cur.node});
|
||||
cur.node && stack.push({opt: 0, node: cur.node.right});
|
||||
cur.node && stack.push({opt: 0, node: cur.node.left});
|
||||
stack.push({ opt: 1, node: cur.node });
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.right });
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.left });
|
||||
break;
|
||||
default:
|
||||
cur.node && stack.push({opt: 0, node: cur.node.right});
|
||||
stack.push({opt: 1, node: cur.node});
|
||||
cur.node && stack.push({opt: 0, node: cur.node.left});
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.right });
|
||||
stack.push({ opt: 1, node: cur.node });
|
||||
cur.node && stack.push({ opt: 0, node: cur.node.left });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1798,7 +1807,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
destNode = this.ensureNotKey(destNode);
|
||||
|
||||
if (srcNode && destNode) {
|
||||
const {key, value} = destNode;
|
||||
const { key, value } = destNode;
|
||||
const tempNode = this.createNode(key, value);
|
||||
|
||||
if (tempNode) {
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {BSTComparator, BSTNodeNested, BSTOptions, BTNCallback, BTNKey} from '../../types';
|
||||
import {CP, IterationType} from '../../types';
|
||||
import {BinaryTree, BinaryTreeNode} from './binary-tree';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {Queue} from '../queue';
|
||||
import type { BSTComparator, BSTNodeNested, BSTOptions, BTNCallback, BTNKey } from '../../types';
|
||||
import { CP, IterationType } from '../../types';
|
||||
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { Queue } from '../queue';
|
||||
|
||||
export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
|
||||
override parent?: N;
|
||||
|
@ -62,7 +62,10 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|||
}
|
||||
}
|
||||
|
||||
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>> extends BinaryTree<V, N> implements IBinaryTree<V, N> {
|
||||
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
|
||||
extends BinaryTree<V, N>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
/**
|
||||
* The constructor function initializes a binary search tree with an optional comparator function.
|
||||
* @param {BSTOptions} [options] - An optional object that contains additional configuration options
|
||||
|
@ -72,7 +75,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
super(options);
|
||||
this._root = undefined;
|
||||
if (options !== undefined) {
|
||||
const {comparator} = options;
|
||||
const { comparator } = options;
|
||||
if (comparator !== undefined) {
|
||||
this._comparator = comparator;
|
||||
}
|
||||
|
@ -225,7 +228,9 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
|
||||
const inserted: (N | undefined)[] = [];
|
||||
const combinedArr: [BTNKey | N, V][] = keysOrNodes.map((value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]);
|
||||
const combinedArr: [BTNKey | N, V][] = keysOrNodes.map(
|
||||
(value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]
|
||||
);
|
||||
|
||||
let sorted = [];
|
||||
|
||||
|
|
|
@ -6,12 +6,23 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import {BiTreeDeleteResult, BTNCallback, BTNKey, IterationType, RBTNColor, RBTreeOptions, RedBlackTreeNodeNested} from '../../types';
|
||||
import {BST, BSTNode} from './bst';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {BinaryTreeNode} from './binary-tree';
|
||||
import {
|
||||
BiTreeDeleteResult,
|
||||
BTNCallback,
|
||||
BTNKey,
|
||||
IterationType,
|
||||
RBTNColor,
|
||||
RBTreeOptions,
|
||||
RedBlackTreeNodeNested
|
||||
} from '../../types';
|
||||
import { BST, BSTNode } from './bst';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { BinaryTreeNode } from './binary-tree';
|
||||
|
||||
export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<V, N> {
|
||||
export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNodeNested<V>> extends BSTNode<
|
||||
V,
|
||||
N
|
||||
> {
|
||||
color: RBTNColor;
|
||||
|
||||
constructor(key: BTNKey, value?: V, color: RBTNColor = RBTNColor.BLACK) {
|
||||
|
@ -29,7 +40,8 @@ export class RedBlackTreeNode<V = any, N extends RedBlackTreeNode<V, N> = RedBla
|
|||
*/
|
||||
export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTreeNode<V, RedBlackTreeNodeNested<V>>>
|
||||
extends BST<V, N>
|
||||
implements IBinaryTree<V, N> {
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
NIL: N = new RedBlackTreeNode<V>(NaN) as unknown as N;
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import type {SegmentTreeNodeVal} from '../../types';
|
||||
import type { SegmentTreeNodeVal } from '../../types';
|
||||
|
||||
export class SegmentTreeNode {
|
||||
start = 0;
|
||||
|
|
|
@ -5,12 +5,15 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {BTNKey, TreeMultimapNodeNested, TreeMultimapOptions} from '../../types';
|
||||
import {BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType} from '../../types';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {AVLTree, AVLTreeNode} from './avl-tree';
|
||||
import type { BTNKey, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types';
|
||||
import { BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { AVLTree, AVLTreeNode } from './avl-tree';
|
||||
|
||||
export class TreeMultimapNode<V = any, N extends TreeMultimapNode<V, N> = TreeMultimapNodeNested<V>> extends AVLTreeNode<V, N> {
|
||||
export class TreeMultimapNode<
|
||||
V = any,
|
||||
N extends TreeMultimapNode<V, N> = TreeMultimapNodeNested<V>
|
||||
> extends AVLTreeNode<V, N> {
|
||||
count: number;
|
||||
|
||||
/**
|
||||
|
@ -34,7 +37,8 @@ export class TreeMultimapNode<V = any, N extends TreeMultimapNode<V, N> = TreeMu
|
|||
*/
|
||||
export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultimapNode<V, TreeMultimapNodeNested<V>>>
|
||||
extends AVLTree<V, N>
|
||||
implements IBinaryTree<V, N> {
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
/**
|
||||
* The constructor function for a TreeMultimap class in TypeScript, which extends another class and sets an option to
|
||||
* merge duplicated values.
|
||||
|
@ -292,7 +296,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
if (!parent) {
|
||||
if (curr.right !== undefined) this._setRoot(curr.right);
|
||||
} else {
|
||||
const {familyPosition: fp} = curr;
|
||||
const { familyPosition: fp } = curr;
|
||||
if (fp === FamilyPosition.LEFT || fp === FamilyPosition.ROOT_LEFT) {
|
||||
parent.left = curr.right;
|
||||
} else if (fp === FamilyPosition.RIGHT || fp === FamilyPosition.ROOT_RIGHT) {
|
||||
|
@ -320,7 +324,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
if (orgCurrent) this._count -= orgCurrent.count;
|
||||
}
|
||||
|
||||
deletedResult.push({deleted: orgCurrent, needBalanced});
|
||||
deletedResult.push({ deleted: orgCurrent, needBalanced });
|
||||
|
||||
if (needBalanced) {
|
||||
this._balancePath(needBalanced);
|
||||
|
@ -396,7 +400,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
srcNode = this.ensureNotKey(srcNode);
|
||||
destNode = this.ensureNotKey(destNode);
|
||||
if (srcNode && destNode) {
|
||||
const {key, value, count, height} = destNode;
|
||||
const { key, value, count, height } = destNode;
|
||||
const tempNode = this.createNode(key, value, count);
|
||||
if (tempNode) {
|
||||
tempNode.height = height;
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {uuidV4} from '../../utils';
|
||||
import {PriorityQueue} from '../priority-queue';
|
||||
import type {DijkstraResult, VertexKey} from '../../types';
|
||||
import {IGraph} from '../../interfaces';
|
||||
import {Queue} from '../queue';
|
||||
import { uuidV4 } from '../../utils';
|
||||
import { PriorityQueue } from '../priority-queue';
|
||||
import type { DijkstraResult, VertexKey } from '../../types';
|
||||
import { IGraph } from '../../interfaces';
|
||||
import { Queue } from '../queue';
|
||||
|
||||
export abstract class AbstractVertex<V = any> {
|
||||
key: VertexKey;
|
||||
|
@ -64,7 +64,8 @@ export abstract class AbstractGraph<
|
|||
E = any,
|
||||
VO extends AbstractVertex<V> = AbstractVertex<V>,
|
||||
EO extends AbstractEdge<E> = AbstractEdge<E>
|
||||
> implements IGraph<V, E, VO, EO> {
|
||||
> implements IGraph<V, E, VO, EO>
|
||||
{
|
||||
protected _vertices: Map<VertexKey, VO> = new Map<VertexKey, VO>();
|
||||
|
||||
get vertices(): Map<VertexKey, VO> {
|
||||
|
@ -300,11 +301,11 @@ export abstract class AbstractGraph<
|
|||
return [];
|
||||
}
|
||||
|
||||
const stack: {vertex: VO; path: VO[]}[] = [];
|
||||
stack.push({vertex: vertex1, path: [vertex1]});
|
||||
const stack: { vertex: VO; path: VO[] }[] = [];
|
||||
stack.push({ vertex: vertex1, path: [vertex1] });
|
||||
|
||||
while (stack.length > 0) {
|
||||
const {vertex, path} = stack.pop()!;
|
||||
const { vertex, path } = stack.pop()!;
|
||||
|
||||
if (vertex === vertex2) {
|
||||
paths.push(path);
|
||||
|
@ -315,7 +316,7 @@ export abstract class AbstractGraph<
|
|||
for (const neighbor of neighbors) {
|
||||
if (!path.includes(neighbor)) {
|
||||
const newPath = [...path, neighbor];
|
||||
stack.push({vertex: neighbor, path: newPath});
|
||||
stack.push({ vertex: neighbor, path: newPath });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -514,7 +515,12 @@ export abstract class AbstractGraph<
|
|||
* shortest paths from the source vertex to all other vertices in the graph. If `genPaths
|
||||
* @returns The function `dijkstraWithoutHeap` returns an object of type `DijkstraResult<VO>`.
|
||||
*/
|
||||
dijkstraWithoutHeap(src: VO | VertexKey, dest?: VO | VertexKey | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<VO> {
|
||||
dijkstraWithoutHeap(
|
||||
src: VO | VertexKey,
|
||||
dest?: VO | VertexKey | null,
|
||||
getMinDist?: boolean,
|
||||
genPaths?: boolean
|
||||
): DijkstraResult<VO> {
|
||||
if (getMinDist === undefined) getMinDist = false;
|
||||
if (genPaths === undefined) genPaths = false;
|
||||
|
||||
|
@ -586,7 +592,7 @@ export abstract class AbstractGraph<
|
|||
if (genPaths) {
|
||||
getPaths(destVertex);
|
||||
}
|
||||
return {distMap, preMap, seen, paths, minDist, minPath};
|
||||
return { distMap, preMap, seen, paths, minDist, minPath };
|
||||
}
|
||||
const neighbors = this.getNeighbors(cur);
|
||||
for (const neighbor of neighbors) {
|
||||
|
@ -620,7 +626,7 @@ export abstract class AbstractGraph<
|
|||
|
||||
genPaths && getPaths(minDest);
|
||||
|
||||
return {distMap, preMap, seen, paths, minDist, minPath};
|
||||
return { distMap, preMap, seen, paths, minDist, minPath };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -657,7 +663,12 @@ export abstract class AbstractGraph<
|
|||
* shortest paths from the source vertex to all other vertices in the graph. If `genPaths
|
||||
* @returns The function `dijkstra` returns an object of type `DijkstraResult<VO>`.
|
||||
*/
|
||||
dijkstra(src: VO | VertexKey, dest?: VO | VertexKey | null, getMinDist?: boolean, genPaths?: boolean): DijkstraResult<VO> {
|
||||
dijkstra(
|
||||
src: VO | VertexKey,
|
||||
dest?: VO | VertexKey | null,
|
||||
getMinDist?: boolean,
|
||||
genPaths?: boolean
|
||||
): DijkstraResult<VO> {
|
||||
if (getMinDist === undefined) getMinDist = false;
|
||||
if (genPaths === undefined) genPaths = false;
|
||||
|
||||
|
@ -681,8 +692,8 @@ export abstract class AbstractGraph<
|
|||
if (vertexOrKey instanceof AbstractVertex) distMap.set(vertexOrKey, Infinity);
|
||||
}
|
||||
|
||||
const heap = new PriorityQueue<{key: number; value: VO}>({comparator: (a, b) => a.key - b.key});
|
||||
heap.add({key: 0, value: srcVertex});
|
||||
const heap = new PriorityQueue<{ key: number; value: VO }>({ comparator: (a, b) => a.key - b.key });
|
||||
heap.add({ key: 0, value: srcVertex });
|
||||
|
||||
distMap.set(srcVertex, 0);
|
||||
preMap.set(srcVertex, null);
|
||||
|
@ -723,7 +734,7 @@ export abstract class AbstractGraph<
|
|||
if (genPaths) {
|
||||
getPaths(destVertex);
|
||||
}
|
||||
return {distMap, preMap, seen, paths, minDist, minPath};
|
||||
return { distMap, preMap, seen, paths, minDist, minPath };
|
||||
}
|
||||
const neighbors = this.getNeighbors(cur);
|
||||
for (const neighbor of neighbors) {
|
||||
|
@ -733,7 +744,7 @@ export abstract class AbstractGraph<
|
|||
const distSrcToNeighbor = distMap.get(neighbor);
|
||||
if (distSrcToNeighbor) {
|
||||
if (dist + weight < distSrcToNeighbor) {
|
||||
heap.add({key: dist + weight, value: neighbor});
|
||||
heap.add({ key: dist + weight, value: neighbor });
|
||||
preMap.set(neighbor, cur);
|
||||
distMap.set(neighbor, dist + weight);
|
||||
}
|
||||
|
@ -760,7 +771,7 @@ export abstract class AbstractGraph<
|
|||
getPaths(minDest);
|
||||
}
|
||||
|
||||
return {distMap, preMap, seen, paths, minDist, minPath};
|
||||
return { distMap, preMap, seen, paths, minDist, minPath };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -800,7 +811,7 @@ export abstract class AbstractGraph<
|
|||
// TODO
|
||||
let hasNegativeCycle: boolean | undefined;
|
||||
if (scanNegativeCycle) hasNegativeCycle = false;
|
||||
if (!srcVertex) return {hasNegativeCycle, distMap, preMap, paths, min, minPath};
|
||||
if (!srcVertex) return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
|
||||
|
||||
const vertices = this._vertices;
|
||||
const numOfVertices = vertices.size;
|
||||
|
@ -872,7 +883,7 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
}
|
||||
|
||||
return {hasNegativeCycle, distMap, preMap, paths, min, minPath};
|
||||
return { hasNegativeCycle, distMap, preMap, paths, min, minPath };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -913,7 +924,7 @@ export abstract class AbstractGraph<
|
|||
* `predecessor` property is a 2D array of vertices (or `null`) representing the predecessor vertices in the shortest
|
||||
* path between vertices in the
|
||||
*/
|
||||
floydWarshall(): {costs: number[][]; predecessor: (VO | null)[][]} {
|
||||
floydWarshall(): { costs: number[][]; predecessor: (VO | null)[][] } {
|
||||
const idAndVertices = [...this._vertices];
|
||||
const n = idAndVertices.length;
|
||||
|
||||
|
@ -945,7 +956,7 @@ export abstract class AbstractGraph<
|
|||
}
|
||||
}
|
||||
}
|
||||
return {costs, predecessor};
|
||||
return { costs, predecessor };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -982,7 +993,12 @@ export abstract class AbstractGraph<
|
|||
* are arrays of vertices that form cycles within the SCCs.
|
||||
* @returns The function `tarjan` returns an object with the following properties:
|
||||
*/
|
||||
tarjan(needCutVertexes: boolean = false, needBridges: boolean = false, needSCCs: boolean = true, needCycles: boolean = false) {
|
||||
tarjan(
|
||||
needCutVertexes: boolean = false,
|
||||
needBridges: boolean = false,
|
||||
needSCCs: boolean = true,
|
||||
needCycles: boolean = false
|
||||
) {
|
||||
// !! in undirected graph we will not let child visit parent when dfs
|
||||
// !! articulation point(in dfs search tree not in graph): (cur !== root && cur.has(child)) && (low(child) >= dfn(cur)) || (cur === root && cur.children() >= 2)
|
||||
// !! bridge: low(child) > dfn(cur)
|
||||
|
@ -1081,7 +1097,7 @@ export abstract class AbstractGraph<
|
|||
});
|
||||
}
|
||||
|
||||
return {dfnMap, lowMap, bridges, cutVertexes, SCCs, cycles};
|
||||
return { dfnMap, lowMap, bridges, cutVertexes, SCCs, cycles };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {arrayRemove} from '../../utils';
|
||||
import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
|
||||
import type {TopologicalStatus, VertexKey} from '../../types';
|
||||
import {IGraph} from '../../interfaces';
|
||||
import { arrayRemove } from '../../utils';
|
||||
import { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';
|
||||
import type { TopologicalStatus, VertexKey } from '../../types';
|
||||
import { IGraph } from '../../interfaces';
|
||||
|
||||
export class DirectedVertex<V = any> extends AbstractVertex<V> {
|
||||
/**
|
||||
|
@ -45,9 +45,15 @@ export class DirectedEdge<E = any> extends AbstractEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
export class DirectedGraph<V = any, E = any, VO extends DirectedVertex<V> = DirectedVertex<V>, EO extends DirectedEdge<E> = DirectedEdge<E>>
|
||||
export class DirectedGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends DirectedVertex<V> = DirectedVertex<V>,
|
||||
EO extends DirectedEdge<E> = DirectedEdge<E>
|
||||
>
|
||||
extends AbstractGraph<V, E, VO, EO>
|
||||
implements IGraph<V, E, VO, EO> {
|
||||
implements IGraph<V, E, VO, EO>
|
||||
{
|
||||
/**
|
||||
* The constructor function initializes an instance of a class.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {MapGraphCoordinate, VertexKey} from '../../types';
|
||||
import {DirectedEdge, DirectedGraph, DirectedVertex} from './directed-graph';
|
||||
import { MapGraphCoordinate, VertexKey } from '../../types';
|
||||
import { DirectedEdge, DirectedGraph, DirectedVertex } from './directed-graph';
|
||||
|
||||
export class MapVertex<V = any> extends DirectedVertex<V> {
|
||||
lat: number;
|
||||
|
@ -40,12 +40,12 @@ export class MapEdge<E = any> extends DirectedEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
export class MapGraph<V = any, E = any, VO extends MapVertex<V> = MapVertex<V>, EO extends MapEdge<E> = MapEdge<E>> extends DirectedGraph<
|
||||
V,
|
||||
E,
|
||||
VO,
|
||||
EO
|
||||
> {
|
||||
export class MapGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends MapVertex<V> = MapVertex<V>,
|
||||
EO extends MapEdge<E> = MapEdge<E>
|
||||
> extends DirectedGraph<V, E, VO, EO> {
|
||||
/**
|
||||
* The constructor function initializes the origin and bottomRight properties of a MapGraphCoordinate object.
|
||||
* @param {MapGraphCoordinate} origin - The `origin` parameter is a `MapGraphCoordinate` object that represents the
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {arrayRemove} from '../../utils';
|
||||
import {AbstractEdge, AbstractGraph, AbstractVertex} from './abstract-graph';
|
||||
import type {VertexKey} from '../../types';
|
||||
import {IGraph} from '../../interfaces';
|
||||
import { arrayRemove } from '../../utils';
|
||||
import { AbstractEdge, AbstractGraph, AbstractVertex } from './abstract-graph';
|
||||
import type { VertexKey } from '../../types';
|
||||
import { IGraph } from '../../interfaces';
|
||||
|
||||
export class UndirectedVertex<V = any> extends AbstractVertex<V> {
|
||||
/**
|
||||
|
@ -49,7 +49,8 @@ export class UndirectedGraph<
|
|||
EO extends UndirectedEdge<E> = UndirectedEdge<E>
|
||||
>
|
||||
extends AbstractGraph<V, E, VO, EO>
|
||||
implements IGraph<V, E, VO, EO> {
|
||||
implements IGraph<V, E, VO, EO>
|
||||
{
|
||||
/**
|
||||
* The constructor initializes a new Map object to store edges.
|
||||
*/
|
||||
|
|
|
@ -6,19 +6,18 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import {isObjOrFunc, rangeCheck, throwRangeError} from "../../utils";
|
||||
import {HashMapLinkedNode, HashMapOptions, IterateDirection} from "../../types";
|
||||
import { isObjOrFunc, rangeCheck, throwRangeError } from '../../utils';
|
||||
import { HashMapLinkedNode, HashMapOptions, IterateDirection } from '../../types';
|
||||
|
||||
/**
|
||||
* Because the implementation of HashMap relies on JavaScript's built-in objects and arrays,
|
||||
* these underlying structures have already dealt with dynamic expansion and hash collisions.
|
||||
* Therefore, there is no need for additional logic to handle these issues.
|
||||
*/
|
||||
class HashMapIterator<K, V> {
|
||||
export class HashMapIterator<K, V> {
|
||||
readonly hashMap: HashMap<K, V>;
|
||||
|
||||
protected _node: HashMapLinkedNode<K, V>;
|
||||
readonly iterateDirection: IterateDirection;
|
||||
protected _node: HashMapLinkedNode<K, V>;
|
||||
protected readonly _sentinel: HashMapLinkedNode<K, V>;
|
||||
|
||||
/**
|
||||
|
@ -36,13 +35,16 @@ class HashMapIterator<K, V> {
|
|||
* @returns The constructor does not return anything. It is used to initialize the properties and
|
||||
* methods of the object being created.
|
||||
*/
|
||||
constructor(node: HashMapLinkedNode<K, V>, sentinel: HashMapLinkedNode<K, V>,
|
||||
hashMap: HashMap<K, V>, iterateDirection: IterateDirection = IterateDirection.DEFAULT) {
|
||||
constructor(
|
||||
node: HashMapLinkedNode<K, V>,
|
||||
sentinel: HashMapLinkedNode<K, V>,
|
||||
hashMap: HashMap<K, V>,
|
||||
iterateDirection: IterateDirection = IterateDirection.DEFAULT
|
||||
) {
|
||||
this._node = node;
|
||||
this._sentinel = sentinel;
|
||||
this.iterateDirection = iterateDirection;
|
||||
|
||||
|
||||
if (this.iterateDirection === IterateDirection.DEFAULT) {
|
||||
this.prev = function () {
|
||||
if (this._node.prev === this._sentinel) {
|
||||
|
@ -87,7 +89,7 @@ class HashMapIterator<K, V> {
|
|||
throwRangeError();
|
||||
}
|
||||
|
||||
return new Proxy(<[K, V]><unknown>[], {
|
||||
return new Proxy(<[K, V]>(<unknown>[]), {
|
||||
get: (target, prop: '0' | '1') => {
|
||||
if (prop === '0') return this._node.key;
|
||||
else if (prop === '1') return this._node.value;
|
||||
|
@ -113,7 +115,6 @@ class HashMapIterator<K, V> {
|
|||
return this._node !== this._sentinel;
|
||||
}
|
||||
|
||||
|
||||
prev() {
|
||||
return this;
|
||||
}
|
||||
|
@ -124,18 +125,12 @@ class HashMapIterator<K, V> {
|
|||
}
|
||||
|
||||
export class HashMap<K = any, V = any> {
|
||||
readonly OBJ_KEY_INDEX = Symbol('OBJ_KEY_INDEX');
|
||||
protected _nodes: HashMapLinkedNode<K, V>[] = [];
|
||||
protected _orgMap: Record<string, HashMapLinkedNode<K, V>> = {};
|
||||
protected _head: HashMapLinkedNode<K, V>;
|
||||
protected _tail: HashMapLinkedNode<K, V>;
|
||||
protected readonly _sentinel: HashMapLinkedNode<K, V>;
|
||||
readonly OBJ_KEY_INDEX = Symbol('OBJ_KEY_INDEX');
|
||||
|
||||
protected _size = 0;
|
||||
|
||||
get size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor initializes a HashMap object with an optional initial set of key-value pairs.
|
||||
|
@ -151,217 +146,14 @@ export class HashMap<K = any, V = any> {
|
|||
hashMap.forEach(el => {
|
||||
this.set(el[0], el[1]);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `set` function adds a new key-value pair to a data structure, either using an object key or a
|
||||
* string key.
|
||||
* @param {K} key - The `key` parameter is the key to be set in the data structure. It can be of any
|
||||
* type, but typically it is a string or symbol.
|
||||
* @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the
|
||||
* value associated with the key being set in the data structure.
|
||||
* @param {boolean} isObjectKey - A boolean flag indicating whether the key is an object key or not.
|
||||
* @returns the size of the data structure after the key-value pair has been set.
|
||||
*/
|
||||
set(key: K, value?: V, isObjectKey: boolean = isObjOrFunc(key)) {
|
||||
let newTail;
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
|
||||
if (index !== undefined) {
|
||||
this._nodes[<number>index].value = <V>value;
|
||||
return this._size;
|
||||
}
|
||||
Object.defineProperty(key, this.OBJ_KEY_INDEX, {
|
||||
value: this._nodes.length,
|
||||
configurable: true
|
||||
});
|
||||
newTail = {
|
||||
key: key,
|
||||
value: <V>value,
|
||||
prev: this._tail,
|
||||
next: this._sentinel
|
||||
};
|
||||
this._nodes.push(newTail);
|
||||
} else {
|
||||
const node = this._orgMap[<string><unknown>key];
|
||||
if (node) {
|
||||
node.value = <V>value;
|
||||
return this._size;
|
||||
}
|
||||
this._orgMap[<string><unknown>key] = newTail = {
|
||||
key: key,
|
||||
value: <V>value,
|
||||
prev: this._tail,
|
||||
next: this._sentinel
|
||||
};
|
||||
}
|
||||
if (this._size === 0) {
|
||||
this._head = newTail;
|
||||
this._sentinel.next = newTail;
|
||||
} else {
|
||||
this._tail.next = newTail;
|
||||
}
|
||||
this._tail = newTail;
|
||||
this._sentinel.prev = newTail;
|
||||
return ++this._size;
|
||||
}
|
||||
protected _size = 0;
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `get` retrieves the value associated with a given key from a map, either by using the
|
||||
* key directly or by using an index stored in the key object.
|
||||
* @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
|
||||
* of any type, but typically it is a string or symbol.
|
||||
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
|
||||
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that
|
||||
* `key` is an object key. If `isObjectKey` is `false`, it means that `key`
|
||||
* @returns The value associated with the given key is being returned. If the key is an object key,
|
||||
* the value is retrieved from the `_nodes` array using the index stored in the `OBJ_KEY_INDEX`
|
||||
* property of the key. If the key is a string key, the value is retrieved from the `_orgMap` object
|
||||
* using the key itself. If the key is not found, `undefined` is
|
||||
*/
|
||||
get(key: K, isObjectKey: boolean = isObjOrFunc(key)) {
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
|
||||
return index !== undefined ? this._nodes[index].value : undefined;
|
||||
}
|
||||
const node = this._orgMap[<string><unknown>key];
|
||||
return node ? node.value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the index.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getAt` retrieves the key-value pair at a specified index in a linked list.
|
||||
* @param {number} index - The index parameter is a number that represents the position of the
|
||||
* element we want to retrieve from the data structure.
|
||||
* @returns The method `getAt(index: number)` is returning an array containing the key-value pair at
|
||||
* the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
|
||||
* where `K` is the key and `V` is the value.
|
||||
*/
|
||||
getAt(index: number) {
|
||||
rangeCheck(index, 0, this._size - 1);
|
||||
let node = this._head;
|
||||
while (index--) {
|
||||
node = node.next;
|
||||
}
|
||||
return <[K, V]>[node.key, node.value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getIterator` returns a new instance of `HashMapIterator` based on the provided key
|
||||
* and whether it is an object key or not.
|
||||
* @param {K} key - The `key` parameter is the key used to retrieve the iterator from the HashMap. It
|
||||
* can be of any type, depending on how the HashMap is implemented.
|
||||
* @param {boolean} [isObjectKey] - The `isObjectKey` parameter is an optional boolean parameter that
|
||||
* indicates whether the `key` parameter is an object key. If `isObjectKey` is `true`, it means that
|
||||
* the `key` parameter is an object and needs to be handled differently. If `isObjectKey` is `false`
|
||||
* @returns a new instance of the `HashMapIterator` class.
|
||||
*/
|
||||
getIterator(key: K, isObjectKey?: boolean) {
|
||||
let node: HashMapLinkedNode<K, V>
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
|
||||
if (index === undefined) {
|
||||
node = this._sentinel
|
||||
} else {
|
||||
node = this._nodes[index];
|
||||
}
|
||||
} else {
|
||||
node = this._orgMap[<string><unknown>key] || this._sentinel;
|
||||
}
|
||||
return new HashMapIterator<K, V>(node, this._sentinel, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `delete` function removes a key-value pair from a map-like data structure.
|
||||
* @param {K} key - The `key` parameter is the key that you want to delete from the data structure.
|
||||
* It can be of any type, but typically it is a string or an object.
|
||||
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
|
||||
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that the
|
||||
* `key` parameter is an object key. If `isObjectKey` is `false`, it means that the
|
||||
* @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
|
||||
* was not found.
|
||||
*/
|
||||
delete(key: K, isObjectKey: boolean = isObjOrFunc(key)) {
|
||||
let node;
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
|
||||
if (index === undefined) return false;
|
||||
delete (<Record<symbol, number>><unknown>key)[this.OBJ_KEY_INDEX];
|
||||
node = this._nodes[index];
|
||||
delete this._nodes[index];
|
||||
} else {
|
||||
node = this._orgMap[<string><unknown>key];
|
||||
if (node === undefined) return false;
|
||||
delete this._orgMap[<string><unknown>key];
|
||||
}
|
||||
this._deleteNode(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the index.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `deleteAt` function deletes a node at a specified index in a linked list.
|
||||
* @param {number} index - The index parameter represents the position at which the node should be
|
||||
* deleted in the linked list.
|
||||
* @returns The size of the list after deleting the element at the specified index.
|
||||
*/
|
||||
deleteAt(index: number) {
|
||||
rangeCheck(index, 0, this._size - 1);
|
||||
let node = this._head;
|
||||
while (index--) {
|
||||
node = node.next;
|
||||
}
|
||||
this._deleteNode(node);
|
||||
get size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function checks if a data structure is empty by comparing its size to zero.
|
||||
* @returns The method is returning a boolean value indicating whether the size of the object is 0 or
|
||||
* not.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this._size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `clear` function clears all the elements in a data structure and resets its properties.
|
||||
*/
|
||||
clear() {
|
||||
// const OBJ_KEY_INDEX = this.OBJ_KEY_INDEX;
|
||||
// this._nodes.forEach(el => {
|
||||
// delete (<Record<symbol, number>><unknown>el.key)[OBJ_KEY_INDEX];
|
||||
// });
|
||||
this._nodes = [];
|
||||
this._orgMap = {};
|
||||
Object.setPrototypeOf(this._orgMap, null);
|
||||
this._size = 0;
|
||||
this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
|
@ -435,6 +227,214 @@ export class HashMap<K = any, V = any> {
|
|||
return <[K, V]>[this._tail.key, this._tail.value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `set` function adds a new key-value pair to a data structure, either using an object key or a
|
||||
* string key.
|
||||
* @param {K} key - The `key` parameter is the key to be set in the data structure. It can be of any
|
||||
* type, but typically it is a string or symbol.
|
||||
* @param {V} [value] - The `value` parameter is an optional parameter of type `V`. It represents the
|
||||
* value associated with the key being set in the data structure.
|
||||
* @param {boolean} isObjectKey - A boolean flag indicating whether the key is an object key or not.
|
||||
* @returns the size of the data structure after the key-value pair has been set.
|
||||
*/
|
||||
set(key: K, value?: V, isObjectKey: boolean = isObjOrFunc(key)) {
|
||||
let newTail;
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>>(<unknown>key))[this.OBJ_KEY_INDEX];
|
||||
if (index !== undefined) {
|
||||
this._nodes[<number>index].value = <V>value;
|
||||
return this._size;
|
||||
}
|
||||
Object.defineProperty(key, this.OBJ_KEY_INDEX, {
|
||||
value: this._nodes.length,
|
||||
configurable: true
|
||||
});
|
||||
newTail = {
|
||||
key: key,
|
||||
value: <V>value,
|
||||
prev: this._tail,
|
||||
next: this._sentinel
|
||||
};
|
||||
this._nodes.push(newTail);
|
||||
} else {
|
||||
const node = this._orgMap[<string>(<unknown>key)];
|
||||
if (node) {
|
||||
node.value = <V>value;
|
||||
return this._size;
|
||||
}
|
||||
this._orgMap[<string>(<unknown>key)] = newTail = {
|
||||
key: key,
|
||||
value: <V>value,
|
||||
prev: this._tail,
|
||||
next: this._sentinel
|
||||
};
|
||||
}
|
||||
if (this._size === 0) {
|
||||
this._head = newTail;
|
||||
this._sentinel.next = newTail;
|
||||
} else {
|
||||
this._tail.next = newTail;
|
||||
}
|
||||
this._tail = newTail;
|
||||
this._sentinel.prev = newTail;
|
||||
return ++this._size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `get` retrieves the value associated with a given key from a map, either by using the
|
||||
* key directly or by using an index stored in the key object.
|
||||
* @param {K} key - The `key` parameter is the key used to retrieve a value from the map. It can be
|
||||
* of any type, but typically it is a string or symbol.
|
||||
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
|
||||
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that
|
||||
* `key` is an object key. If `isObjectKey` is `false`, it means that `key`
|
||||
* @returns The value associated with the given key is being returned. If the key is an object key,
|
||||
* the value is retrieved from the `_nodes` array using the index stored in the `OBJ_KEY_INDEX`
|
||||
* property of the key. If the key is a string key, the value is retrieved from the `_orgMap` object
|
||||
* using the key itself. If the key is not found, `undefined` is
|
||||
*/
|
||||
get(key: K, isObjectKey: boolean = isObjOrFunc(key)) {
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>>(<unknown>key))[this.OBJ_KEY_INDEX];
|
||||
return index !== undefined ? this._nodes[index].value : undefined;
|
||||
}
|
||||
const node = this._orgMap[<string>(<unknown>key)];
|
||||
return node ? node.value : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the index.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getAt` retrieves the key-value pair at a specified index in a linked list.
|
||||
* @param {number} index - The index parameter is a number that represents the position of the
|
||||
* element we want to retrieve from the data structure.
|
||||
* @returns The method `getAt(index: number)` is returning an array containing the key-value pair at
|
||||
* the specified index in the data structure. The key-value pair is represented as a tuple `[K, V]`,
|
||||
* where `K` is the key and `V` is the value.
|
||||
*/
|
||||
getAt(index: number) {
|
||||
rangeCheck(index, 0, this._size - 1);
|
||||
let node = this._head;
|
||||
while (index--) {
|
||||
node = node.next;
|
||||
}
|
||||
return <[K, V]>[node.key, node.value];
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getIterator` returns a new instance of `HashMapIterator` based on the provided key
|
||||
* and whether it is an object key or not.
|
||||
* @param {K} key - The `key` parameter is the key used to retrieve the iterator from the HashMap. It
|
||||
* can be of any type, depending on how the HashMap is implemented.
|
||||
* @param {boolean} [isObjectKey] - The `isObjectKey` parameter is an optional boolean parameter that
|
||||
* indicates whether the `key` parameter is an object key. If `isObjectKey` is `true`, it means that
|
||||
* the `key` parameter is an object and needs to be handled differently. If `isObjectKey` is `false`
|
||||
* @returns a new instance of the `HashMapIterator` class.
|
||||
*/
|
||||
getIterator(key: K, isObjectKey?: boolean) {
|
||||
let node: HashMapLinkedNode<K, V>;
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>>(<unknown>key))[this.OBJ_KEY_INDEX];
|
||||
if (index === undefined) {
|
||||
node = this._sentinel;
|
||||
} else {
|
||||
node = this._nodes[index];
|
||||
}
|
||||
} else {
|
||||
node = this._orgMap[<string>(<unknown>key)] || this._sentinel;
|
||||
}
|
||||
return new HashMapIterator<K, V>(node, this._sentinel, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `delete` function removes a key-value pair from a map-like data structure.
|
||||
* @param {K} key - The `key` parameter is the key that you want to delete from the data structure.
|
||||
* It can be of any type, but typically it is a string or an object.
|
||||
* @param {boolean} isObjectKey - The `isObjectKey` parameter is a boolean flag that indicates
|
||||
* whether the `key` parameter is an object key or not. If `isObjectKey` is `true`, it means that the
|
||||
* `key` parameter is an object key. If `isObjectKey` is `false`, it means that the
|
||||
* @returns a boolean value. It returns `true` if the deletion was successful, and `false` if the key
|
||||
* was not found.
|
||||
*/
|
||||
delete(key: K, isObjectKey: boolean = isObjOrFunc(key)) {
|
||||
let node;
|
||||
if (isObjectKey) {
|
||||
const index = (<Record<symbol, number>>(<unknown>key))[this.OBJ_KEY_INDEX];
|
||||
if (index === undefined) return false;
|
||||
delete (<Record<symbol, number>>(<unknown>key))[this.OBJ_KEY_INDEX];
|
||||
node = this._nodes[index];
|
||||
delete this._nodes[index];
|
||||
} else {
|
||||
node = this._orgMap[<string>(<unknown>key)];
|
||||
if (node === undefined) return false;
|
||||
delete this._orgMap[<string>(<unknown>key)];
|
||||
}
|
||||
this._deleteNode(node);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the index.
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `deleteAt` function deletes a node at a specified index in a linked list.
|
||||
* @param {number} index - The index parameter represents the position at which the node should be
|
||||
* deleted in the linked list.
|
||||
* @returns The size of the list after deleting the element at the specified index.
|
||||
*/
|
||||
deleteAt(index: number) {
|
||||
rangeCheck(index, 0, this._size - 1);
|
||||
let node = this._head;
|
||||
while (index--) {
|
||||
node = node.next;
|
||||
}
|
||||
this._deleteNode(node);
|
||||
return this._size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function checks if a data structure is empty by comparing its size to zero.
|
||||
* @returns The method is returning a boolean value indicating whether the size of the object is 0 or
|
||||
* not.
|
||||
*/
|
||||
isEmpty() {
|
||||
return this._size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(1)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `clear` function clears all the elements in a data structure and resets its properties.
|
||||
*/
|
||||
clear() {
|
||||
// const OBJ_KEY_INDEX = this.OBJ_KEY_INDEX;
|
||||
// this._nodes.forEach(el => {
|
||||
// delete (<Record<symbol, number>><unknown>el.key)[OBJ_KEY_INDEX];
|
||||
// });
|
||||
this._nodes = [];
|
||||
this._orgMap = {};
|
||||
Object.setPrototypeOf(this._orgMap, null);
|
||||
this._size = 0;
|
||||
this._head = this._tail = this._sentinel.prev = this._sentinel.next = this._sentinel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Time Complexity: O(n), where n is the number of elements in the HashMap.
|
||||
* Space Complexity: O(1)
|
||||
|
@ -459,7 +459,7 @@ export class HashMap<K = any, V = any> {
|
|||
*
|
||||
* The above function is an iterator that yields key-value pairs from a linked list.
|
||||
*/
|
||||
* [Symbol.iterator]() {
|
||||
*[Symbol.iterator]() {
|
||||
let node = this._head;
|
||||
while (node !== this._sentinel) {
|
||||
yield <[K, V]>[node.key, node.value];
|
||||
|
@ -478,7 +478,7 @@ export class HashMap<K = any, V = any> {
|
|||
* and next nodes in the list.
|
||||
*/
|
||||
protected _deleteNode(node: HashMapLinkedNode<K, V>) {
|
||||
const {prev, next} = node;
|
||||
const { prev, next } = node;
|
||||
prev.next = next;
|
||||
next.prev = prev;
|
||||
if (node === this._head) {
|
||||
|
|
|
@ -18,7 +18,7 @@ export class HashTableNode<K, V> {
|
|||
}
|
||||
}
|
||||
|
||||
import {HashFunction} from '../../types';
|
||||
import { HashFunction } from '../../types';
|
||||
|
||||
export class HashTable<K, V> {
|
||||
protected static readonly DEFAULT_CAPACITY = 16;
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import type {Comparator, DFSOrderPattern} from '../../types';
|
||||
import type { Comparator, DFSOrderPattern } from '../../types';
|
||||
|
||||
export class Heap<E = any> {
|
||||
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
|
||||
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
|
||||
this._comparator = options.comparator;
|
||||
if (options.nodes && options.nodes.length > 0) {
|
||||
this._nodes = options.nodes;
|
||||
|
@ -48,7 +48,7 @@ export class Heap<E = any> {
|
|||
* @returns A new Heap instance.
|
||||
* @param options
|
||||
*/
|
||||
static heapify<E>(options: {nodes: E[]; comparator: Comparator<E>}): Heap<E> {
|
||||
static heapify<E>(options: { nodes: E[]; comparator: Comparator<E> }): Heap<E> {
|
||||
return new Heap<E>(options);
|
||||
}
|
||||
|
||||
|
@ -265,7 +265,7 @@ export class Heap<E = any> {
|
|||
* @returns A new Heap instance containing the same elements.
|
||||
*/
|
||||
clone(): Heap<E> {
|
||||
const clonedHeap = new Heap<E>({comparator: this.comparator});
|
||||
const clonedHeap = new Heap<E>({ comparator: this.comparator });
|
||||
clonedHeap._nodes = [...this.nodes];
|
||||
return clonedHeap;
|
||||
}
|
||||
|
@ -741,7 +741,10 @@ export class FibonacciHeap<E> {
|
|||
protected consolidate(): void {
|
||||
const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this.size);
|
||||
const nodes = this.consumeLinkedList(this.root);
|
||||
let x: FibonacciHeapNode<E> | undefined, y: FibonacciHeapNode<E> | undefined, d: number, t: FibonacciHeapNode<E> | undefined;
|
||||
let x: FibonacciHeapNode<E> | undefined,
|
||||
y: FibonacciHeapNode<E> | undefined,
|
||||
d: number,
|
||||
t: FibonacciHeapNode<E> | undefined;
|
||||
|
||||
for (const node of nodes) {
|
||||
x = node;
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import {Heap} from './heap';
|
||||
import type {Comparator} from '../../types';
|
||||
import { Heap } from './heap';
|
||||
import type { Comparator } from '../../types';
|
||||
|
||||
export class MaxHeap<E = any> extends Heap<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import {Heap} from './heap';
|
||||
import type {Comparator} from '../../types';
|
||||
import { Heap } from './heap';
|
||||
import type { Comparator } from '../../types';
|
||||
|
||||
export class MinHeap<E = any> extends Heap<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -14,8 +14,8 @@ export class MatrixNTI2D<V = any> {
|
|||
* given initial value or 0 if not provided.
|
||||
* @param options - An object containing the following properties:
|
||||
*/
|
||||
constructor(options: {row: number; col: number; initialVal?: V}) {
|
||||
const {row, col, initialVal} = options;
|
||||
constructor(options: { row: number; col: number; initialVal?: V }) {
|
||||
const { row, col, initialVal } = options;
|
||||
this._matrix = new Array(row).fill(undefined).map(() => new Array(col).fill(initialVal || 0));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {Vector2D} from './vector2d';
|
||||
import { Vector2D } from './vector2d';
|
||||
|
||||
export class Matrix2D {
|
||||
protected readonly _matrix: number[][];
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {Direction, NavigatorParams, Turning} from '../../types';
|
||||
import type { Direction, NavigatorParams, Turning } from '../../types';
|
||||
|
||||
export class Character {
|
||||
direction: Direction;
|
||||
|
@ -37,7 +37,7 @@ export class Navigator<T = number> {
|
|||
* in the matrix.
|
||||
* @param - - `matrix`: a 2D array representing the grid or map
|
||||
*/
|
||||
constructor({matrix, turning, onMove, init: {cur, charDir, VISITED}}: NavigatorParams<T>) {
|
||||
constructor({ matrix, turning, onMove, init: { cur, charDir, VISITED } }: NavigatorParams<T>) {
|
||||
this._matrix = matrix;
|
||||
this._cur = cur;
|
||||
this._character = new Character(charDir, turning);
|
||||
|
@ -53,7 +53,7 @@ export class Navigator<T = number> {
|
|||
*/
|
||||
start() {
|
||||
while (this.check(this._character.direction) || this.check(this._character.turn().direction)) {
|
||||
const {direction} = this._character;
|
||||
const { direction } = this._character;
|
||||
if (this.check(direction)) {
|
||||
this.move(direction);
|
||||
} else if (this.check(this._character.turn().direction)) {
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
* @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {PriorityQueue} from './priority-queue';
|
||||
import type {Comparator} from '../../types';
|
||||
import { PriorityQueue } from './priority-queue';
|
||||
import type { Comparator } from '../../types';
|
||||
|
||||
export class MaxPriorityQueue<E = any> extends PriorityQueue<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
* @copyright Copyright (c) 2022 Kirk Qi <qilinaus@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {PriorityQueue} from './priority-queue';
|
||||
import type {Comparator} from '../../types';
|
||||
import { PriorityQueue } from './priority-queue';
|
||||
import type { Comparator } from '../../types';
|
||||
|
||||
export class MinPriorityQueue<E = any> extends PriorityQueue<E> {
|
||||
constructor(
|
||||
options: {comparator: Comparator<E>; nodes?: E[]} = {
|
||||
options: { comparator: Comparator<E>; nodes?: E[] } = {
|
||||
comparator: (a: E, b: E) => {
|
||||
if (!(typeof a === 'number' && typeof b === 'number')) {
|
||||
throw new Error('The a, b params of compare function must be number');
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
|
||||
import {Heap} from '../heap';
|
||||
import {Comparator} from '../../types';
|
||||
import { Heap } from '../heap';
|
||||
import { Comparator } from '../../types';
|
||||
|
||||
export class PriorityQueue<E = any> extends Heap<E> {
|
||||
constructor(options: {comparator: Comparator<E>; nodes?: E[]}) {
|
||||
constructor(options: { comparator: Comparator<E>; nodes?: E[] }) {
|
||||
super(options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import {DoublyLinkedList} from '../linked-list';
|
||||
import { DoublyLinkedList } from '../linked-list';
|
||||
|
||||
// O(n) time complexity of obtaining the value
|
||||
// O(1) time complexity of adding at the beginning and the end
|
||||
|
@ -19,9 +19,9 @@ export class ObjectDeque<E = number> {
|
|||
if (capacity !== undefined) this._capacity = capacity;
|
||||
}
|
||||
|
||||
protected _nodes: {[key: number]: E} = {};
|
||||
protected _nodes: { [key: number]: E } = {};
|
||||
|
||||
get nodes(): {[p: number]: E} {
|
||||
get nodes(): { [p: number]: E } {
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @copyright Tyler Zeng <zrwusa@gmail.com>
|
||||
* @class
|
||||
*/
|
||||
import {SinglyLinkedList} from '../linked-list';
|
||||
import { SinglyLinkedList } from '../linked-list';
|
||||
|
||||
export class LinkedListQueue<E = any> extends SinglyLinkedList<E> {
|
||||
/**
|
||||
|
|
|
@ -27,7 +27,7 @@ export class TreeNode<V = any> {
|
|||
if (level > maxDepth) {
|
||||
maxDepth = level;
|
||||
}
|
||||
const {children} = node;
|
||||
const { children } = node;
|
||||
if (children) {
|
||||
for (let i = 0, len = children.length; i < len; i++) {
|
||||
bfs(children[i], level + 1);
|
||||
|
|
|
@ -164,7 +164,7 @@ export class Trie {
|
|||
if (level > maxDepth) {
|
||||
maxDepth = level;
|
||||
}
|
||||
const {children} = node;
|
||||
const { children } = node;
|
||||
if (children) {
|
||||
for (const child of children.entries()) {
|
||||
bfs(child[1], level + 1);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {BinaryTreeNode} from '../data-structures';
|
||||
import {BinaryTreeNodeNested, BiTreeDeleteResult, BTNCallback, BTNKey} from '../types';
|
||||
import { BinaryTreeNode } from '../data-structures';
|
||||
import { BinaryTreeNodeNested, BiTreeDeleteResult, BTNCallback, BTNKey } from '../types';
|
||||
|
||||
export interface IBinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNodeNested<V>> {
|
||||
createNode(key: BTNKey, value?: N['value']): N;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {VertexKey} from '../types';
|
||||
import { VertexKey } from '../types';
|
||||
|
||||
export interface IGraph<V, E, VO, EO> {
|
||||
createVertex(key: VertexKey, value?: V): VO;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {AVLTreeNode} from '../../../data-structures';
|
||||
import {BSTOptions} from './bst';
|
||||
import { AVLTreeNode } from '../../../data-structures';
|
||||
import { BSTOptions } from './bst';
|
||||
|
||||
export type AVLTreeNodeNested<T> = AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, AVLTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
export type AVLTreeOptions = BSTOptions & {};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {BinaryTreeNode} from '../../../data-structures';
|
||||
import { BinaryTreeNode } from '../../../data-structures';
|
||||
|
||||
/**
|
||||
* Enum representing different loop types.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {BSTNode} from '../../../data-structures';
|
||||
import type {BinaryTreeOptions, BTNKey} from './binary-tree';
|
||||
import { BSTNode } from '../../../data-structures';
|
||||
import type { BinaryTreeOptions, BTNKey } from './binary-tree';
|
||||
|
||||
export type BSTComparator = (a: BTNKey, b: BTNKey) => number;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {RedBlackTreeNode} from '../../../data-structures';
|
||||
import {BSTOptions} from "./bst";
|
||||
import { RedBlackTreeNode } from '../../../data-structures';
|
||||
import { BSTOptions } from "./bst";
|
||||
|
||||
export enum RBTNColor { RED = 1, BLACK = 0}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {TreeMultimapNode} from '../../../data-structures';
|
||||
import {AVLTreeOptions} from './avl-tree';
|
||||
import { TreeMultimapNode } from '../../../data-structures';
|
||||
import { AVLTreeOptions } from './avl-tree';
|
||||
|
||||
export type TreeMultimapNodeNested<T> = TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, TreeMultimapNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ export type HashMapOptions<T> = {
|
|||
sizeFunction?: number | (() => number);
|
||||
fixedLength?: number;
|
||||
forEach: (callback: (el: T) => void) => void;
|
||||
}
|
||||
};
|
||||
|
||||
export type HashMapLinkedNode<K, V> = {
|
||||
key: K
|
||||
value: V
|
||||
next: HashMapLinkedNode<K, V>
|
||||
prev: HashMapLinkedNode<K, V>
|
||||
}
|
||||
key: K;
|
||||
value: V;
|
||||
next: HashMapLinkedNode<K, V>;
|
||||
prev: HashMapLinkedNode<K, V>;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type Direction = 'up' | 'right' | 'down' | 'left';
|
||||
|
||||
export type Turning = {[key in Direction]: Direction};
|
||||
export type Turning = { [key in Direction]: Direction };
|
||||
|
||||
export type NavigatorParams<T = any> = {
|
||||
matrix: T[][];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export type ToThunkFn = () => ReturnType<TrlFn>;
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & {__THUNK__: symbol};
|
||||
export type Thunk = () => ReturnType<ToThunkFn> & { __THUNK__: symbol };
|
||||
export type TrlFn = (...args: any[]) => any;
|
||||
export type TrlAsyncFn = (...args: any[]) => any;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export type KeyValueObject = {[key: string]: any};
|
||||
export type KeyValueObject = { [key: string]: any };
|
||||
|
||||
export type KeyValueObjectWithKey = {[key: string]: any; key: string | number | symbol};
|
||||
export type KeyValueObjectWithKey = { [key: string]: any; key: string | number | symbol };
|
||||
|
||||
export type NonNumberNonObjectButDefined = string | boolean | symbol | null;
|
||||
|
||||
|
@ -16,6 +16,20 @@ export type ObjectWithNumberKey = {
|
|||
key: number;
|
||||
};
|
||||
|
||||
export type RestrictValByKey = NonNumberNonObjectButDefined | ObjectWithoutKey | ObjectWithNonNumberKey | ObjectWithNumberKey;
|
||||
export type RestrictValByKey =
|
||||
| NonNumberNonObjectButDefined
|
||||
| ObjectWithoutKey
|
||||
| ObjectWithNonNumberKey
|
||||
| ObjectWithNumberKey;
|
||||
|
||||
export type DummyAny = string | number | boolean | null | undefined | object | symbol | void | ((...args: []) => any) | never;
|
||||
export type DummyAny =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| undefined
|
||||
| object
|
||||
| symbol
|
||||
| void
|
||||
| ((...args: []) => any)
|
||||
| never;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {Thunk, ToThunkFn, TrlAsyncFn, TrlFn} from '../types';
|
||||
import type { Thunk, ToThunkFn, TrlAsyncFn, TrlFn } from '../types';
|
||||
|
||||
export const uuidV4 = function () {
|
||||
return 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {
|
||||
|
@ -57,7 +57,7 @@ export const trampoline = (fn: TrlFn) => {
|
|||
|
||||
return result;
|
||||
},
|
||||
{cont}
|
||||
{ cont }
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -74,7 +74,7 @@ export const trampolineAsync = (fn: TrlAsyncFn) => {
|
|||
|
||||
return result;
|
||||
},
|
||||
{cont}
|
||||
{ cont }
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -87,13 +87,13 @@ export const getMSB = (value: number): number => {
|
|||
|
||||
export const rangeCheck = (index: number, min: number, max: number, message = 'Index out of bounds.'): void => {
|
||||
if (index < min || index > max) throw new RangeError(message);
|
||||
}
|
||||
};
|
||||
|
||||
export const throwRangeError = (message = 'The value is off-limits.'): void => {
|
||||
throw new RangeError(message);
|
||||
}
|
||||
};
|
||||
|
||||
export const isObjOrFunc = (input: unknown): input is Record<string, unknown> | ((...args: any[]) => any) => {
|
||||
const inputType = typeof input;
|
||||
return (inputType === 'object' && input !== null) || inputType === 'function';
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {AVLTree, CP} from 'data-structure-typed';
|
||||
import { AVLTree, CP } from 'data-structure-typed';
|
||||
|
||||
describe('AVL Tree Test from data-structure-typed', () => {
|
||||
it('should perform various operations on a AVL Tree from data-structure-typed', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {AVLTree, CP} from 'avl-tree-typed';
|
||||
import { AVLTree, CP } from 'avl-tree-typed';
|
||||
|
||||
describe('AVL Tree Test', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {BST, BSTNode, CP} from 'bst-typed';
|
||||
import { BST, BSTNode, CP } from 'bst-typed';
|
||||
|
||||
describe('Individual package BST operations test', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
|
@ -183,25 +183,25 @@ describe('Individual package BST operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
objBST.add(11, { key: 11, keyA: 11 });
|
||||
objBST.add(3, { key: 3, keyA: 3 });
|
||||
const values = [
|
||||
{key: 15, keyA: 15},
|
||||
{key: 1, keyA: 1},
|
||||
{key: 8, keyA: 8},
|
||||
{key: 13, keyA: 13},
|
||||
{key: 16, keyA: 16},
|
||||
{key: 2, keyA: 2},
|
||||
{key: 6, keyA: 6},
|
||||
{key: 9, keyA: 9},
|
||||
{key: 12, keyA: 12},
|
||||
{key: 14, keyA: 14},
|
||||
{key: 4, keyA: 4},
|
||||
{key: 7, keyA: 7},
|
||||
{key: 10, keyA: 10},
|
||||
{key: 5, keyA: 5}
|
||||
{ key: 15, keyA: 15 },
|
||||
{ key: 1, keyA: 1 },
|
||||
{ key: 8, keyA: 8 },
|
||||
{ key: 13, keyA: 13 },
|
||||
{ key: 16, keyA: 16 },
|
||||
{ key: 2, keyA: 2 },
|
||||
{ key: 6, keyA: 6 },
|
||||
{ key: 9, keyA: 9 },
|
||||
{ key: 12, keyA: 12 },
|
||||
{ key: 14, keyA: 14 },
|
||||
{ key: 4, keyA: 4 },
|
||||
{ key: 7, keyA: 7 },
|
||||
{ key: 10, keyA: 10 },
|
||||
{ key: 5, keyA: 5 }
|
||||
];
|
||||
|
||||
objBST.addMany(
|
||||
|
@ -230,7 +230,7 @@ describe('Individual package BST operations test', () => {
|
|||
expect(leftMost?.key).toBe(1);
|
||||
|
||||
const node15 = objBST.getNode(15);
|
||||
expect(node15?.value).toEqual({key: 15, keyA: 15});
|
||||
expect(node15?.value).toEqual({ key: 15, keyA: 15 });
|
||||
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.key).toBe(12);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const {MinHeap} = require('heap-typed');
|
||||
const { MinHeap } = require('heap-typed');
|
||||
|
||||
describe('JS Heap Operation Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import {AVLTree} from '../../../../src';
|
||||
import { AVLTree } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {getRandomIntArray, magnitude} from '../../../utils';
|
||||
import { getRandomIntArray, magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const avl = new AVLTree<number>();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
const { TEN_THOUSAND } = magnitude;
|
||||
const arr = getRandomIntArray(TEN_THOUSAND, 0, TEN_THOUSAND, true);
|
||||
|
||||
suite
|
||||
|
@ -33,4 +33,4 @@ suite
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import {BinaryTree} from '../../../../src';
|
||||
import { BinaryTree } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {getRandomIntArray, magnitude} from '../../../utils';
|
||||
import { getRandomIntArray, magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const biTree = new BinaryTree<number>();
|
||||
const {N_LOG_N} = magnitude;
|
||||
const { N_LOG_N } = magnitude;
|
||||
const arr = getRandomIntArray(N_LOG_N, 0, N_LOG_N, true);
|
||||
|
||||
suite
|
||||
|
@ -42,4 +42,4 @@ suite
|
|||
for (let i = 0; i < N_LOG_N; i++) biTree.morris(n => n, 'pre');
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import {BST} from '../../../../src';
|
||||
import { BST } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {getRandomIntArray, magnitude} from '../../../utils';
|
||||
import { getRandomIntArray, magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const bst = new BST<number>();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
const { TEN_THOUSAND } = magnitude;
|
||||
const arr = getRandomIntArray(TEN_THOUSAND, 0, TEN_THOUSAND, true);
|
||||
|
||||
suite
|
||||
|
@ -33,4 +33,4 @@ suite
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import {RedBlackTree} from '../../../../src';
|
||||
import { RedBlackTree } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {getRandomIntArray, magnitude} from '../../../utils';
|
||||
import {OrderedMap} from 'js-sdsl';
|
||||
import {isCompetitor} from '../../../config';
|
||||
import { getRandomIntArray, magnitude } from '../../../utils';
|
||||
import { OrderedMap } from 'js-sdsl';
|
||||
import { isCompetitor } from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const rbTree = new RedBlackTree();
|
||||
const {HUNDRED_THOUSAND} = magnitude;
|
||||
const { HUNDRED_THOUSAND } = magnitude;
|
||||
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
|
||||
const competitor = new OrderedMap<number, number>();
|
||||
|
||||
|
@ -41,4 +41,4 @@ suite
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {DirectedGraph} from '../../../../src';
|
||||
import { DirectedGraph } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {getRandomIndex, getRandomWords, magnitude} from '../../../utils';
|
||||
import { getRandomIndex, getRandomWords, magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {THOUSAND} = magnitude;
|
||||
const { THOUSAND } = magnitude;
|
||||
const graph = new DirectedGraph<number, number>();
|
||||
const vertexes = getRandomWords(THOUSAND);
|
||||
|
||||
|
@ -46,4 +46,4 @@ suite
|
|||
// }
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {HashMap} from '../../../../src';
|
||||
import {HashMap as CHashMap} from 'js-sdsl';
|
||||
import { HashMap } from '../../../../src';
|
||||
import { HashMap as CHashMap } from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from '../../../config';
|
||||
import { magnitude } from '../../../utils';
|
||||
import { isCompetitor } from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
const { TEN_THOUSAND } = magnitude;
|
||||
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} set`, () => {
|
||||
const hm = new HashMap<number, number>();
|
||||
|
@ -45,4 +45,4 @@ if (isCompetitor) {
|
|||
}
|
||||
});
|
||||
}
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import {FibonacciHeap, Heap} from '../../../../src';
|
||||
import { FibonacciHeap, Heap } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import { magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
const { TEN_THOUSAND } = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
|
||||
const heap = new Heap<number>({comparator: (a, b) => b - a});
|
||||
const heap = new Heap<number>({ comparator: (a, b) => b - a });
|
||||
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
heap.add(i);
|
||||
|
@ -27,4 +27,4 @@ suite
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {DoublyLinkedList, DoublyLinkedListNode} from '../../../../src';
|
||||
import {LinkList as CLinkedList} from 'js-sdsl';
|
||||
import { DoublyLinkedList, DoublyLinkedListNode } from '../../../../src';
|
||||
import { LinkList as CLinkedList } from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from '../../../config';
|
||||
import { magnitude } from '../../../utils';
|
||||
import { isCompetitor } from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
const { LINEAR } = magnitude;
|
||||
|
||||
suite.add(`${LINEAR.toLocaleString()} unshift`, () => {
|
||||
const list = new DoublyLinkedList<number>();
|
||||
|
@ -48,4 +48,4 @@ suite
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {SinglyLinkedList, SinglyLinkedListNode} from '../../../../src';
|
||||
import { SinglyLinkedList, SinglyLinkedListNode } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import { magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
const { TEN_THOUSAND } = magnitude;
|
||||
|
||||
suite
|
||||
.add(`${TEN_THOUSAND.toLocaleString()} push & pop`, () => {
|
||||
|
@ -31,4 +31,4 @@ suite
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import {MaxPriorityQueue} from '../../../../src';
|
||||
import { MaxPriorityQueue } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import { magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
const { TEN_THOUSAND } = magnitude;
|
||||
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} refill & poll`, () => {
|
||||
const nodes = Array.from(new Set<number>(Array.from(new Array(TEN_THOUSAND), () => Math.floor(Math.random() * TEN_THOUSAND * 100))));
|
||||
const nodes = Array.from(
|
||||
new Set<number>(Array.from(new Array(TEN_THOUSAND), () => Math.floor(Math.random() * TEN_THOUSAND * 100)))
|
||||
);
|
||||
const maxPQ = new MaxPriorityQueue<number>();
|
||||
maxPQ.refill(nodes);
|
||||
while (maxPQ.size > 0) {
|
||||
|
@ -14,4 +16,4 @@ suite.add(`${TEN_THOUSAND.toLocaleString()} refill & poll`, () => {
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import {PriorityQueue as CPriorityQueue} from 'js-sdsl';
|
||||
import {PriorityQueue} from '../../../../src';
|
||||
import { PriorityQueue as CPriorityQueue } from 'js-sdsl';
|
||||
import { PriorityQueue } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from '../../../config';
|
||||
import { magnitude } from '../../../utils';
|
||||
import { isCompetitor } from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {TEN_THOUSAND} = magnitude;
|
||||
const { TEN_THOUSAND } = magnitude;
|
||||
|
||||
suite.add(`${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
|
||||
const pq = new PriorityQueue<number>({comparator: (a, b) => b - a});
|
||||
const pq = new PriorityQueue<number>({ comparator: (a, b) => b - a });
|
||||
|
||||
for (let i = 0; i < TEN_THOUSAND; i++) {
|
||||
pq.add(i);
|
||||
|
@ -32,4 +32,4 @@ if (isCompetitor) {
|
|||
});
|
||||
}
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {Deque} from '../../../../src';
|
||||
import {Deque as CDeque} from 'js-sdsl';
|
||||
import { Deque } from '../../../../src';
|
||||
import { Deque as CDeque } from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from '../../../config';
|
||||
import { magnitude } from '../../../utils';
|
||||
import { isCompetitor } from '../../../config';
|
||||
|
||||
export const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
const { LINEAR } = magnitude;
|
||||
|
||||
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const deque = new Deque<number>();
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {Queue} from '../../../../src';
|
||||
import {Queue as CQueue} from 'js-sdsl';
|
||||
import { Queue } from '../../../../src';
|
||||
import { Queue as CQueue } from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from '../../../config';
|
||||
import { magnitude } from '../../../utils';
|
||||
import { isCompetitor } from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
const { LINEAR } = magnitude;
|
||||
|
||||
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const queue = new Queue<number>();
|
||||
|
@ -32,4 +32,4 @@ suite.add(`${LINEAR.toLocaleString()} push & shift`, () => {
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {Stack} from '../../../../src';
|
||||
import {Stack as CStack} from 'js-sdsl';
|
||||
import { Stack } from '../../../../src';
|
||||
import { Stack as CStack } from 'js-sdsl';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {magnitude} from '../../../utils';
|
||||
import {isCompetitor} from '../../../config';
|
||||
import { magnitude } from '../../../utils';
|
||||
import { isCompetitor } from '../../../config';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {LINEAR} = magnitude;
|
||||
const { LINEAR } = magnitude;
|
||||
|
||||
suite.add(`${LINEAR.toLocaleString()} push`, () => {
|
||||
const stack = new Stack<number>();
|
||||
|
@ -46,4 +46,4 @@ if (isCompetitor) {
|
|||
});
|
||||
}
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {Trie} from '../../../../src';
|
||||
import { Trie } from '../../../../src';
|
||||
import * as Benchmark from 'benchmark';
|
||||
import {getRandomWords, magnitude} from '../../../utils';
|
||||
import { getRandomWords, magnitude } from '../../../utils';
|
||||
|
||||
const suite = new Benchmark.Suite();
|
||||
const {HUNDRED_THOUSAND} = magnitude;
|
||||
const { HUNDRED_THOUSAND } = magnitude;
|
||||
const trie = new Trie();
|
||||
const randomWords = getRandomWords(HUNDRED_THOUSAND, false);
|
||||
|
||||
|
@ -19,4 +19,4 @@ suite
|
|||
}
|
||||
});
|
||||
|
||||
export {suite};
|
||||
export { suite };
|
||||
|
|
|
@ -2,8 +2,8 @@ import * as Benchmark from 'benchmark';
|
|||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as fastGlob from 'fast-glob';
|
||||
import {Color, numberFix, render} from '../utils';
|
||||
import {PerformanceTest} from './types';
|
||||
import { Color, numberFix, render } from '../utils';
|
||||
import { PerformanceTest } from './types';
|
||||
|
||||
const parentDirectory = path.resolve(__dirname, '../..');
|
||||
const reportDistPath = path.join(parentDirectory, 'benchmark');
|
||||
|
@ -11,22 +11,22 @@ const reportDistPath = path.join(parentDirectory, 'benchmark');
|
|||
const testDir = path.join(__dirname, 'data-structures');
|
||||
const testFiles = fastGlob.sync(path.join(testDir, '**', '*.test.ts'));
|
||||
|
||||
const report: {[key: string]: any} = {};
|
||||
const report: { [key: string]: any } = {};
|
||||
|
||||
let completedCount = 0;
|
||||
|
||||
const performanceTests: PerformanceTest[] = [];
|
||||
const {GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW} = Color;
|
||||
const { GREEN, BOLD, END, YELLOW, GRAY, CYAN, BG_YELLOW } = Color;
|
||||
|
||||
testFiles.forEach((file: string) => {
|
||||
const testName = path.basename(file, '.test.ts');
|
||||
const testFunction = require(file);
|
||||
const {suite} = testFunction;
|
||||
if (suite) performanceTests.push({testName, suite, file});
|
||||
const { suite } = testFunction;
|
||||
if (suite) performanceTests.push({ testName, suite, file });
|
||||
});
|
||||
|
||||
const composeReport = () => {
|
||||
if (!fs.existsSync(reportDistPath)) fs.mkdirSync(reportDistPath, {recursive: true});
|
||||
if (!fs.existsSync(reportDistPath)) fs.mkdirSync(reportDistPath, { recursive: true });
|
||||
|
||||
const filePath = path.join(reportDistPath, 'report.json');
|
||||
const htmlFilePath = path.join(reportDistPath, 'report.html');
|
||||
|
@ -85,9 +85,9 @@ const composeReport = () => {
|
|||
{
|
||||
'<>': 'tr',
|
||||
html: [
|
||||
{'<>': 'td', html: '${name}'},
|
||||
{'<>': 'td', html: '${periodMS}'},
|
||||
{'<>': 'td', html: '${mean}'}
|
||||
{ '<>': 'td', html: '${name}' },
|
||||
{ '<>': 'td', html: '${periodMS}' },
|
||||
{ '<>': 'td', html: '${mean}' }
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -142,7 +142,7 @@ function replaceMarkdownContent(startMarker: string, endMarker: string, newText:
|
|||
}
|
||||
|
||||
performanceTests.forEach(item => {
|
||||
const {suite, testName, file} = item;
|
||||
const { suite, testName, file } = item;
|
||||
const relativeFilePath = path.relative(__dirname, file);
|
||||
const directory = path.dirname(relativeFilePath);
|
||||
const fileName = path.basename(relativeFilePath);
|
||||
|
@ -173,13 +173,15 @@ performanceTests.forEach(item => {
|
|||
console.log(
|
||||
// `Files: ${GREEN}${testFileCount}${END} `,
|
||||
// `Suites: ${GREEN}${performanceTests.length}${END} `,
|
||||
`Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${performanceTests.length}${END}`,
|
||||
`Suites Progress: ${isDone ? GREEN : YELLOW}${completedCount}${END}/${isDone ? GREEN : YELLOW}${
|
||||
performanceTests.length
|
||||
}${END}`,
|
||||
`Time: ${isTimeWarn ? YELLOW : GREEN}${runTime}s${END}`
|
||||
);
|
||||
if (isDone) {
|
||||
composeReport();
|
||||
}
|
||||
})
|
||||
.run({async: false});
|
||||
.run({ async: false });
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
import * as Benchmark from 'benchmark';
|
||||
|
||||
export type PerformanceTest = {testName: string; suite: Benchmark.Suite; file: string};
|
||||
export type PerformanceTest = { testName: string; suite: Benchmark.Suite; file: string };
|
||||
|
|
|
@ -1 +1 @@
|
|||
export type Json2htmlOptions = {plainHtml?: boolean} & Partial<{[key: string]: any}>;
|
||||
export type Json2htmlOptions = { plainHtml?: boolean } & Partial<{ [key: string]: any }>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {AVLTree, AVLTreeNode, CP, IterationType} from '../../../../src';
|
||||
import { AVLTree, AVLTreeNode, CP, IterationType } from '../../../../src';
|
||||
|
||||
describe('AVL Tree Test', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
|
@ -112,7 +112,7 @@ describe('AVL Tree Test', () => {
|
|||
describe('AVL Tree Test recursively', () => {
|
||||
it('should perform various operations on a AVL Tree', () => {
|
||||
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
|
||||
const tree = new AVLTree<number>({iterationType: IterationType.RECURSIVE});
|
||||
const tree = new AVLTree<number>({ iterationType: IterationType.RECURSIVE });
|
||||
|
||||
for (const i of arr) tree.add(i, i);
|
||||
|
||||
|
@ -219,7 +219,7 @@ describe('AVL Tree Test recursively', () => {
|
|||
});
|
||||
|
||||
describe('AVLTree APIs test', () => {
|
||||
const avl = new AVLTree<{id: number; text: string}>();
|
||||
const avl = new AVLTree<{ id: number; text: string }>();
|
||||
beforeEach(() => {
|
||||
avl.clear();
|
||||
});
|
||||
|
@ -228,9 +228,9 @@ describe('AVLTree APIs test', () => {
|
|||
avl.add(1);
|
||||
const node2 = new AVLTreeNode(2);
|
||||
avl.add(node2);
|
||||
const node3 = new AVLTreeNode(3, {id: 3, text: 'text3'});
|
||||
const node3 = new AVLTreeNode(3, { id: 3, text: 'text3' });
|
||||
avl.add(node3);
|
||||
avl.add(node3, {id: 3, text: 'text33'});
|
||||
avl.add(node3, { id: 3, text: 'text33' });
|
||||
|
||||
const bfsRes = avl.bfs(node => node.key);
|
||||
expect(bfsRes[0]).toBe(2);
|
||||
|
@ -268,7 +268,7 @@ describe('AVLTree', () => {
|
|||
});
|
||||
|
||||
describe('BinaryTree APIs test', () => {
|
||||
const avl = new AVLTree<{id: number; text: string}>();
|
||||
const avl = new AVLTree<{ id: number; text: string }>();
|
||||
beforeEach(() => {
|
||||
avl.clear();
|
||||
});
|
||||
|
@ -277,9 +277,9 @@ describe('AVLTree', () => {
|
|||
avl.add(1);
|
||||
const node2 = new AVLTreeNode(2);
|
||||
avl.add(node2);
|
||||
const node3 = new AVLTreeNode(3, {id: 3, text: 'text3'});
|
||||
const node3 = new AVLTreeNode(3, { id: 3, text: 'text3' });
|
||||
avl.add(node3);
|
||||
avl.add(node3, {id: 3, text: 'text33'});
|
||||
avl.add(node3, { id: 3, text: 'text33' });
|
||||
|
||||
const bfsRes = avl.bfs(node => node);
|
||||
expect(bfsRes[0]?.key).toBe(2);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {BinaryIndexedTree} from '../../../../src';
|
||||
import { BinaryIndexedTree } from '../../../../src';
|
||||
// import {isDebugTest} from '../../../config';
|
||||
|
||||
// const isDebug = isDebugTest;
|
||||
|
@ -8,13 +8,13 @@ describe('BinaryIndexedTree simple', () => {
|
|||
|
||||
beforeEach(() => {
|
||||
//Create a new BinaryIndexedTree instance before each test case
|
||||
bit = new BinaryIndexedTree({frequency: 0, max: 10}); // Modify the value of max as needed
|
||||
bit = new BinaryIndexedTree({ frequency: 0, max: 10 }); // Modify the value of max as needed
|
||||
});
|
||||
|
||||
it('should initialize correctly', () => {
|
||||
expect(bit.freq).toBe(0);
|
||||
expect(bit.max).toBe(10);
|
||||
expect(bit.freqMap).toEqual({0: 0}); // Modify the initialized record value according to the actual situation
|
||||
expect(bit.freqMap).toEqual({ 0: 0 }); // Modify the initialized record value according to the actual situation
|
||||
// More initialization checks can be added
|
||||
});
|
||||
|
||||
|
@ -54,7 +54,7 @@ describe('BinaryIndexedTree', () => {
|
|||
let bit: BinaryIndexedTree;
|
||||
|
||||
beforeEach(function () {
|
||||
bit = new BinaryIndexedTree({frequency, max});
|
||||
bit = new BinaryIndexedTree({ frequency, max });
|
||||
});
|
||||
it('should validate the index', function () {
|
||||
expect(() => bit.readSingle(-1)).toThrow('Index out of range');
|
||||
|
@ -73,7 +73,7 @@ describe('BinaryIndexedTree', () => {
|
|||
it('should frequency and max', function () {
|
||||
const frequency = 200;
|
||||
const max = 1000;
|
||||
const bit = new BinaryIndexedTree({frequency, max});
|
||||
const bit = new BinaryIndexedTree({ frequency, max });
|
||||
|
||||
expect(bit.freq).toBe(frequency);
|
||||
expect(bit.max).toBe(max);
|
||||
|
@ -123,7 +123,7 @@ describe('designated values', function () {
|
|||
let bit: BinaryIndexedTree;
|
||||
|
||||
beforeEach(function () {
|
||||
bit = new BinaryIndexedTree({max: array.length});
|
||||
bit = new BinaryIndexedTree({ max: array.length });
|
||||
array.forEach((value, i) => bit.writeSingle(i, value));
|
||||
});
|
||||
|
||||
|
@ -182,7 +182,7 @@ describe('descending sequence', function () {
|
|||
let bit: BinaryIndexedTree;
|
||||
|
||||
beforeEach(function () {
|
||||
bit = new BinaryIndexedTree({max: array.length});
|
||||
bit = new BinaryIndexedTree({ max: array.length });
|
||||
array.forEach((value, i) => bit.writeSingle(i, value));
|
||||
});
|
||||
|
||||
|
@ -219,7 +219,7 @@ describe('descending sequence', function () {
|
|||
|
||||
describe('BinaryIndexedTree additional tests', () => {
|
||||
it('should handle read method correctly', () => {
|
||||
const bit = new BinaryIndexedTree({max: 10});
|
||||
const bit = new BinaryIndexedTree({ max: 10 });
|
||||
bit.writeSingle(2, 10);
|
||||
bit.writeSingle(5, 20);
|
||||
bit.writeSingle(8, 30);
|
||||
|
@ -227,7 +227,7 @@ describe('BinaryIndexedTree additional tests', () => {
|
|||
});
|
||||
|
||||
it('should handle consecutive operations', () => {
|
||||
const bit = new BinaryIndexedTree({max: 10});
|
||||
const bit = new BinaryIndexedTree({ max: 10 });
|
||||
bit.writeSingle(2, 10);
|
||||
bit.update(2, 5);
|
||||
expect(bit.readSingle(2)).toBe(15);
|
||||
|
@ -237,7 +237,7 @@ describe('BinaryIndexedTree additional tests', () => {
|
|||
});
|
||||
|
||||
it('should handle frequent increment updates', () => {
|
||||
const bit = new BinaryIndexedTree({max: 10});
|
||||
const bit = new BinaryIndexedTree({ max: 10 });
|
||||
for (let i = 0; i < 10; i++) {
|
||||
bit.update(2, 5);
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ describe('BinaryIndexedTree additional tests', () => {
|
|||
});
|
||||
|
||||
it('should handle edge cases', () => {
|
||||
const bit = new BinaryIndexedTree({max: 10});
|
||||
const bit = new BinaryIndexedTree({ max: 10 });
|
||||
bit.writeSingle(9, 100);
|
||||
expect(bit.readSingle(9)).toBe(100);
|
||||
expect(bit.lowerBound(200)).toBe(10);
|
||||
|
@ -291,7 +291,7 @@ describe('', () => {
|
|||
|
||||
constructor(nums: number[]) {
|
||||
this._nums = nums;
|
||||
this._tree = new BinaryIndexedTree({max: nums.length + 1});
|
||||
this._tree = new BinaryIndexedTree({ max: nums.length + 1 });
|
||||
for (let i = 0; i < nums.length; i++) {
|
||||
this._tree.update(i + 1, nums[i]);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {BinaryTree, BinaryTreeNode, IterationType} from '../../../../src';
|
||||
import {getRandomIntArray} from '../../../utils';
|
||||
import {FamilyPosition} from 'binary-tree-typed';
|
||||
import { BinaryTree, BinaryTreeNode, IterationType } from '../../../../src';
|
||||
import { getRandomIntArray } from '../../../utils';
|
||||
import { FamilyPosition } from 'binary-tree-typed';
|
||||
// import {isDebugTest} from '../../../config';
|
||||
|
||||
// const isDebug = isDebugTest;
|
||||
|
@ -242,8 +242,12 @@ describe('BinaryTree', () => {
|
|||
tree.addMany([4, 2, 6, null, 1, 3, null, 5, null, 7]);
|
||||
expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.ITERATIVE)).toEqual([6, 3, 7]);
|
||||
expect(tree.subTreeTraverse(node => node.key, tree.getNode(6), IterationType.RECURSIVE)).toEqual([6, 3, 7]);
|
||||
expect(tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.ITERATIVE, true)).toEqual([6, 3, 7, null]);
|
||||
expect(tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.RECURSIVE, true)).toEqual([6, 3, 7, null]);
|
||||
expect(
|
||||
tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.ITERATIVE, true)
|
||||
).toEqual([6, 3, 7, null]);
|
||||
expect(
|
||||
tree.subTreeTraverse(node => (node ? node.key : null), tree.getNode(6), IterationType.RECURSIVE, true)
|
||||
).toEqual([6, 3, 7, null]);
|
||||
});
|
||||
|
||||
it('should clear the tree', () => {
|
||||
|
@ -315,81 +319,41 @@ describe('BinaryTree traversals', () => {
|
|||
|
||||
const arr = [35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55];
|
||||
tree.refill(arr);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
40,
|
||||
15,
|
||||
29,
|
||||
null,
|
||||
50,
|
||||
null,
|
||||
16,
|
||||
28,
|
||||
30,
|
||||
45,
|
||||
55
|
||||
]);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
40,
|
||||
15,
|
||||
29,
|
||||
null,
|
||||
50,
|
||||
null,
|
||||
16,
|
||||
28,
|
||||
30,
|
||||
45,
|
||||
55
|
||||
]);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.ITERATIVE).map(node => (node === null ? null : node.key))).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
expect(tree.bfs(node => node, tree.root, IterationType.RECURSIVE).map(node => (node === null ? null : node.key))).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 40, 15, 29, null, 50, null, 16, 28, 30, 45, 55]);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.ITERATIVE).map(node => (node === null ? null : node.key))
|
||||
).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
expect(
|
||||
tree.bfs(node => node, tree.root, IterationType.RECURSIVE).map(node => (node === null ? null : node.key))
|
||||
).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
|
||||
expect(tree.dfs(node => node.key, 'pre')).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
||||
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55]);
|
||||
expect(tree.dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
15,
|
||||
null,
|
||||
16,
|
||||
29,
|
||||
28,
|
||||
30,
|
||||
40,
|
||||
null,
|
||||
50,
|
||||
45,
|
||||
55
|
||||
]);
|
||||
expect(tree.dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))).toEqual([
|
||||
35,
|
||||
20,
|
||||
15,
|
||||
null,
|
||||
16,
|
||||
29,
|
||||
28,
|
||||
30,
|
||||
40,
|
||||
null,
|
||||
50,
|
||||
45,
|
||||
55
|
||||
expect(tree.dfs(node => node.key, 'pre', tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
35, 20, 15, 16, 29, 28, 30, 40, 50, 45, 55
|
||||
]);
|
||||
expect(
|
||||
tree.dfs(node => node, 'pre', tree.root, IterationType.ITERATIVE, true).map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
|
||||
expect(
|
||||
tree.dfs(node => node, 'pre', tree.root, IterationType.RECURSIVE, true).map(node => (node ? node.key : null))
|
||||
).toEqual([35, 20, 15, null, 16, 29, 28, 30, 40, null, 50, 45, 55]);
|
||||
|
||||
expect(tree.dfs(node => node.key, 'in')).toEqual([15, 16, 20, 28, 29, 30, 35, 40, 45, 50, 55]);
|
||||
expect(tree.dfs(node => node.key, 'post')).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
||||
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55]);
|
||||
expect(tree.dfs(node => node.key, 'post', tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
16, 15, 28, 30, 29, 20, 45, 55, 50, 40, 35
|
||||
]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
expect(tree.bfs(node => node.key, tree.root, IterationType.ITERATIVE)).toEqual([
|
||||
35, 20, 40, 15, 29, 50, 16, 28, 30, 45, 55
|
||||
]);
|
||||
|
||||
expect(tree.listLevels(node => node.key)).toEqual([[35], [20, 40], [15, 29, 50], [16, 28, 30, 45, 55]]);
|
||||
|
||||
|
@ -417,7 +381,7 @@ describe('BinaryTree', () => {
|
|||
let tree: BinaryTree<string>;
|
||||
|
||||
beforeEach(() => {
|
||||
tree = new BinaryTree<string>({iterationType: IterationType.RECURSIVE});
|
||||
tree = new BinaryTree<string>({ iterationType: IterationType.RECURSIVE });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -560,7 +524,13 @@ describe('BinaryTree', () => {
|
|||
expect(nodes.length).toBe(1);
|
||||
expect(nodes[0].key).toBe(3);
|
||||
|
||||
const nodesRec = tree.getNodes('B', (node: BinaryTreeNode<string>) => node.value, false, tree.root, IterationType.RECURSIVE);
|
||||
const nodesRec = tree.getNodes(
|
||||
'B',
|
||||
(node: BinaryTreeNode<string>) => node.value,
|
||||
false,
|
||||
tree.root,
|
||||
IterationType.RECURSIVE
|
||||
);
|
||||
|
||||
expect(nodesRec.length).toBe(1);
|
||||
expect(nodesRec[0].key).toBe(3);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {BST, BSTNode, CP, IterationType} from '../../../../src';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import { BST, BSTNode, CP, IterationType } from '../../../../src';
|
||||
import { isDebugTest } from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
|
||||
|
@ -189,25 +189,25 @@ describe('BST operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
objBST.add(11, { key: 11, keyA: 11 });
|
||||
objBST.add(3, { key: 3, keyA: 3 });
|
||||
const values = [
|
||||
{key: 15, keyA: 15},
|
||||
{key: 1, keyA: 1},
|
||||
{key: 8, keyA: 8},
|
||||
{key: 13, keyA: 13},
|
||||
{key: 16, keyA: 16},
|
||||
{key: 2, keyA: 2},
|
||||
{key: 6, keyA: 6},
|
||||
{key: 9, keyA: 9},
|
||||
{key: 12, keyA: 12},
|
||||
{key: 14, keyA: 14},
|
||||
{key: 4, keyA: 4},
|
||||
{key: 7, keyA: 7},
|
||||
{key: 10, keyA: 10},
|
||||
{key: 5, keyA: 5}
|
||||
{ key: 15, keyA: 15 },
|
||||
{ key: 1, keyA: 1 },
|
||||
{ key: 8, keyA: 8 },
|
||||
{ key: 13, keyA: 13 },
|
||||
{ key: 16, keyA: 16 },
|
||||
{ key: 2, keyA: 2 },
|
||||
{ key: 6, keyA: 6 },
|
||||
{ key: 9, keyA: 9 },
|
||||
{ key: 12, keyA: 12 },
|
||||
{ key: 14, keyA: 14 },
|
||||
{ key: 4, keyA: 4 },
|
||||
{ key: 7, keyA: 7 },
|
||||
{ key: 10, keyA: 10 },
|
||||
{ key: 5, keyA: 5 }
|
||||
];
|
||||
|
||||
objBST.addMany(
|
||||
|
@ -236,7 +236,7 @@ describe('BST operations test', () => {
|
|||
expect(leftMost?.key).toBe(1);
|
||||
|
||||
const node15 = objBST.getNode(15);
|
||||
expect(node15?.value).toEqual({key: 15, keyA: 15});
|
||||
expect(node15?.value).toEqual({ key: 15, keyA: 15 });
|
||||
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.key).toBe(12);
|
||||
|
||||
|
@ -260,7 +260,7 @@ describe('BST operations test', () => {
|
|||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
|
||||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
@ -385,7 +385,7 @@ describe('BST operations test', () => {
|
|||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodes.push(node));
|
||||
expect(bfsNodes[0].key).toBe(2);
|
||||
expect(bfsNodes[1].key).toBe(12);
|
||||
|
@ -395,7 +395,7 @@ describe('BST operations test', () => {
|
|||
|
||||
describe('BST operations test recursively', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const bst = new BST({iterationType: IterationType.RECURSIVE});
|
||||
const bst = new BST({ iterationType: IterationType.RECURSIVE });
|
||||
expect(bst).toBeInstanceOf(BST);
|
||||
bst.add(11, 11);
|
||||
bst.add(3, 3);
|
||||
|
@ -580,25 +580,25 @@ describe('BST operations test recursively', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
expect(objBST).toBeInstanceOf(BST);
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
objBST.add(11, { key: 11, keyA: 11 });
|
||||
objBST.add(3, { key: 3, keyA: 3 });
|
||||
const values = [
|
||||
{key: 15, keyA: 15},
|
||||
{key: 1, keyA: 1},
|
||||
{key: 8, keyA: 8},
|
||||
{key: 13, keyA: 13},
|
||||
{key: 16, keyA: 16},
|
||||
{key: 2, keyA: 2},
|
||||
{key: 6, keyA: 6},
|
||||
{key: 9, keyA: 9},
|
||||
{key: 12, keyA: 12},
|
||||
{key: 14, keyA: 14},
|
||||
{key: 4, keyA: 4},
|
||||
{key: 7, keyA: 7},
|
||||
{key: 10, keyA: 10},
|
||||
{key: 5, keyA: 5}
|
||||
{ key: 15, keyA: 15 },
|
||||
{ key: 1, keyA: 1 },
|
||||
{ key: 8, keyA: 8 },
|
||||
{ key: 13, keyA: 13 },
|
||||
{ key: 16, keyA: 16 },
|
||||
{ key: 2, keyA: 2 },
|
||||
{ key: 6, keyA: 6 },
|
||||
{ key: 9, keyA: 9 },
|
||||
{ key: 12, keyA: 12 },
|
||||
{ key: 14, keyA: 14 },
|
||||
{ key: 4, keyA: 4 },
|
||||
{ key: 7, keyA: 7 },
|
||||
{ key: 10, keyA: 10 },
|
||||
{ key: 5, keyA: 5 }
|
||||
];
|
||||
|
||||
objBST.addMany(
|
||||
|
@ -614,7 +614,7 @@ describe('BST operations test recursively', () => {
|
|||
expect(objBST.has(6)).toBe(true);
|
||||
|
||||
const node6 = objBST.getNode(6);
|
||||
expect(objBST.get(6)).toEqual({key: 6, keyA: 6});
|
||||
expect(objBST.get(6)).toEqual({ key: 6, keyA: 6 });
|
||||
expect(node6 && objBST.getHeight(node6)).toBe(2);
|
||||
expect(node6 && objBST.getDepth(node6)).toBe(3);
|
||||
|
||||
|
@ -628,7 +628,7 @@ describe('BST operations test recursively', () => {
|
|||
expect(leftMost?.key).toBe(1);
|
||||
|
||||
const node15 = objBST.getNode(15);
|
||||
expect(node15?.value).toEqual({key: 15, keyA: 15});
|
||||
expect(node15?.value).toEqual({ key: 15, keyA: 15 });
|
||||
const minNodeBySpecificNode = node15 && objBST.getLeftMost(node15);
|
||||
expect(minNodeBySpecificNode?.key).toBe(12);
|
||||
|
||||
|
@ -652,7 +652,7 @@ describe('BST operations test recursively', () => {
|
|||
objBST.perfectlyBalance();
|
||||
expect(objBST.isPerfectlyBalanced()).toBe(true);
|
||||
|
||||
const bfsNodesAfterBalanced: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodesAfterBalanced: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodesAfterBalanced.push(node));
|
||||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
@ -777,7 +777,7 @@ describe('BST operations test recursively', () => {
|
|||
expect(bfsIDs[1]).toBe(12);
|
||||
expect(bfsIDs[2]).toBe(16);
|
||||
|
||||
const bfsNodes: BSTNode<{key: number; keyA: number}>[] = [];
|
||||
const bfsNodes: BSTNode<{ key: number; keyA: number }>[] = [];
|
||||
objBST.bfs(node => bfsNodes.push(node));
|
||||
expect(bfsNodes[0].key).toBe(2);
|
||||
expect(bfsNodes[1].key).toBe(12);
|
||||
|
@ -843,7 +843,11 @@ describe('BST Performance test', function () {
|
|||
bst.addMany([4, 2, 6, 1, 3, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.ITERATIVE)).toEqual([6, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node.key, bst.getNode(6), IterationType.RECURSIVE)).toEqual([6, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.ITERATIVE, true)).toEqual([6, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.RECURSIVE, true)).toEqual([6, 5, 7]);
|
||||
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.ITERATIVE, true)).toEqual([
|
||||
6, 5, 7
|
||||
]);
|
||||
expect(bst.subTreeTraverse(node => node?.key ?? undefined, bst.getNode(6), IterationType.RECURSIVE, true)).toEqual([
|
||||
6, 5, 7
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {AVLTree, BST} from '../../../../src';
|
||||
import { AVLTree, BST } from '../../../../src';
|
||||
|
||||
describe('Overall BinaryTree Test', () => {
|
||||
it('should perform various operations on BinaryTree', () => {
|
||||
|
@ -29,27 +29,27 @@ describe('Overall BinaryTree Test', () => {
|
|||
bfsIDs[0] === 11; // true
|
||||
expect(bfsIDs[0]).toBe(11);
|
||||
|
||||
const objBST = new BST<{key: number; keyA: number}>();
|
||||
objBST.add(11, {key: 11, keyA: 11});
|
||||
objBST.add(3, {key: 3, keyA: 3});
|
||||
const objBST = new BST<{ key: number; keyA: number }>();
|
||||
objBST.add(11, { key: 11, keyA: 11 });
|
||||
objBST.add(3, { key: 3, keyA: 3 });
|
||||
|
||||
objBST.addMany(
|
||||
[15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5],
|
||||
[
|
||||
{key: 15, keyA: 15},
|
||||
{key: 1, keyA: 1},
|
||||
{key: 8, keyA: 8},
|
||||
{key: 13, keyA: 13},
|
||||
{key: 16, keyA: 16},
|
||||
{key: 2, keyA: 2},
|
||||
{key: 6, keyA: 6},
|
||||
{key: 9, keyA: 9},
|
||||
{key: 12, keyA: 12},
|
||||
{key: 14, keyA: 14},
|
||||
{key: 4, keyA: 4},
|
||||
{key: 7, keyA: 7},
|
||||
{key: 10, keyA: 10},
|
||||
{key: 5, keyA: 5}
|
||||
{ key: 15, keyA: 15 },
|
||||
{ key: 1, keyA: 1 },
|
||||
{ key: 8, keyA: 8 },
|
||||
{ key: 13, keyA: 13 },
|
||||
{ key: 16, keyA: 16 },
|
||||
{ key: 2, keyA: 2 },
|
||||
{ key: 6, keyA: 6 },
|
||||
{ key: 9, keyA: 9 },
|
||||
{ key: 12, keyA: 12 },
|
||||
{ key: 14, keyA: 14 },
|
||||
{ key: 4, keyA: 4 },
|
||||
{ key: 7, keyA: 7 },
|
||||
{ key: 10, keyA: 10 },
|
||||
{ key: 5, keyA: 5 }
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {IterationType, RBTNColor, RedBlackTree, RedBlackTreeNode} from '../../../../src';
|
||||
import {getRandomInt, getRandomIntArray, magnitude} from '../../../utils';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import {OrderedMap} from 'js-sdsl';
|
||||
import { IterationType, RBTNColor, RedBlackTree, RedBlackTreeNode } from '../../../../src';
|
||||
import { getRandomInt, getRandomIntArray, magnitude } from '../../../utils';
|
||||
import { isDebugTest } from '../../../config';
|
||||
import { OrderedMap } from 'js-sdsl';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
|
||||
|
@ -438,12 +438,12 @@ describe('RedBlackTree', () => {
|
|||
expect(tree.size).toBe(51);
|
||||
expect(tree.isBST()).toBe(true);
|
||||
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.ITERATIVE)).toEqual([
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
||||
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
|
||||
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
]);
|
||||
expect(tree.dfs(n => n.key, 'in', tree.root, IterationType.RECURSIVE)).toEqual([
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
|
||||
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
|
||||
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -468,7 +468,7 @@ describe('RedBlackTree', () => {
|
|||
// TODO there is a bug when dfs the tree with NIL node
|
||||
// expect(tree.isBST()).toBe(true);
|
||||
});
|
||||
const {HUNDRED_THOUSAND} = magnitude;
|
||||
const { HUNDRED_THOUSAND } = magnitude;
|
||||
const arr = getRandomIntArray(HUNDRED_THOUSAND, 0, HUNDRED_THOUSAND, true);
|
||||
const competitor = new OrderedMap<number, number>();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {SegmentTree} from '../../../../src';
|
||||
import { SegmentTree } from '../../../../src';
|
||||
|
||||
describe('SegmentTree', () => {
|
||||
let segmentTree: SegmentTree;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {CP, IterationType, TreeMultimap, TreeMultimapNode} from '../../../../src';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import { CP, IterationType, TreeMultimap, TreeMultimapNode } from '../../../../src';
|
||||
import { isDebugTest } from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
|
||||
|
@ -207,25 +207,25 @@ describe('TreeMultimap operations test', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultimap = new TreeMultimap<{key: number; keyA: number}>();
|
||||
const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
|
||||
expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
|
||||
objTreeMultimap.add(11, {key: 11, keyA: 11});
|
||||
objTreeMultimap.add(3, {key: 3, keyA: 3});
|
||||
objTreeMultimap.add(11, { key: 11, keyA: 11 });
|
||||
objTreeMultimap.add(3, { key: 3, keyA: 3 });
|
||||
const values = [
|
||||
{key: 15, keyA: 15},
|
||||
{key: 1, keyA: 1},
|
||||
{key: 8, keyA: 8},
|
||||
{key: 13, keyA: 13},
|
||||
{key: 16, keyA: 16},
|
||||
{key: 2, keyA: 2},
|
||||
{key: 6, keyA: 6},
|
||||
{key: 9, keyA: 9},
|
||||
{key: 12, keyA: 12},
|
||||
{key: 14, keyA: 14},
|
||||
{key: 4, keyA: 4},
|
||||
{key: 7, keyA: 7},
|
||||
{key: 10, keyA: 10},
|
||||
{key: 5, keyA: 5}
|
||||
{ key: 15, keyA: 15 },
|
||||
{ key: 1, keyA: 1 },
|
||||
{ key: 8, keyA: 8 },
|
||||
{ key: 13, keyA: 13 },
|
||||
{ key: 16, keyA: 16 },
|
||||
{ key: 2, keyA: 2 },
|
||||
{ key: 6, keyA: 6 },
|
||||
{ key: 9, keyA: 9 },
|
||||
{ key: 12, keyA: 12 },
|
||||
{ key: 14, keyA: 14 },
|
||||
{ key: 4, keyA: 4 },
|
||||
{ key: 7, keyA: 7 },
|
||||
{ key: 10, keyA: 10 },
|
||||
{ key: 5, keyA: 5 }
|
||||
];
|
||||
|
||||
objTreeMultimap.addMany(
|
||||
|
@ -245,7 +245,7 @@ describe('TreeMultimap operations test', () => {
|
|||
|
||||
describe('TreeMultimap operations test recursively', () => {
|
||||
it('should perform various operations on a Binary Search Tree with numeric values', () => {
|
||||
const treeMultimap = new TreeMultimap({iterationType: IterationType.RECURSIVE});
|
||||
const treeMultimap = new TreeMultimap({ iterationType: IterationType.RECURSIVE });
|
||||
|
||||
expect(treeMultimap instanceof TreeMultimap);
|
||||
treeMultimap.add(11, 11);
|
||||
|
@ -447,25 +447,25 @@ describe('TreeMultimap operations test recursively', () => {
|
|||
});
|
||||
|
||||
it('should perform various operations on a Binary Search Tree with object values', () => {
|
||||
const objTreeMultimap = new TreeMultimap<{key: number; keyA: number}>();
|
||||
const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
|
||||
expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
|
||||
objTreeMultimap.add(11, {key: 11, keyA: 11});
|
||||
objTreeMultimap.add(3, {key: 3, keyA: 3});
|
||||
objTreeMultimap.add(11, { key: 11, keyA: 11 });
|
||||
objTreeMultimap.add(3, { key: 3, keyA: 3 });
|
||||
const values = [
|
||||
{key: 15, keyA: 15},
|
||||
{key: 1, keyA: 1},
|
||||
{key: 8, keyA: 8},
|
||||
{key: 13, keyA: 13},
|
||||
{key: 16, keyA: 16},
|
||||
{key: 2, keyA: 2},
|
||||
{key: 6, keyA: 6},
|
||||
{key: 9, keyA: 9},
|
||||
{key: 12, keyA: 12},
|
||||
{key: 14, keyA: 14},
|
||||
{key: 4, keyA: 4},
|
||||
{key: 7, keyA: 7},
|
||||
{key: 10, keyA: 10},
|
||||
{key: 5, keyA: 5}
|
||||
{ key: 15, keyA: 15 },
|
||||
{ key: 1, keyA: 1 },
|
||||
{ key: 8, keyA: 8 },
|
||||
{ key: 13, keyA: 13 },
|
||||
{ key: 16, keyA: 16 },
|
||||
{ key: 2, keyA: 2 },
|
||||
{ key: 6, keyA: 6 },
|
||||
{ key: 9, keyA: 9 },
|
||||
{ key: 12, keyA: 12 },
|
||||
{ key: 14, keyA: 14 },
|
||||
{ key: 4, keyA: 4 },
|
||||
{ key: 7, keyA: 7 },
|
||||
{ key: 10, keyA: 10 },
|
||||
{ key: 5, keyA: 5 }
|
||||
];
|
||||
|
||||
objTreeMultimap.addMany(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {AbstractEdge, AbstractGraph, AbstractVertex, VertexKey} from '../../../../src';
|
||||
import { AbstractEdge, AbstractGraph, AbstractVertex, VertexKey } from '../../../../src';
|
||||
|
||||
class MyVertex<V = any> extends AbstractVertex<V> {
|
||||
data?: V;
|
||||
|
@ -22,12 +22,12 @@ class MyEdge<E = any> extends AbstractEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
class MyGraph<V = any, E = any, VO extends MyVertex<V> = MyVertex<V>, EO extends MyEdge<E> = MyEdge<E>> extends AbstractGraph<
|
||||
V,
|
||||
E,
|
||||
VO,
|
||||
EO
|
||||
> {
|
||||
class MyGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends MyVertex<V> = MyVertex<V>,
|
||||
EO extends MyEdge<E> = MyEdge<E>
|
||||
> extends AbstractGraph<V, E, VO, EO> {
|
||||
createVertex(key: VertexKey, value?: V): VO {
|
||||
return new MyVertex(key, value) as VO;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {DirectedEdge, DirectedGraph, DirectedVertex, VertexKey} from '../../../../src';
|
||||
import { DirectedEdge, DirectedGraph, DirectedVertex, VertexKey } from '../../../../src';
|
||||
|
||||
describe('DirectedGraph Operation Test', () => {
|
||||
let graph: DirectedGraph;
|
||||
|
@ -126,12 +126,12 @@ class MyEdge<E = any> extends DirectedEdge<E> {
|
|||
}
|
||||
}
|
||||
|
||||
class MyDirectedGraph<V = any, E = any, VO extends MyVertex<V> = MyVertex<V>, EO extends MyEdge<E> = MyEdge<E>> extends DirectedGraph<
|
||||
V,
|
||||
E,
|
||||
VO,
|
||||
EO
|
||||
> {
|
||||
class MyDirectedGraph<
|
||||
V = any,
|
||||
E = any,
|
||||
VO extends MyVertex<V> = MyVertex<V>,
|
||||
EO extends MyEdge<E> = MyEdge<E>
|
||||
> extends DirectedGraph<V, E, VO, EO> {
|
||||
createVertex(key: VertexKey, value: V): VO {
|
||||
return new MyVertex(key, value) as VO;
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|||
const fordResult1 = myGraph.bellmanFord(1);
|
||||
expect(fordResult1).toBeTruthy();
|
||||
expect(fordResult1.hasNegativeCycle).toBeUndefined();
|
||||
const {distMap, preMap, paths, min, minPath} = fordResult1;
|
||||
const { distMap, preMap, paths, min, minPath } = fordResult1;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
|
@ -343,7 +343,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|||
const floydResult = myGraph.floydWarshall();
|
||||
expect(floydResult).toBeTruthy();
|
||||
if (floydResult) {
|
||||
const {costs, predecessor} = floydResult;
|
||||
const { costs, predecessor } = floydResult;
|
||||
expect(costs).toBeInstanceOf(Array);
|
||||
expect(costs.length).toBe(9);
|
||||
expect(costs[0]).toEqual([32, 12, 35, 14, 70, Infinity, 61, Infinity, 19]);
|
||||
|
@ -351,9 +351,29 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|||
expect(costs[2]).toEqual([3, 15, 38, 17, 35, Infinity, 64, Infinity, 22]);
|
||||
expect(costs[3]).toEqual([123, 135, 120, 137, 155, Infinity, 47, Infinity, 126]);
|
||||
expect(costs[4]).toEqual([133, 145, 130, 147, 165, Infinity, 57, Infinity, 136]);
|
||||
expect(costs[5]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[5]).toEqual([
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity
|
||||
]);
|
||||
expect(costs[6]).toEqual([76, 88, 73, 90, 108, Infinity, 137, Infinity, 79]);
|
||||
expect(costs[7]).toEqual([Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity, Infinity]);
|
||||
expect(costs[7]).toEqual([
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity,
|
||||
Infinity
|
||||
]);
|
||||
expect(costs[8]).toEqual([173, 185, 170, 187, 205, Infinity, 97, Infinity, 176]);
|
||||
|
||||
expect(predecessor).toBeInstanceOf(Array);
|
||||
|
@ -369,7 +389,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|||
|
||||
expect(dijkstraRes12tt).toBeTruthy();
|
||||
if (dijkstraRes12tt) {
|
||||
const {distMap, minDist, minPath, paths} = dijkstraRes12tt;
|
||||
const { distMap, minDist, minPath, paths } = dijkstraRes12tt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
|
@ -420,7 +440,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|||
|
||||
expect(dijkstraRes1ntt).toBeTruthy();
|
||||
if (dijkstraRes1ntt) {
|
||||
const {distMap, minDist, minPath, paths} = dijkstraRes1ntt;
|
||||
const { distMap, minDist, minPath, paths } = dijkstraRes1ntt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
|
@ -482,7 +502,7 @@ describe('Inherit from DirectedGraph and perform operations test2.', () => {
|
|||
const dijkstraWithoutHeapRes1ntt = myGraph.dijkstraWithoutHeap(1, null, true, true);
|
||||
expect(dijkstraWithoutHeapRes1ntt).toBeTruthy();
|
||||
if (dijkstraWithoutHeapRes1ntt) {
|
||||
const {distMap, minDist, minPath, paths} = dijkstraWithoutHeapRes1ntt;
|
||||
const { distMap, minDist, minPath, paths } = dijkstraWithoutHeapRes1ntt;
|
||||
expect(distMap).toBeInstanceOf(Map);
|
||||
expect(distMap.size).toBe(9);
|
||||
expect(distMap.get(vertex1)).toBe(0);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {MapEdge, MapGraph, MapVertex} from '../../../../src';
|
||||
import { MapEdge, MapGraph, MapVertex } from '../../../../src';
|
||||
|
||||
describe('MapGraph Operation Test', () => {
|
||||
it('dijkstra shortest path', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {DirectedGraph, UndirectedGraph} from '../../../../src';
|
||||
import { DirectedGraph, UndirectedGraph } from '../../../../src';
|
||||
|
||||
describe('Overall Graph Operation Test', () => {
|
||||
it('Overall DirectedGraph Operation Test', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {UndirectedEdge, UndirectedGraph, UndirectedVertex} from '../../../../src';
|
||||
import { UndirectedEdge, UndirectedGraph, UndirectedVertex } from '../../../../src';
|
||||
import saltyVertexes from './salty-vertexes.json';
|
||||
import saltyEdges from './salty-edges.json';
|
||||
|
||||
|
@ -150,7 +150,7 @@ describe('UndirectedGraph', () => {
|
|||
});
|
||||
|
||||
it('should getAllPathsBetween work well in 66 vertexes 97 edges graph', () => {
|
||||
const graph = new UndirectedGraph<{name: string}, number>();
|
||||
const graph = new UndirectedGraph<{ name: string }, number>();
|
||||
for (const v of saltyVertexes) {
|
||||
graph.addVertex(v.name, v);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {CoordinateMap} from '../../../../src';
|
||||
import { CoordinateMap } from '../../../../src';
|
||||
|
||||
describe('CoordinateMap', () => {
|
||||
it('should set and get values correctly', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {CoordinateSet} from '../../../../src';
|
||||
import { CoordinateSet } from '../../../../src';
|
||||
|
||||
describe('CoordinateSet', () => {
|
||||
it('should add and check values correctly', () => {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import {HashMap} from '../../../../src';
|
||||
import {getRandomInt, getRandomIntArray} from "../../../utils";
|
||||
import * as console from "console";
|
||||
|
||||
import { HashMap } from '../../../../src';
|
||||
import { getRandomInt, getRandomIntArray } from '../../../utils';
|
||||
|
||||
describe('HashMap', () => {
|
||||
let hashMap: HashMap<string, number>;
|
||||
|
@ -67,7 +65,6 @@ describe('HashMap', () => {
|
|||
// expect(entries).toContainEqual(['three', 3]);
|
||||
});
|
||||
|
||||
|
||||
it('should resize the table when load factor is exceeded', () => {
|
||||
// Set a small initial capacity for testing resizing
|
||||
hashMap = new HashMap<string, number>();
|
||||
|
@ -85,10 +82,6 @@ describe('HashMap', () => {
|
|||
});
|
||||
|
||||
it('should allow using a custom hash function', () => {
|
||||
const customHashFn = () => {
|
||||
// A simple custom hash function that always returns 0
|
||||
return 0;
|
||||
};
|
||||
hashMap = new HashMap<string, number>();
|
||||
|
||||
hashMap.set('one', 1);
|
||||
|
@ -100,54 +93,6 @@ describe('HashMap', () => {
|
|||
// Make sure they are stored separately.
|
||||
// expect(hashMap.table[0].length).toBe(2);
|
||||
});
|
||||
|
||||
|
||||
it('performance', () => {
|
||||
// const ht = new HashTable();
|
||||
// const st = performance.now();
|
||||
// for (let i = 0; i < 1000000; i++) {
|
||||
// ht.set(i, i);
|
||||
// }
|
||||
// console.log(performance.now() - st);
|
||||
const n = 1000000;
|
||||
|
||||
// const hms = new SHashMap();
|
||||
// const ss = performance.now();
|
||||
// for (let i = 0; i < n; i++) {
|
||||
// hms.put(i, i);
|
||||
// }
|
||||
// console.log(performance.now() - ss, 'HashMap.put');
|
||||
// const hashS = performance.now();
|
||||
// for (let i = 0; i < n; i++) {
|
||||
// hms.hash(i);
|
||||
// }
|
||||
// console.log(performance.now() - hashS, 'hash');
|
||||
// const arr = [];
|
||||
// const arrS = performance.now();
|
||||
// for (let i = 0; i < n; i++) {
|
||||
// arr.push(i)
|
||||
// }
|
||||
// console.log(performance.now() - arrS, 'array.push');
|
||||
// const mp = new Map();
|
||||
// const smp = performance.now();
|
||||
// for (let i = 0; i < n; i++) {
|
||||
// mp.set(i, i);
|
||||
// }
|
||||
// console.log(performance.now() - smp, 'Map.set');
|
||||
// const cHm = new CHashMap();
|
||||
// const sC = performance.now();
|
||||
// for (let i = 0; i < n; i++) {
|
||||
// cHm.setElement(i, i);
|
||||
// }
|
||||
// console.log(performance.now() - sC, 'Competitor HashMap.setElement');
|
||||
const hm = new HashMap();
|
||||
const s = performance.now();
|
||||
for (let i = 0; i < n; i++) {
|
||||
hm.set(i, i);
|
||||
}
|
||||
console.log(performance.now() - s, 'HashMap.set');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('HashMap', () => {
|
||||
|
@ -167,14 +112,14 @@ describe('HashMap', () => {
|
|||
});
|
||||
|
||||
it('should handle object keys correctly', () => {
|
||||
const keyObj = {id: 1};
|
||||
const keyObj = { id: 1 };
|
||||
hashMap.set(keyObj, 'objectValue');
|
||||
expect(hashMap.get(keyObj)).toBe('objectValue');
|
||||
});
|
||||
|
||||
it('should handle number keys correctly', () => {
|
||||
hashMap.set(999, {a:'999Value'});
|
||||
expect(hashMap.get(999)).toEqual({a:'999Value'});
|
||||
hashMap.set(999, { a: '999Value' });
|
||||
expect(hashMap.get(999)).toEqual({ a: '999Value' });
|
||||
});
|
||||
|
||||
it('should update the value for an existing key', () => {
|
||||
|
@ -208,7 +153,10 @@ describe('HashMap', () => {
|
|||
for (const value of hashMap) {
|
||||
values.push(value);
|
||||
}
|
||||
expect(values).toEqual([['key1', 'value1'], ['key2', 'value2']]);
|
||||
expect(values).toEqual([
|
||||
['key1', 'value1'],
|
||||
['key2', 'value2']
|
||||
]);
|
||||
});
|
||||
|
||||
// test('should delete element at specific index', () => {
|
||||
|
@ -236,9 +184,10 @@ describe('HashMap', () => {
|
|||
index++;
|
||||
});
|
||||
}
|
||||
|
||||
const stdMap: Map<unknown, unknown> = new Map();
|
||||
const arr: number[] = getRandomIntArray(10000, 1, 10000);
|
||||
|
||||
const arr: number[] = getRandomIntArray(1000, 1, 10000);
|
||||
|
||||
it('delete test', () => {
|
||||
for (const item of arr) {
|
||||
stdMap.set(item, item);
|
||||
|
@ -251,18 +200,18 @@ describe('HashMap', () => {
|
|||
}
|
||||
compareHashMaps(hashMap, stdMap);
|
||||
|
||||
for (let i = 0; i < 10000; ++i) {
|
||||
for (let i = 0; i < 1000; ++i) {
|
||||
const random = getRandomInt(0, 100);
|
||||
expect(hashMap.delete(random)).toEqual(stdMap.delete(random));
|
||||
}
|
||||
compareHashMaps(hashMap, stdMap);
|
||||
});
|
||||
|
||||
test('should iterate correctly with reverse iterators', () => {
|
||||
hashMap.set('key1', 'value1');
|
||||
hashMap.set('key2', 'value2');
|
||||
const iterator = hashMap.reverseBegin;
|
||||
expect(iterator.next().current).toEqual(['key1', 'value1']);
|
||||
|
||||
});
|
||||
|
||||
test('should return the last element', () => {
|
||||
|
@ -274,13 +223,10 @@ describe('HashMap', () => {
|
|||
test('should return undefined for empty map', () => {
|
||||
expect(hashMap.back).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should get element at specific index', () => {
|
||||
hashMap.set('key1', 'value1');
|
||||
hashMap.set('key2', 'value2');
|
||||
expect(hashMap.getAt(1)).toEqual(['key2', 'value2']);
|
||||
});
|
||||
|
||||
|
||||
|
||||
})
|
||||
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {HashTable, HashTableNode} from '../../../../src';
|
||||
import { HashTable, HashTableNode } from '../../../../src';
|
||||
|
||||
describe('HashNode', () => {
|
||||
it('should create a HashNode with key and value', () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {FibonacciHeap, MaxHeap, MinHeap} from '../../../../src';
|
||||
import {logBigOMetricsWrap} from '../../../utils';
|
||||
import { FibonacciHeap, MaxHeap, MinHeap } from '../../../../src';
|
||||
import { logBigOMetricsWrap } from '../../../utils';
|
||||
|
||||
describe('Heap Operation Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
|
@ -22,34 +22,46 @@ describe('Heap Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should object heap work well', function () {
|
||||
const minHeap = new MinHeap<{a: string; key: number}>({comparator: (a, b) => a.key - b.key});
|
||||
minHeap.add({key: 1, a: 'a1'});
|
||||
minHeap.add({key: 6, a: 'a6'});
|
||||
minHeap.add({key: 2, a: 'a2'});
|
||||
minHeap.add({key: 0, a: 'a0'});
|
||||
const minHeap = new MinHeap<{ a: string; key: number }>({ comparator: (a, b) => a.key - b.key });
|
||||
minHeap.add({ key: 1, a: 'a1' });
|
||||
minHeap.add({ key: 6, a: 'a6' });
|
||||
minHeap.add({ key: 2, a: 'a2' });
|
||||
minHeap.add({ key: 0, a: 'a0' });
|
||||
|
||||
expect(minHeap.peek()).toEqual({a: 'a0', key: 0});
|
||||
expect(minHeap.toArray().map(item => ({a: item.a}))).toEqual([{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}]);
|
||||
expect(minHeap.peek()).toEqual({ a: 'a0', key: 0 });
|
||||
expect(minHeap.toArray().map(item => ({ a: item.a }))).toEqual([
|
||||
{ a: 'a0' },
|
||||
{ a: 'a1' },
|
||||
{ a: 'a2' },
|
||||
{ a: 'a6' }
|
||||
]);
|
||||
let i = 0;
|
||||
const expectPolled = [{a: 'a0'}, {a: 'a1'}, {a: 'a2'}, {a: 'a6'}];
|
||||
const expectPolled = [{ a: 'a0' }, { a: 'a1' }, { a: 'a2' }, { a: 'a6' }];
|
||||
while (minHeap.size > 0) {
|
||||
expect({a: minHeap.poll()?.a}).toEqual(expectPolled[i]);
|
||||
expect({ a: minHeap.poll()?.a }).toEqual(expectPolled[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
const maxHeap = new MaxHeap<{key: number; a: string}>({comparator: (a, b) => b.key - a.key});
|
||||
maxHeap.add({key: 1, a: 'a1'});
|
||||
maxHeap.add({key: 6, a: 'a6'});
|
||||
maxHeap.add({key: 5, a: 'a5'});
|
||||
maxHeap.add({key: 2, a: 'a2'});
|
||||
maxHeap.add({key: 0, a: 'a0'});
|
||||
maxHeap.add({key: 9, a: 'a9'});
|
||||
expect(maxHeap.peek()).toEqual({a: 'a9', key: 9});
|
||||
expect(maxHeap.toArray().map(item => ({a: item.a}))).toEqual([{a: 'a9'}, {a: 'a2'}, {a: 'a6'}, {a: 'a1'}, {a: 'a0'}, {a: 'a5'}]);
|
||||
const maxExpectPolled = [{a: 'a9'}, {a: 'a6'}, {a: 'a5'}, {a: 'a2'}, {a: 'a1'}, {a: 'a0'}];
|
||||
const maxHeap = new MaxHeap<{ key: number; a: string }>({ comparator: (a, b) => b.key - a.key });
|
||||
maxHeap.add({ key: 1, a: 'a1' });
|
||||
maxHeap.add({ key: 6, a: 'a6' });
|
||||
maxHeap.add({ key: 5, a: 'a5' });
|
||||
maxHeap.add({ key: 2, a: 'a2' });
|
||||
maxHeap.add({ key: 0, a: 'a0' });
|
||||
maxHeap.add({ key: 9, a: 'a9' });
|
||||
expect(maxHeap.peek()).toEqual({ a: 'a9', key: 9 });
|
||||
expect(maxHeap.toArray().map(item => ({ a: item.a }))).toEqual([
|
||||
{ a: 'a9' },
|
||||
{ a: 'a2' },
|
||||
{ a: 'a6' },
|
||||
{ a: 'a1' },
|
||||
{ a: 'a0' },
|
||||
{ a: 'a5' }
|
||||
]);
|
||||
const maxExpectPolled = [{ a: 'a9' }, { a: 'a6' }, { a: 'a5' }, { a: 'a2' }, { a: 'a1' }, { a: 'a0' }];
|
||||
let maxI = 0;
|
||||
while (maxHeap.size > 0) {
|
||||
expect({a: maxHeap.poll()?.a}).toEqual(maxExpectPolled[maxI]);
|
||||
expect({ a: maxHeap.poll()?.a }).toEqual(maxExpectPolled[maxI]);
|
||||
maxI++;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {Comparator, MaxHeap} from '../../../../src';
|
||||
import { Comparator, MaxHeap } from '../../../../src';
|
||||
|
||||
describe('MaxHeap', () => {
|
||||
const numberComparator: Comparator<number> = (a, b) => b - a;
|
||||
let maxHeap: MaxHeap<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
maxHeap = new MaxHeap({comparator: numberComparator});
|
||||
maxHeap = new MaxHeap({ comparator: numberComparator });
|
||||
});
|
||||
|
||||
it('add and poll elements in descending order', () => {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {Comparator, MinHeap} from '../../../../src';
|
||||
import { Comparator, MinHeap } from '../../../../src';
|
||||
|
||||
describe('MinHeap', () => {
|
||||
const numberComparator: Comparator<number> = (a, b) => a - b;
|
||||
let minHeap: MinHeap<number>;
|
||||
|
||||
beforeEach(() => {
|
||||
minHeap = new MinHeap({comparator: numberComparator});
|
||||
minHeap = new MinHeap({ comparator: numberComparator });
|
||||
});
|
||||
|
||||
it('add and poll elements in ascending order', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {DoublyLinkedList, DoublyLinkedListNode} from '../../../../src';
|
||||
import { DoublyLinkedList, DoublyLinkedListNode } from '../../../../src';
|
||||
|
||||
describe('DoublyLinkedListNode', () => {
|
||||
it('should DoublyLinkedListNode', () => {
|
||||
|
@ -60,7 +60,7 @@ describe('DoublyLinkedList Operation Test', () => {
|
|||
|
||||
describe('DoublyLinkedList Operation Test', () => {
|
||||
let list: DoublyLinkedList<number>;
|
||||
let objectList: DoublyLinkedList<{keyA: number}>;
|
||||
let objectList: DoublyLinkedList<{ keyA: number }>;
|
||||
|
||||
beforeEach(() => {
|
||||
list = new DoublyLinkedList();
|
||||
|
@ -370,9 +370,9 @@ describe('DoublyLinkedList Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should insert and manipulate objects with numeric properties', () => {
|
||||
const obj1 = {keyA: 10};
|
||||
const obj2 = {keyA: 20};
|
||||
const obj3 = {keyA: 30};
|
||||
const obj1 = { keyA: 10 };
|
||||
const obj2 = { keyA: 20 };
|
||||
const obj3 = { keyA: 30 };
|
||||
|
||||
objectList.push(obj1);
|
||||
objectList.push(obj2);
|
||||
|
@ -380,7 +380,7 @@ describe('DoublyLinkedList Operation Test', () => {
|
|||
|
||||
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
|
||||
|
||||
const newObj = {keyA: 25}; // Corrected newObj value
|
||||
const newObj = { keyA: 25 }; // Corrected newObj value
|
||||
const insertSuccess = objectList.insertBefore(obj2, newObj);
|
||||
expect(insertSuccess).toBe(true);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {SinglyLinkedList, SinglyLinkedListNode} from '../../../../src';
|
||||
import { SinglyLinkedList, SinglyLinkedListNode } from '../../../../src';
|
||||
|
||||
describe('SinglyLinkedListNode', () => {
|
||||
it('should SinglyLinkedList', () => {
|
||||
|
@ -11,10 +11,10 @@ describe('SinglyLinkedListNode', () => {
|
|||
|
||||
describe('SinglyLinkedList Operation Test', () => {
|
||||
let list: SinglyLinkedList<number>;
|
||||
let objectList: SinglyLinkedList<{keyA: number}>;
|
||||
let objectList: SinglyLinkedList<{ keyA: number }>;
|
||||
beforeEach(() => {
|
||||
list = new SinglyLinkedList<number>();
|
||||
objectList = new SinglyLinkedList<{keyA: number}>();
|
||||
objectList = new SinglyLinkedList<{ keyA: number }>();
|
||||
});
|
||||
|
||||
describe('push', () => {
|
||||
|
@ -366,9 +366,9 @@ describe('SinglyLinkedList Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should insert and manipulate objects with numeric properties', () => {
|
||||
const obj1 = {keyA: 1};
|
||||
const obj2 = {keyA: 2};
|
||||
const obj3 = {keyA: 3};
|
||||
const obj1 = { keyA: 1 };
|
||||
const obj2 = { keyA: 2 };
|
||||
const obj3 = { keyA: 3 };
|
||||
|
||||
objectList.push(obj1);
|
||||
objectList.push(obj2);
|
||||
|
@ -376,7 +376,7 @@ describe('SinglyLinkedList Operation Test', () => {
|
|||
|
||||
expect(objectList.toArray()).toEqual([obj1, obj2, obj3]);
|
||||
|
||||
const newObj = {keyA: 2.5}; // Corrected newObj value
|
||||
const newObj = { keyA: 2.5 }; // Corrected newObj value
|
||||
const insertSuccess = objectList.insertBefore(obj2, newObj);
|
||||
expect(insertSuccess).toBe(true);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {SkipList} from '../../../../src';
|
||||
import { SkipList } from '../../../../src';
|
||||
|
||||
describe('SkipList', () => {
|
||||
let skipList: SkipList<number, string>;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import {MatrixNTI2D} from '../../../../src';
|
||||
import { MatrixNTI2D } from '../../../../src';
|
||||
|
||||
describe('MatrixNTI2D', () => {
|
||||
it('should initialize a matrix with rows and columns', () => {
|
||||
const numRows = 3;
|
||||
const numCols = 4;
|
||||
const matrix = new MatrixNTI2D({row: numRows, col: numCols});
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols });
|
||||
|
||||
expect(matrix.toArray().length).toBe(numRows);
|
||||
expect(matrix.toArray()[0].length).toBe(numCols);
|
||||
|
@ -14,7 +14,7 @@ describe('MatrixNTI2D', () => {
|
|||
const numRows = 3;
|
||||
const numCols = 4;
|
||||
const initialValue = 42;
|
||||
const matrix = new MatrixNTI2D({row: numRows, col: numCols, initialVal: initialValue});
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols, initialVal: initialValue });
|
||||
|
||||
const matrixArray = matrix.toArray();
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
|
@ -27,7 +27,7 @@ describe('MatrixNTI2D', () => {
|
|||
it('should initialize all elements with 0 if no initial value is provided', () => {
|
||||
const numRows = 3;
|
||||
const numCols = 4;
|
||||
const matrix = new MatrixNTI2D({row: numRows, col: numCols});
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols });
|
||||
|
||||
const matrixArray = matrix.toArray();
|
||||
for (let i = 0; i < numRows; i++) {
|
||||
|
@ -40,7 +40,7 @@ describe('MatrixNTI2D', () => {
|
|||
it('should convert the matrix to a two-dimensional array', () => {
|
||||
const numRows = 2;
|
||||
const numCols = 3;
|
||||
const matrix = new MatrixNTI2D({row: numRows, col: numCols, initialVal: 1});
|
||||
const matrix = new MatrixNTI2D({ row: numRows, col: numCols, initialVal: 1 });
|
||||
|
||||
const matrixArray = matrix.toArray();
|
||||
expect(matrixArray.length).toBe(numRows);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Matrix2D, Vector2D} from '../../../../src';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import { Matrix2D, Vector2D } from '../../../../src';
|
||||
import { isDebugTest } from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
describe('Matrix2D', () => {
|
||||
|
@ -288,7 +288,7 @@ describe('Matrix2D', () => {
|
|||
const vector = new Vector2D(2, 3);
|
||||
const result = Matrix2D.multiplyByVector(matrix, vector);
|
||||
isDebug && console.log(JSON.stringify(result));
|
||||
expect(result).toEqual({x: 17, y: 35, w: 1});
|
||||
expect(result).toEqual({ x: 17, y: 35, w: 1 });
|
||||
});
|
||||
|
||||
it('should correctly create a view matrix', () => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Character, Navigator, NavigatorParams, Turning} from '../../../../src';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import { Character, Navigator, NavigatorParams, Turning } from '../../../../src';
|
||||
import { isDebugTest } from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
const exampleMatrix: number[][] = [
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Vector2D} from '../../../../src';
|
||||
import { Vector2D } from '../../../../src';
|
||||
|
||||
describe('Vector2D', () => {
|
||||
it('should create a vector with default values', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {MaxPriorityQueue} from '../../../../src';
|
||||
import { MaxPriorityQueue } from '../../../../src';
|
||||
|
||||
describe('MaxPriorityQueue Operation Test', () => {
|
||||
it('should add elements and maintain heap property', () => {
|
||||
|
@ -16,9 +16,9 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should add elements and maintain heap property in a object MaxPriorityQueue', () => {
|
||||
const priorityQueue = new MaxPriorityQueue<{keyA: number}>({comparator: (a, b) => b.keyA - a.keyA});
|
||||
priorityQueue.refill([{keyA: 5}, {keyA: 3}, {keyA: 1}]);
|
||||
priorityQueue.add({keyA: 7});
|
||||
const priorityQueue = new MaxPriorityQueue<{ keyA: number }>({ comparator: (a, b) => b.keyA - a.keyA });
|
||||
priorityQueue.refill([{ keyA: 5 }, { keyA: 3 }, { keyA: 1 }]);
|
||||
priorityQueue.add({ keyA: 7 });
|
||||
|
||||
expect(priorityQueue.poll()?.keyA).toBe(7);
|
||||
expect(priorityQueue.poll()?.keyA).toBe(5);
|
||||
|
@ -52,7 +52,7 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
|
||||
it('should correctly heapify an array', () => {
|
||||
const array = [5, 3, 7, 1];
|
||||
const heap = MaxPriorityQueue.heapify<number>({nodes: array, comparator: (a, b) => b - a});
|
||||
const heap = MaxPriorityQueue.heapify<number>({ nodes: array, comparator: (a, b) => b - a });
|
||||
heap.refill(array);
|
||||
|
||||
expect(heap.poll()).toBe(7);
|
||||
|
@ -62,8 +62,8 @@ describe('MaxPriorityQueue Operation Test', () => {
|
|||
});
|
||||
|
||||
it('should correctly heapify an object array', () => {
|
||||
const nodes = [{keyA: 5}, {keyA: 3}, {keyA: 7}, {keyA: 1}];
|
||||
const maxPQ = MaxPriorityQueue.heapify<{keyA: number}>({nodes: nodes, comparator: (a, b) => b.keyA - a.keyA});
|
||||
const nodes = [{ keyA: 5 }, { keyA: 3 }, { keyA: 7 }, { keyA: 1 }];
|
||||
const maxPQ = MaxPriorityQueue.heapify<{ keyA: number }>({ nodes: nodes, comparator: (a, b) => b.keyA - a.keyA });
|
||||
|
||||
expect(maxPQ.poll()?.keyA).toBe(7);
|
||||
expect(maxPQ.poll()?.keyA).toBe(5);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {MinPriorityQueue} from '../../../../src';
|
||||
import { MinPriorityQueue } from '../../../../src';
|
||||
|
||||
describe('MinPriorityQueue Operation Test', () => {
|
||||
it('should check if a node exists in the queue', () => {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import {PriorityQueue} from '../../../../src';
|
||||
import {PriorityQueue as CPriorityQueue} from 'js-sdsl';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import { PriorityQueue } from '../../../../src';
|
||||
import { PriorityQueue as CPriorityQueue } from 'js-sdsl';
|
||||
import { isDebugTest } from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
describe('PriorityQueue Operation Test', () => {
|
||||
it('should PriorityQueue poll, pee, heapify, toArray work well', function () {
|
||||
const minPQ = new PriorityQueue<number>({comparator: (a, b) => a - b});
|
||||
const minPQ = new PriorityQueue<number>({ comparator: (a, b) => a - b });
|
||||
minPQ.refill([5, 2, 3, 4, 6, 1]);
|
||||
expect(minPQ.toArray()).toEqual([1, 2, 3, 4, 6, 5]);
|
||||
minPQ.poll();
|
||||
|
@ -13,13 +13,16 @@ describe('PriorityQueue Operation Test', () => {
|
|||
minPQ.poll();
|
||||
expect(minPQ.toArray()).toEqual([4, 5, 6]);
|
||||
expect(minPQ.peek()).toBe(4);
|
||||
expect(PriorityQueue.heapify({nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], comparator: (a, b) => a - b}).toArray()).toEqual([
|
||||
1, 2, 3, 5, 6, 7, 8, 9, 10
|
||||
]);
|
||||
expect(
|
||||
PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()
|
||||
).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
||||
it('should Max PriorityQueue poll, peek, heapify, toArray work well', function () {
|
||||
const maxPriorityQueue = new PriorityQueue<number>({comparator: (a, b) => b - a});
|
||||
const maxPriorityQueue = new PriorityQueue<number>({ comparator: (a, b) => b - a });
|
||||
maxPriorityQueue.refill([5, 2, 3, 4, 6, 1]);
|
||||
expect(maxPriorityQueue.toArray()).toEqual([6, 5, 3, 4, 2, 1]);
|
||||
maxPriorityQueue.poll();
|
||||
|
@ -27,13 +30,16 @@ describe('PriorityQueue Operation Test', () => {
|
|||
maxPriorityQueue.poll();
|
||||
expect(maxPriorityQueue.toArray()).toEqual([3, 2, 1]);
|
||||
expect(maxPriorityQueue.peek()).toBe(3);
|
||||
expect(PriorityQueue.heapify({nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10], comparator: (a, b) => a - b}).toArray()).toEqual([
|
||||
1, 2, 3, 5, 6, 7, 8, 9, 10
|
||||
]);
|
||||
expect(
|
||||
PriorityQueue.heapify({
|
||||
nodes: [3, 2, 1, 5, 6, 7, 8, 9, 10],
|
||||
comparator: (a, b) => a - b
|
||||
}).toArray()
|
||||
).toEqual([1, 2, 3, 5, 6, 7, 8, 9, 10]);
|
||||
});
|
||||
|
||||
it('should PriorityQueue clone, sort, getNodes, dfs work well', function () {
|
||||
const minPQ1 = new PriorityQueue<number>({comparator: (a, b) => a - b});
|
||||
const minPQ1 = new PriorityQueue<number>({ comparator: (a, b) => a - b });
|
||||
minPQ1.refill([2, 5, 8, 3, 1, 6, 7, 4]);
|
||||
const clonedPriorityQueue = minPQ1.clone();
|
||||
expect(clonedPriorityQueue.getNodes()).toEqual(minPQ1.getNodes());
|
||||
|
@ -46,7 +52,7 @@ describe('PriorityQueue Operation Test', () => {
|
|||
|
||||
describe('Priority Queue Performance Test', () => {
|
||||
it('should numeric heap work well', function () {
|
||||
const pq = new PriorityQueue({comparator: (a, b) => b - a});
|
||||
const pq = new PriorityQueue({ comparator: (a, b) => b - a });
|
||||
|
||||
const tS = performance.now();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {ArrayDeque, Deque, ObjectDeque} from '../../../../src';
|
||||
import {bigO} from '../../../utils';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import { ArrayDeque, Deque, ObjectDeque } from '../../../../src';
|
||||
import { bigO } from '../../../utils';
|
||||
import { isDebugTest } from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
describe('Deque Tests', () => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {LinkedListQueue, Queue} from '../../../../src';
|
||||
import {bigO} from '../../../utils';
|
||||
import {isDebugTest} from '../../../config';
|
||||
import { LinkedListQueue, Queue } from '../../../../src';
|
||||
import { bigO } from '../../../utils';
|
||||
import { isDebugTest } from '../../../config';
|
||||
|
||||
const isDebug = isDebugTest;
|
||||
describe('Queue Operation Test', () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Stack} from '../../../../src';
|
||||
import { Stack } from '../../../../src';
|
||||
|
||||
describe('Stack', () => {
|
||||
let stack: Stack<number>;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {TreeNode} from '../../../../src';
|
||||
import { TreeNode } from '../../../../src';
|
||||
|
||||
describe('TreeNode', () => {
|
||||
it('should create a TreeNode with the given key and value', () => {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue