style: reformated codebase

This commit is contained in:
Revone 2023-11-16 10:14:14 +08:00
parent bac0964ac2
commit dd2701dab7
104 changed files with 962 additions and 925 deletions

View file

@ -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

View file

@ -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": {

View file

@ -1,6 +1,6 @@
module.exports = {
"arrowParens": "avoid",
"bracketSpacing": false,
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "css",
"insertPragma": false,
"bracketSameLine": false,

View file

@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
## [v1.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

View file

@ -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)

View file

@ -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",

View file

@ -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) {

View file

@ -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;
}

View file

@ -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) {

View file

@ -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 = [];

View file

@ -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;
/**

View file

@ -6,7 +6,7 @@
* @license MIT License
*/
import type {SegmentTreeNodeVal} from '../../types';
import type { SegmentTreeNodeVal } from '../../types';
export class SegmentTreeNode {
start = 0;

View file

@ -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;

View file

@ -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 };
}
/**

View file

@ -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.
*/

View file

@ -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

View file

@ -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.
*/

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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');

View file

@ -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');

View file

@ -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));
}

View file

@ -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[][];

View file

@ -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)) {

View file

@ -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');

View file

@ -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');

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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> {
/**

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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 & {};

View file

@ -1,4 +1,4 @@
import {BinaryTreeNode} from '../../../data-structures';
import { BinaryTreeNode } from '../../../data-structures';
/**
* Enum representing different loop types.

View file

@ -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;

View file

@ -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}

View file

@ -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>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

View file

@ -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>;
};

View file

@ -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[][];

View file

@ -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;

View file

@ -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;

View file

@ -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';
}
};

View file

@ -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', () => {

View file

@ -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', () => {

View file

@ -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);

View file

@ -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 () {

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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>();

View file

@ -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 };

View file

@ -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 };

View file

@ -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 };

View file

@ -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 });
}
});

View file

@ -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 };

View file

@ -1 +1 @@
export type Json2htmlOptions = {plainHtml?: boolean} & Partial<{[key: string]: any}>;
export type Json2htmlOptions = { plainHtml?: boolean } & Partial<{ [key: string]: any }>;

View file

@ -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);

View file

@ -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]);
}

View file

@ -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);

View file

@ -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
]);
});
});

View file

@ -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 }
]
);

View file

@ -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>();

View file

@ -1,4 +1,4 @@
import {SegmentTree} from '../../../../src';
import { SegmentTree } from '../../../../src';
describe('SegmentTree', () => {
let segmentTree: SegmentTree;

View file

@ -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(

View file

@ -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;
}

View file

@ -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);

View file

@ -1,4 +1,4 @@
import {MapEdge, MapGraph, MapVertex} from '../../../../src';
import { MapEdge, MapGraph, MapVertex } from '../../../../src';
describe('MapGraph Operation Test', () => {
it('dijkstra shortest path', () => {

View file

@ -1,4 +1,4 @@
import {DirectedGraph, UndirectedGraph} from '../../../../src';
import { DirectedGraph, UndirectedGraph } from '../../../../src';
describe('Overall Graph Operation Test', () => {
it('Overall DirectedGraph Operation Test', () => {

View file

@ -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);
}

View file

@ -1,4 +1,4 @@
import {CoordinateMap} from '../../../../src';
import { CoordinateMap } from '../../../../src';
describe('CoordinateMap', () => {
it('should set and get values correctly', () => {

View file

@ -1,4 +1,4 @@
import {CoordinateSet} from '../../../../src';
import { CoordinateSet } from '../../../../src';
describe('CoordinateSet', () => {
it('should add and check values correctly', () => {

View file

@ -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']);
});
})
});

View file

@ -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', () => {

View file

@ -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++;
}
});

View file

@ -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', () => {

View file

@ -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', () => {

View file

@ -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);

View file

@ -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);

View file

@ -1,4 +1,4 @@
import {SkipList} from '../../../../src';
import { SkipList } from '../../../../src';
describe('SkipList', () => {
let skipList: SkipList<number, string>;

View file

@ -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);

View file

@ -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', () => {

View file

@ -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[][] = [

View file

@ -1,4 +1,4 @@
import {Vector2D} from '../../../../src';
import { Vector2D } from '../../../../src';
describe('Vector2D', () => {
it('should create a vector with default values', () => {

View file

@ -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);

View file

@ -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', () => {

View file

@ -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();

View file

@ -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', () => {

View file

@ -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', () => {

View file

@ -1,4 +1,4 @@
import {Stack} from '../../../../src';
import { Stack } from '../../../../src';
describe('Stack', () => {
let stack: Stack<number>;

View file

@ -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