mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 04:44:04 +00:00
fix: Bug fix #103: Fixed an issue where all binary tree clone methods lost constructor parameters. Optimized variable names. Standardized access modifiers for binary tree member variables.
This commit is contained in:
parent
fc0d157295
commit
6428e0f228
63
README.md
63
README.md
|
@ -14,6 +14,8 @@
|
|||
[//]: # (<p><a href="https://github.com/zrwusa/data-structure-typed/blob/main/README.md">English</a> | <a href="https://github.com/zrwusa/data-structure-typed/blob/main/README_zh-CN.md">简体中文</a></p>)
|
||||
|
||||
|
||||
> ***Our goal is to make every data structure as convenient and efficient as JavaScript's Array.***
|
||||
|
||||
## Installation and Usage
|
||||
|
||||
### npm
|
||||
|
@ -212,6 +214,7 @@ Performance surpasses that of native JS/TS
|
|||
|
||||
|
||||
### Conciseness and uniformity
|
||||
|
||||
In [java.utils](), you need to memorize a table for all sequential data structures(Queue, Deque, LinkedList),
|
||||
|
||||
<table style="display: table; width:100%; table-layout: fixed;">
|
||||
|
@ -710,24 +713,24 @@ bst.print()
|
|||
|
||||
const objBST = new BST<number, { height: number, age: number }>();
|
||||
|
||||
objBST.add(11, { "name": "Pablo", "age": 15 });
|
||||
objBST.add(3, { "name": "Kirk", "age": 1 });
|
||||
objBST.add(11, { "name": "Pablo", "size": 15 });
|
||||
objBST.add(3, { "name": "Kirk", "size": 1 });
|
||||
|
||||
objBST.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], [
|
||||
{ "name": "Alice", "age": 15 },
|
||||
{ "name": "Bob", "age": 1 },
|
||||
{ "name": "Charlie", "age": 8 },
|
||||
{ "name": "David", "age": 13 },
|
||||
{ "name": "Emma", "age": 16 },
|
||||
{ "name": "Frank", "age": 2 },
|
||||
{ "name": "Grace", "age": 6 },
|
||||
{ "name": "Hannah", "age": 9 },
|
||||
{ "name": "Isaac", "age": 12 },
|
||||
{ "name": "Jack", "age": 14 },
|
||||
{ "name": "Katie", "age": 4 },
|
||||
{ "name": "Liam", "age": 7 },
|
||||
{ "name": "Mia", "age": 10 },
|
||||
{ "name": "Noah", "age": 5 }
|
||||
{ "name": "Alice", "size": 15 },
|
||||
{ "name": "Bob", "size": 1 },
|
||||
{ "name": "Charlie", "size": 8 },
|
||||
{ "name": "David", "size": 13 },
|
||||
{ "name": "Emma", "size": 16 },
|
||||
{ "name": "Frank", "size": 2 },
|
||||
{ "name": "Grace", "size": 6 },
|
||||
{ "name": "Hannah", "size": 9 },
|
||||
{ "name": "Isaac", "size": 12 },
|
||||
{ "name": "Jack", "size": 14 },
|
||||
{ "name": "Katie", "size": 4 },
|
||||
{ "name": "Liam", "size": 7 },
|
||||
{ "name": "Mia", "size": 10 },
|
||||
{ "name": "Noah", "size": 5 }
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -823,43 +826,43 @@ Version 11.7.9
|
|||
[//]: # (No deletion!!! Start of Replace Section)
|
||||
<div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>heap</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>6.56</td><td>152.37</td><td>1.86e-4</td></tr><tr><td>100,000 add & poll</td><td>35.15</td><td>28.45</td><td>7.98e-4</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>6.49</td><td>154.00</td><td>1.90e-4</td></tr><tr><td>100,000 add & poll</td><td>35.79</td><td>27.94</td><td>0.01</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>rb-tree</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>83.54</td><td>11.97</td><td>8.43e-4</td></tr><tr><td>100,000 add randomly</td><td>85.53</td><td>11.69</td><td>0.00</td></tr><tr><td>100,000 get</td><td>115.17</td><td>8.68</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>30.20</td><td>33.11</td><td>0.00</td></tr><tr><td>100,000 add & delete orderly</td><td>151.05</td><td>6.62</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>239.32</td><td>4.18</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>85.30</td><td>11.72</td><td>7.38e-4</td></tr><tr><td>100,000 add randomly</td><td>84.77</td><td>11.80</td><td>0.00</td></tr><tr><td>100,000 get</td><td>113.74</td><td>8.79</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>24.51</td><td>40.80</td><td>0.00</td></tr><tr><td>100,000 add & delete orderly</td><td>152.17</td><td>6.57</td><td>0.01</td></tr><tr><td>100,000 add & delete randomly</td><td>240.78</td><td>4.15</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'>queue</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>44.31</td><td>22.57</td><td>0.01</td></tr><tr><td>100,000 push & shift</td><td>5.50</td><td>181.72</td><td>0.00</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2451.35</td><td>0.41</td><td>0.39</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>44.16</td><td>22.64</td><td>0.01</td></tr><tr><td>100,000 push & shift</td><td>6.08</td><td>164.58</td><td>0.00</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2240.74</td><td>0.45</td><td>0.17</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>20.56</td><td>48.65</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>25.77</td><td>38.81</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>26.35</td><td>37.95</td><td>0.00</td></tr><tr><td>100,000 push & shift</td><td>2.54</td><td>394.25</td><td>4.24e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2109.72</td><td>0.47</td><td>0.12</td></tr><tr><td>100,000 unshift & shift</td><td>2.43</td><td>411.24</td><td>3.06e-4</td></tr><tr><td>Native JS Array 100,000 unshift & shift</td><td>4275.22</td><td>0.23</td><td>0.35</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>20.75</td><td>48.19</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>26.85</td><td>37.24</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>27.56</td><td>36.28</td><td>0.00</td></tr><tr><td>100,000 push & shift</td><td>2.61</td><td>382.75</td><td>4.11e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2388.65</td><td>0.42</td><td>0.15</td></tr><tr><td>100,000 unshift & shift</td><td>2.50</td><td>399.53</td><td>3.59e-4</td></tr><tr><td>Native JS Array 100,000 unshift & shift</td><td>4343.52</td><td>0.23</td><td>0.30</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>hash-map</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 set</td><td>85.09</td><td>11.75</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set</td><td>211.60</td><td>4.73</td><td>0.03</td></tr><tr><td>Native JS Set 1,000,000 add</td><td>165.56</td><td>6.04</td><td>0.01</td></tr><tr><td>1,000,000 set & get</td><td>78.93</td><td>12.67</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set & get</td><td>273.56</td><td>3.66</td><td>0.00</td></tr><tr><td>Native JS Set 1,000,000 add & has</td><td>241.87</td><td>4.13</td><td>0.03</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>339.57</td><td>2.94</td><td>0.04</td></tr><tr><td>Native JS Map 1,000,000 ObjKey set & get</td><td>294.22</td><td>3.40</td><td>0.02</td></tr><tr><td>Native JS Set 1,000,000 ObjKey add & has</td><td>268.41</td><td>3.73</td><td>0.03</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 set</td><td>87.12</td><td>11.48</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set</td><td>211.63</td><td>4.73</td><td>0.03</td></tr><tr><td>Native JS Set 1,000,000 add</td><td>167.62</td><td>5.97</td><td>0.01</td></tr><tr><td>1,000,000 set & get</td><td>78.91</td><td>12.67</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set & get</td><td>295.47</td><td>3.38</td><td>0.03</td></tr><tr><td>Native JS Set 1,000,000 add & has</td><td>267.22</td><td>3.74</td><td>0.07</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>378.26</td><td>2.64</td><td>0.06</td></tr><tr><td>Native JS Map 1,000,000 ObjKey set & get</td><td>344.04</td><td>2.91</td><td>0.06</td></tr><tr><td>Native JS Set 1,000,000 ObjKey add & has</td><td>277.87</td><td>3.60</td><td>0.04</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>43.89</td><td>22.78</td><td>8.04e-4</td></tr><tr><td>100,000 getWords</td><td>82.90</td><td>12.06</td><td>0.00</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 push</td><td>42.67</td><td>23.44</td><td>8.55e-4</td></tr><tr><td>100,000 getWords</td><td>82.51</td><td>12.12</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'>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>100,000 add</td><td>281.55</td><td>3.55</td><td>0.00</td></tr><tr><td>100,000 add randomly</td><td>353.66</td><td>2.83</td><td>0.02</td></tr><tr><td>100,000 get</td><td>150.33</td><td>6.65</td><td>0.01</td></tr><tr><td>100,000 iterator</td><td>33.26</td><td>30.07</td><td>0.01</td></tr><tr><td>100,000 add & delete orderly</td><td>465.24</td><td>2.15</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>634.77</td><td>1.58</td><td>0.02</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>307.42</td><td>3.25</td><td>9.13e-4</td></tr><tr><td>100,000 add randomly</td><td>373.75</td><td>2.68</td><td>0.01</td></tr><tr><td>100,000 get</td><td>172.23</td><td>5.81</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>25.90</td><td>38.61</td><td>0.00</td></tr><tr><td>100,000 add & delete orderly</td><td>509.58</td><td>1.96</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>690.44</td><td>1.45</td><td>0.02</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>binary-tree-overall</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 RBTree add randomly</td><td>7.62</td><td>131.29</td><td>8.51e-5</td></tr><tr><td>10,000 RBTree get randomly</td><td>10.50</td><td>95.20</td><td>5.32e-5</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>20.69</td><td>48.33</td><td>1.32e-4</td></tr><tr><td>10,000 AVLTree add randomly</td><td>25.68</td><td>38.94</td><td>2.47e-4</td></tr><tr><td>10,000 AVLTree get randomly</td><td>10.95</td><td>91.29</td><td>6.68e-5</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>48.33</td><td>20.69</td><td>3.14e-4</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 RBTree add randomly</td><td>7.45</td><td>134.14</td><td>0.00</td></tr><tr><td>10,000 RBTree get randomly</td><td>13.03</td><td>76.74</td><td>1.43e-4</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>22.62</td><td>44.21</td><td>1.83e-4</td></tr><tr><td>10,000 AVLTree add randomly</td><td>28.44</td><td>35.16</td><td>2.71e-4</td></tr><tr><td>10,000 AVLTree get randomly</td><td>13.02</td><td>76.81</td><td>1.05e-4</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>54.46</td><td>18.36</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>1.03e+4</td><td>1.01e-6</td></tr><tr><td>1,000 addEdge</td><td>5.95</td><td>168.01</td><td>1.05e-4</td></tr><tr><td>1,000 getVertex</td><td>0.10</td><td>1.05e+4</td><td>1.10e-6</td></tr><tr><td>1,000 getEdge</td><td>23.44</td><td>42.67</td><td>0.00</td></tr><tr><td>tarjan</td><td>194.66</td><td>5.14</td><td>0.00</td></tr><tr><td>topologicalSort</td><td>151.88</td><td>6.58</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.10</td><td>1.01e+4</td><td>8.01e-7</td></tr><tr><td>1,000 addEdge</td><td>6.06</td><td>165.03</td><td>2.89e-4</td></tr><tr><td>1,000 getVertex</td><td>0.10</td><td>1.05e+4</td><td>9.35e-7</td></tr><tr><td>1,000 getEdge</td><td>23.80</td><td>42.02</td><td>0.00</td></tr><tr><td>tarjan</td><td>193.59</td><td>5.17</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>148.99</td><td>6.71</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 push</td><td>191.43</td><td>5.22</td><td>0.04</td></tr><tr><td>1,000,000 unshift</td><td>171.35</td><td>5.84</td><td>0.01</td></tr><tr><td>1,000,000 unshift & shift</td><td>151.25</td><td>6.61</td><td>0.00</td></tr><tr><td>1,000,000 addBefore</td><td>264.87</td><td>3.78</td><td>0.07</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>191.05</td><td>5.23</td><td>0.04</td></tr><tr><td>1,000,000 unshift</td><td>186.38</td><td>5.37</td><td>0.06</td></tr><tr><td>1,000,000 unshift & shift</td><td>151.27</td><td>6.61</td><td>0.00</td></tr><tr><td>1,000,000 addBefore</td><td>267.57</td><td>3.74</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>1,000,000 push & shift</td><td>173.29</td><td>5.77</td><td>0.05</td></tr><tr><td>10,000 push & pop</td><td>235.53</td><td>4.25</td><td>0.01</td></tr><tr><td>10,000 addBefore</td><td>278.19</td><td>3.59</td><td>0.01</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push & shift</td><td>163.01</td><td>6.13</td><td>0.03</td></tr><tr><td>10,000 push & pop</td><td>246.05</td><td>4.06</td><td>0.04</td></tr><tr><td>10,000 addBefore</td><td>275.54</td><td>3.63</td><td>0.01</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>priority-queue</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>30.64</td><td>32.64</td><td>0.00</td></tr><tr><td>100,000 add & poll</td><td>89.25</td><td>11.20</td><td>0.00</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>30.54</td><td>32.75</td><td>0.00</td></tr><tr><td>100,000 add & poll</td><td>89.20</td><td>11.21</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>40.92</td><td>24.44</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>46.83</td><td>21.35</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>40.42</td><td>24.74</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>47.90</td><td>20.88</td><td>0.01</td></tr></table></div>
|
||||
</div>
|
||||
|
||||
[//]: # (No deletion!!! End of Replace Section)
|
||||
|
@ -1218,4 +1221,4 @@ const {
|
|||
AVLTree, MinHeap, SinglyLinkedList, DirectedGraph, TreeMultiMap,
|
||||
DirectedVertex, AVLTreeNode
|
||||
} = dataStructureTyped;
|
||||
```
|
||||
```
|
||||
|
|
4
src/constants/index.ts
Normal file
4
src/constants/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export enum DFSOperation {
|
||||
VISIT = 0,
|
||||
PROCESS = 1
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {
|
||||
|
@ -11,11 +11,11 @@ import type {
|
|||
AVLTreeMultiMapOptions,
|
||||
BinaryTreeDeleteResult,
|
||||
BSTNKeyOrNode,
|
||||
BTNCallback,
|
||||
BTNKeyOrNodeOrEntry,
|
||||
IterationType
|
||||
BTNPredicate,
|
||||
IterationType,
|
||||
BTNEntry
|
||||
} from '../../types';
|
||||
import { BTNEntry } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { AVLTree, AVLTreeNode } from './avl-tree';
|
||||
|
||||
|
@ -80,18 +80,18 @@ export class AVLTreeMultiMap<
|
|||
{
|
||||
/**
|
||||
* The constructor initializes a new AVLTreeMultiMap object with optional initial elements.
|
||||
* @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an
|
||||
* @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an
|
||||
* iterable object that can contain either keys, nodes, entries, or raw elements.
|
||||
* @param [options] - The `options` parameter is an optional object that can be used to customize the
|
||||
* behavior of the AVLTreeMultiMap. It can include properties such as `compareKeys` and
|
||||
* `compareValues` functions to define custom comparison logic for keys and values, respectively.
|
||||
*/
|
||||
constructor(
|
||||
keysOrNodesOrEntriesOrRawElements: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
options?: AVLTreeMultiMapOptions<K, V, R>
|
||||
) {
|
||||
super([], options);
|
||||
if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements);
|
||||
if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);
|
||||
}
|
||||
|
||||
protected _count = 0;
|
||||
|
@ -144,29 +144,28 @@ export class AVLTreeMultiMap<
|
|||
override createTree(options?: AVLTreeMultiMapOptions<K, V, R>): TREE {
|
||||
return new AVLTreeMultiMap<K, V, R, NODE, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this.comparator,
|
||||
comparator: this._comparator,
|
||||
toEntryFn: this._toEntryFn,
|
||||
...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if the input is an instance of AVLTreeMultiMapNode.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is
|
||||
* an instance of the `AVLTreeMultiMapNode` class.
|
||||
*/
|
||||
override isNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>
|
||||
): keyOrNodeOrEntryOrRawElement is NODE {
|
||||
return keyOrNodeOrEntryOrRawElement instanceof AVLTreeMultiMapNode;
|
||||
override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {
|
||||
return keyOrNodeOrEntryOrRaw instanceof AVLTreeMultiMapNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function `keyValueOrEntryOrRawElementToNode` converts a key, value, entry, or raw element into
|
||||
* a node object.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The
|
||||
* `keyOrNodeOrEntryOrRawElement` parameter can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The
|
||||
* `keyOrNodeOrEntryOrRaw` parameter can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {V} [value] - The `value` parameter is an optional value that can be passed to the
|
||||
* `override` function. It represents the value associated with the key in the data structure. If no
|
||||
* value is provided, it will default to `undefined`.
|
||||
|
@ -175,25 +174,25 @@ export class AVLTreeMultiMap<
|
|||
* @returns either a NODE object or undefined.
|
||||
*/
|
||||
override keyValueOrEntryOrRawElementToNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>,
|
||||
keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,
|
||||
value?: V,
|
||||
count = 1
|
||||
): NODE | undefined {
|
||||
if (keyOrNodeOrEntryOrRawElement === undefined || keyOrNodeOrEntryOrRawElement === null) return;
|
||||
if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement;
|
||||
if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return;
|
||||
if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;
|
||||
|
||||
if (this.isEntry(keyOrNodeOrEntryOrRawElement)) {
|
||||
const [key, entryValue] = keyOrNodeOrEntryOrRawElement;
|
||||
if (this.isEntry(keyOrNodeOrEntryOrRaw)) {
|
||||
const [key, entryValue] = keyOrNodeOrEntryOrRaw;
|
||||
if (key === undefined || key === null) return;
|
||||
if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count);
|
||||
}
|
||||
|
||||
if (this.toEntryFn) {
|
||||
const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R);
|
||||
if (this._toEntryFn) {
|
||||
const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);
|
||||
if (this.isKey(key)) return this.createNode(key, value ?? entryValue, count);
|
||||
}
|
||||
|
||||
if (this.isKey(keyOrNodeOrEntryOrRawElement)) return this.createNode(keyOrNodeOrEntryOrRawElement, value, count);
|
||||
if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, count);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -204,8 +203,8 @@ export class AVLTreeMultiMap<
|
|||
*
|
||||
* The function overrides the add method of a TypeScript class to add a new node to a data structure
|
||||
* and update the count.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The
|
||||
* `keyOrNodeOrEntryOrRawElement` parameter can accept a value of type `R`, which can be any type. It
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The
|
||||
* `keyOrNodeOrEntryOrRaw` parameter can accept a value of type `R`, which can be any type. It
|
||||
* can also accept a value of type `BTNKeyOrNodeOrEntry<K, V, NODE>`, which represents a key, node,
|
||||
* entry, or raw element
|
||||
* @param {V} [value] - The `value` parameter represents the value associated with the key in the
|
||||
|
@ -215,8 +214,8 @@ export class AVLTreeMultiMap<
|
|||
* be added once. However, you can specify a different value for `count` if you want to add
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>, value?: V, count = 1): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value, count);
|
||||
override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V, count = 1): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count);
|
||||
if (newNode === undefined) return false;
|
||||
|
||||
const orgNodeCount = newNode?.count || 0;
|
||||
|
@ -231,31 +230,29 @@ export class AVLTreeMultiMap<
|
|||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `delete` function in a binary tree data structure deletes a node based on its identifier and
|
||||
* returns the deleted node along with the parent node that needs to be balanced.
|
||||
* @param identifier - The identifier parameter is the value used to identify the node that needs to
|
||||
* be deleted from the binary tree. It can be of any type and is the return type of the callback
|
||||
* function.
|
||||
* @param {C} callback - The `callback` parameter is a function that is used to determine the
|
||||
* equality of nodes in the binary tree. It is optional and has a default value of
|
||||
* `this._DEFAULT_CALLBACK`. The `callback` function takes a single argument, which is the identifier
|
||||
* of a node, and returns a value that
|
||||
* @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node
|
||||
* being deleted. If set to true, the count of the node will not be considered and the node will be
|
||||
* deleted regardless of its count. If set to false (default), the count of the node will be taken
|
||||
* into account and the node
|
||||
* @returns an array of `BinaryTreeDeleteResult<NODE>`.
|
||||
* The function overrides the delete method in a binary tree data structure, handling deletion of
|
||||
* nodes and maintaining balance in the tree.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`
|
||||
* parameter in the `delete` method is used to specify the condition for deleting a node from the
|
||||
* binary tree. It can be a key, node, entry, or a custom predicate function that determines which
|
||||
* node(s) should be deleted.
|
||||
* @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a
|
||||
* boolean flag that determines whether to ignore the count of the node being deleted. If
|
||||
* `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If
|
||||
* `ignoreCount` is set to
|
||||
* @returns The `delete` method overrides the default delete behavior in a binary tree data
|
||||
* structure. It takes a predicate or node to be deleted and an optional flag to ignore count. The
|
||||
* method returns an array of `BinaryTreeDeleteResult` objects, each containing information about the
|
||||
* deleted node and whether balancing is needed in the tree.
|
||||
*/
|
||||
override delete<C extends BTNCallback<NODE>>(
|
||||
identifier: ReturnType<C>,
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
override delete(
|
||||
predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,
|
||||
ignoreCount = false
|
||||
): BinaryTreeDeleteResult<NODE>[] {
|
||||
const deletedResult: BinaryTreeDeleteResult<NODE>[] = [];
|
||||
if (!this.root) return deletedResult;
|
||||
callback = this._ensureCallback(identifier, callback);
|
||||
|
||||
const curr: NODE | undefined = this.getNode(identifier, callback) ?? undefined;
|
||||
const curr: NODE | undefined = this.getNode(predicate) ?? undefined;
|
||||
if (!curr) return deletedResult;
|
||||
|
||||
const parent: NODE | undefined = curr?.parent ? curr.parent : undefined;
|
||||
|
@ -293,7 +290,7 @@ export class AVLTreeMultiMap<
|
|||
}
|
||||
}
|
||||
}
|
||||
this._size = this.size - 1;
|
||||
this._size = this._size - 1;
|
||||
// TODO How to handle when the count of target node is lesser than current node's count
|
||||
if (orgCurrent) this._count -= orgCurrent.count;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import { BST, BSTNode } from './bst';
|
||||
|
@ -12,10 +12,10 @@ import type {
|
|||
AVLTreeOptions,
|
||||
BinaryTreeDeleteResult,
|
||||
BSTNKeyOrNode,
|
||||
BTNCallback,
|
||||
BTNKeyOrNodeOrEntry
|
||||
BTNKeyOrNodeOrEntry,
|
||||
BTNPredicate,
|
||||
BTNEntry
|
||||
} from '../../types';
|
||||
import { BTNEntry } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
|
||||
export class AVLTreeNode<
|
||||
|
@ -78,7 +78,7 @@ export class AVLTree<
|
|||
/**
|
||||
* This is a constructor function for an AVLTree class that initializes the tree with keys, nodes,
|
||||
* entries, or raw elements.
|
||||
* @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an
|
||||
* @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an
|
||||
* iterable object that can contain either keys, nodes, entries, or raw elements. These elements will
|
||||
* be used to initialize the AVLTree.
|
||||
* @param [options] - The `options` parameter is an optional object that can be used to customize the
|
||||
|
@ -87,11 +87,11 @@ export class AVLTree<
|
|||
* `nodeBuilder` (
|
||||
*/
|
||||
constructor(
|
||||
keysOrNodesOrEntriesOrRawElements: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
options?: AVLTreeOptions<K, V, R>
|
||||
) {
|
||||
super([], options);
|
||||
if (keysOrNodesOrEntriesOrRawElements) super.addMany(keysOrNodesOrEntriesOrRawElements);
|
||||
if (keysOrNodesOrEntriesOrRaws) super.addMany(keysOrNodesOrEntriesOrRaws);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -117,22 +117,21 @@ export class AVLTree<
|
|||
override createTree(options?: AVLTreeOptions<K, V, R>): TREE {
|
||||
return new AVLTree<K, V, R, NODE, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this.comparator,
|
||||
comparator: this._comparator,
|
||||
toEntryFn: this._toEntryFn,
|
||||
...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if the input is an instance of AVLTreeNode.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is
|
||||
* an instance of the `AVLTreeNode` class.
|
||||
*/
|
||||
override isNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>
|
||||
): keyOrNodeOrEntryOrRawElement is NODE {
|
||||
return keyOrNodeOrEntryOrRawElement instanceof AVLTreeNode;
|
||||
override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {
|
||||
return keyOrNodeOrEntryOrRaw instanceof AVLTreeNode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,17 +140,17 @@ export class AVLTree<
|
|||
*
|
||||
* The function overrides the add method of a class and inserts a key-value pair into a data
|
||||
* structure, then balances the path.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can accept values of type `R`, `BTNKeyOrNodeOrEntry<K, V, NODE>`, or
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can accept values of type `R`, `BTNKeyOrNodeOrEntry<K, V, NODE>`, or
|
||||
* `RawElement`.
|
||||
* @param {V} [value] - The `value` parameter is an optional value that you want to associate with
|
||||
* the key or node being added to the data structure.
|
||||
* @returns The method is returning a boolean value.
|
||||
*/
|
||||
override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>, value?: V): boolean {
|
||||
if (keyOrNodeOrEntryOrRawElement === null) return false;
|
||||
const inserted = super.add(keyOrNodeOrEntryOrRawElement, value);
|
||||
if (inserted) this._balancePath(keyOrNodeOrEntryOrRawElement);
|
||||
override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {
|
||||
if (keyOrNodeOrEntryOrRaw === null) return false;
|
||||
const inserted = super.add(keyOrNodeOrEntryOrRaw, value);
|
||||
if (inserted) this._balancePath(keyOrNodeOrEntryOrRaw);
|
||||
return inserted;
|
||||
}
|
||||
|
||||
|
@ -159,20 +158,17 @@ export class AVLTree<
|
|||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function overrides the delete method of a binary tree class and performs additional operations
|
||||
* to balance the tree after deletion.
|
||||
* @param identifier - The `identifier` parameter is the value or condition used to identify the
|
||||
* node(s) to be deleted from the binary tree. It can be of any type that is compatible with the
|
||||
* binary tree's node type.
|
||||
* @param {C} callback - The `callback` parameter is a function that will be used to determine if a
|
||||
* node should be deleted or not. It is optional and has a default value of `this._DEFAULT_CALLBACK`.
|
||||
* @returns The method is returning an array of BinaryTreeDeleteResult<NODE> objects.
|
||||
* The function overrides the delete method in a TypeScript class, performs deletion, and then
|
||||
* balances the tree if necessary.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`
|
||||
* parameter in the `override delete` method can be one of the following types:
|
||||
* @returns The `delete` method is being overridden in this code snippet. It first calls the `delete`
|
||||
* method from the superclass (presumably a parent class) with the provided `predicate`, which could
|
||||
* be a key, node, entry, or a custom predicate. The result of this deletion operation is stored in
|
||||
* `deletedResults`, which is an array of `BinaryTreeDeleteResult` objects.
|
||||
*/
|
||||
override delete<C extends BTNCallback<NODE>>(
|
||||
identifier: ReturnType<C>,
|
||||
callback: C = this._DEFAULT_CALLBACK as C
|
||||
): BinaryTreeDeleteResult<NODE>[] {
|
||||
const deletedResults = super.delete(identifier, callback);
|
||||
override delete(predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>): BinaryTreeDeleteResult<NODE>[] {
|
||||
const deletedResults = super.delete(predicate);
|
||||
for (const { needBalanced } of deletedResults) {
|
||||
if (needBalanced) {
|
||||
this._balancePath(needBalanced);
|
||||
|
@ -437,10 +433,10 @@ export class AVLTree<
|
|||
*
|
||||
* The `_balancePath` function is used to update the heights of nodes and perform rotation operations
|
||||
* to restore balance in an AVL tree after inserting a node.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} node - The `node` parameter can be of type `R` or
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} node - The `node` parameter can be of type `R` or
|
||||
* `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
*/
|
||||
protected _balancePath(node: R | BTNKeyOrNodeOrEntry<K, V, NODE>): void {
|
||||
protected _balancePath(node: BTNKeyOrNodeOrEntry<K, V, NODE> | R): void {
|
||||
node = this.ensureNode(node);
|
||||
const path = this.getPathToRoot(node => node, node, false); // first O(log n) + O(log n)
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import { getMSB } from '../../utils';
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {
|
||||
|
@ -11,7 +11,9 @@ import type {
|
|||
BSTNodeNested,
|
||||
BSTOptions,
|
||||
BTNCallback,
|
||||
BTNEntry,
|
||||
BTNKeyOrNodeOrEntry,
|
||||
BTNPredicate,
|
||||
BTNPureKeyOrNodeOrEntry,
|
||||
Comparator,
|
||||
CP,
|
||||
|
@ -19,7 +21,6 @@ import type {
|
|||
IterationType,
|
||||
OptBSTN
|
||||
} from '../../types';
|
||||
import { BTNEntry } from '../../types';
|
||||
import { BinaryTree, BinaryTreeNode } from './binary-tree';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { Queue } from '../queue';
|
||||
|
@ -106,14 +107,14 @@ export class BST<
|
|||
{
|
||||
/**
|
||||
* This is the constructor function for a Binary Search Tree class in TypeScript.
|
||||
* @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an
|
||||
* @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an
|
||||
* iterable that can contain either keys, nodes, entries, or raw elements. These elements will be
|
||||
* added to the binary search tree during the construction of the object.
|
||||
* @param [options] - An optional object that contains additional options for the Binary Search Tree.
|
||||
* It can include a comparator function that defines the order of the elements in the tree.
|
||||
*/
|
||||
constructor(
|
||||
keysOrNodesOrEntriesOrRawElements: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
options?: BSTOptions<K, V, R>
|
||||
) {
|
||||
super([], options);
|
||||
|
@ -123,7 +124,7 @@ export class BST<
|
|||
if (comparator) this._comparator = comparator;
|
||||
}
|
||||
|
||||
if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements);
|
||||
if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);
|
||||
}
|
||||
|
||||
protected override _root?: NODE = undefined;
|
||||
|
@ -155,17 +156,18 @@ export class BST<
|
|||
* following properties:
|
||||
* @returns a new instance of the BST class with the provided options.
|
||||
*/
|
||||
override createTree(options?: Partial<BSTOptions<K, V, R>>): TREE {
|
||||
override createTree(options?: BSTOptions<K, V, R>): TREE {
|
||||
return new BST<K, V, R, NODE, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this.comparator,
|
||||
comparator: this._comparator,
|
||||
toEntryFn: this._toEntryFn,
|
||||
...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function overrides a method and converts a key, value pair or entry or raw element to a node.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - A variable that can be of
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - A variable that can be of
|
||||
* type R or BTNKeyOrNodeOrEntry<K, V, NODE>. It represents either a key, a node, an entry, or a raw
|
||||
* element.
|
||||
* @param {V} [value] - The `value` parameter is an optional value of type `V`. It represents the
|
||||
|
@ -173,10 +175,10 @@ export class BST<
|
|||
* @returns either a NODE object or undefined.
|
||||
*/
|
||||
override keyValueOrEntryOrRawElementToNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>,
|
||||
keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,
|
||||
value?: V
|
||||
): OptBSTN<NODE> {
|
||||
return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value) ?? undefined;
|
||||
return super.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value) ?? undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,8 +187,8 @@ export class BST<
|
|||
*
|
||||
* The function ensures the existence of a node in a data structure and returns it, or undefined if
|
||||
* it doesn't exist.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can accept a value of type `R`, which represents the key, node,
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can accept a value of type `R`, which represents the key, node,
|
||||
* entry, or raw element that needs to be ensured in the tree.
|
||||
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter is an optional
|
||||
* parameter that specifies the type of iteration to be used when ensuring a node. It has a default
|
||||
|
@ -195,25 +197,31 @@ export class BST<
|
|||
* not be ensured.
|
||||
*/
|
||||
override ensureNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>,
|
||||
keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,
|
||||
iterationType: IterationType = this.iterationType
|
||||
): OptBSTN<NODE> {
|
||||
return super.ensureNode(keyOrNodeOrEntryOrRawElement, iterationType) ?? undefined;
|
||||
return super.ensureNode(keyOrNodeOrEntryOrRaw, iterationType) ?? undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if the input is an instance of the BSTNode class.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is
|
||||
* an instance of the `BSTNode` class.
|
||||
*/
|
||||
override isNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>
|
||||
): keyOrNodeOrEntryOrRawElement is NODE {
|
||||
return keyOrNodeOrEntryOrRawElement instanceof BSTNode;
|
||||
override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {
|
||||
return keyOrNodeOrEntryOrRaw instanceof BSTNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function "override isKey" checks if a key is comparable based on a given comparator.
|
||||
* @param {any} key - The `key` parameter is a value that will be checked to determine if it is of
|
||||
* type `K`.
|
||||
* @returns The `override isKey(key: any): key is K` function is returning a boolean value based on
|
||||
* the result of the `isComparable` function with the condition `this.comparator !==
|
||||
* this._DEFAULT_COMPARATOR`.
|
||||
*/
|
||||
override isKey(key: any): key is K {
|
||||
return isComparable(key, this.comparator !== this._DEFAULT_COMPARATOR);
|
||||
}
|
||||
|
@ -223,23 +231,23 @@ export class BST<
|
|||
* Space Complexity: O(1)
|
||||
*
|
||||
* The `add` function in TypeScript adds a new node to a binary search tree based on the key value.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {V} [value] - The `value` parameter is an optional value that can be associated with the
|
||||
* key in the binary search tree. If provided, it will be stored in the node along with the key.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>, value?: V): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value);
|
||||
override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);
|
||||
if (newNode === undefined) return false;
|
||||
|
||||
if (this.root === undefined) {
|
||||
if (this._root === undefined) {
|
||||
this._setRoot(newNode);
|
||||
this._size++;
|
||||
return true;
|
||||
}
|
||||
|
||||
let current = this.root;
|
||||
let current = this._root;
|
||||
while (current !== undefined) {
|
||||
if (this.comparator(current.key, newNode.key) === 0) {
|
||||
this._replaceNode(current, newNode);
|
||||
|
@ -270,7 +278,7 @@ export class BST<
|
|||
*
|
||||
* The `addMany` function in TypeScript adds multiple keys or nodes to a data structure and returns
|
||||
* an array indicating whether each key or node was successfully inserted.
|
||||
* @param keysOrNodesOrEntriesOrRawElements - An iterable containing keys, nodes, entries, or raw
|
||||
* @param keysOrNodesOrEntriesOrRaws - An iterable containing keys, nodes, entries, or raw
|
||||
* elements to be added to the data structure.
|
||||
* @param [values] - An optional iterable of values to be associated with the keys or nodes being
|
||||
* added. If provided, the values will be assigned to the corresponding keys or nodes in the same
|
||||
|
@ -286,7 +294,7 @@ export class BST<
|
|||
* successfully inserted into the data structure.
|
||||
*/
|
||||
override addMany(
|
||||
keysOrNodesOrEntriesOrRawElements: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>>,
|
||||
keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>>,
|
||||
values?: Iterable<V | undefined>,
|
||||
isBalanceAdd = true,
|
||||
iterationType: IterationType = this.iterationType
|
||||
|
@ -300,7 +308,7 @@ export class BST<
|
|||
}
|
||||
|
||||
if (!isBalanceAdd) {
|
||||
for (const kve of keysOrNodesOrEntriesOrRawElements) {
|
||||
for (const kve of keysOrNodesOrEntriesOrRaws) {
|
||||
const value = valuesIterator?.next().value;
|
||||
const nn = this.add(kve, value);
|
||||
inserted.push(nn);
|
||||
|
@ -311,13 +319,13 @@ export class BST<
|
|||
const realBTNExemplars: (R | BTNPureKeyOrNodeOrEntry<K, V, NODE>)[] = [];
|
||||
|
||||
const isRealBTNExemplar = (
|
||||
kve: R | BTNKeyOrNodeOrEntry<K, V, NODE>
|
||||
kve: BTNKeyOrNodeOrEntry<K, V, NODE> | R
|
||||
): kve is BTNPureKeyOrNodeOrEntry<K, V, NODE> => {
|
||||
if (kve === undefined || kve === null) return false;
|
||||
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
|
||||
};
|
||||
|
||||
for (const kve of keysOrNodesOrEntriesOrRawElements) {
|
||||
for (const kve of keysOrNodesOrEntriesOrRaws) {
|
||||
if (isRealBTNExemplar(kve)) realBTNExemplars.push(kve);
|
||||
}
|
||||
|
||||
|
@ -327,16 +335,16 @@ export class BST<
|
|||
let keyA: K | undefined | null, keyB: K | undefined | null;
|
||||
if (this.isEntry(a)) keyA = a[0];
|
||||
else if (this.isRealNode(a)) keyA = a.key;
|
||||
else if (this.toEntryFn) {
|
||||
keyA = this.toEntryFn(a as R)[0];
|
||||
else if (this._toEntryFn) {
|
||||
keyA = this._toEntryFn(a as R)[0];
|
||||
} else {
|
||||
keyA = a as K;
|
||||
}
|
||||
|
||||
if (this.isEntry(b)) keyB = b[0];
|
||||
else if (this.isRealNode(b)) keyB = b.key;
|
||||
else if (this.toEntryFn) {
|
||||
keyB = this.toEntryFn(b as R)[0];
|
||||
else if (this._toEntryFn) {
|
||||
keyB = this._toEntryFn(b as R)[0];
|
||||
} else {
|
||||
keyB = b as K;
|
||||
}
|
||||
|
@ -388,51 +396,49 @@ export class BST<
|
|||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(k + log n)
|
||||
*
|
||||
* The `getNodes` function in TypeScript retrieves nodes from a binary tree based on a given
|
||||
* identifier and callback function.
|
||||
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you
|
||||
* want to search for in the binary tree. It can be of any type that is returned by the callback
|
||||
* function.
|
||||
* @param {C} callback - The `callback` parameter is a function that takes a node as input and
|
||||
* returns a value. This value is used to identify the nodes that match the given identifier. The
|
||||
* `callback` function is optional and defaults to `this._DEFAULT_CALLBACK`.
|
||||
* @param [onlyOne=false] - A boolean value indicating whether to return only the first matching node
|
||||
* or all matching nodes. If set to true, only the first matching node will be returned. If set to
|
||||
* false, all matching nodes will be returned. The default value is false.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
||||
* point for the search in the binary tree. It can be either a node object, a key-value pair, or an
|
||||
* entry object. If it is not provided, the `root` of the binary tree is used as the starting point.
|
||||
* @param {IterationType} iterationType - The `iterationType` parameter determines the type of
|
||||
* iteration to be performed. It can have two possible values:
|
||||
* @returns The method `getNodes` returns an array of `NODE` objects.
|
||||
* The function `getNodes` in TypeScript overrides the base class method to retrieve nodes based on a
|
||||
* given predicate and iteration type.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`
|
||||
* parameter in the `getNodes` method is used to filter the nodes that will be returned. It can be a
|
||||
* key, a node, an entry, or a custom predicate function that determines whether a node should be
|
||||
* included in the result.
|
||||
* @param [onlyOne=false] - The `onlyOne` parameter in the `getNodes` method is a boolean flag that
|
||||
* determines whether to return only the first node that matches the predicate (`true`) or all nodes
|
||||
* that match the predicate (`false`). If `onlyOne` is set to `true`, the method will stop iterating
|
||||
* and
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter in the
|
||||
* `getNodes` method is used to specify the starting point for traversing the tree when searching for
|
||||
* nodes that match a given predicate. It represents the root node of the subtree where the search
|
||||
* should begin. If not explicitly provided, the default value for `begin
|
||||
* @param {IterationType} iterationType - The `iterationType` parameter in the `getNodes` method
|
||||
* specifies the type of iteration to be performed when traversing the nodes of a binary tree. It can
|
||||
* have two possible values:
|
||||
* @returns The `getNodes` method returns an array of nodes that satisfy the given predicate.
|
||||
*/
|
||||
override getNodes<C extends BTNCallback<NODE>>(
|
||||
identifier: ReturnType<C> | undefined,
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
override getNodes(
|
||||
predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,
|
||||
onlyOne = false,
|
||||
beginRoot: R | BTNKeyOrNodeOrEntry<K, V, NODE> = this.root,
|
||||
beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,
|
||||
iterationType: IterationType = this.iterationType
|
||||
): NODE[] {
|
||||
if (identifier === undefined) return [];
|
||||
if (identifier === null) return [];
|
||||
if (predicate === undefined) return [];
|
||||
if (predicate === null) return [];
|
||||
beginRoot = this.ensureNode(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
callback = this._ensureCallback(identifier, callback);
|
||||
const callback = this._ensurePredicate(predicate);
|
||||
const ans: NODE[] = [];
|
||||
|
||||
if (iterationType === 'RECURSIVE') {
|
||||
const dfs = (cur: NODE) => {
|
||||
const callbackResult = callback(cur);
|
||||
if (callbackResult === identifier) {
|
||||
if (callback(cur)) {
|
||||
ans.push(cur);
|
||||
if (onlyOne) return;
|
||||
}
|
||||
|
||||
if (!this.isRealNode(cur.left) && !this.isRealNode(cur.right)) return;
|
||||
// TODO potential bug
|
||||
if (callback === this._DEFAULT_CALLBACK) {
|
||||
if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) dfs(cur.left);
|
||||
if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) dfs(cur.right);
|
||||
if (this.isKey(predicate)) {
|
||||
if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) dfs(cur.left);
|
||||
if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) dfs(cur.right);
|
||||
} else {
|
||||
if (this.isRealNode(cur.left)) dfs(cur.left);
|
||||
if (this.isRealNode(cur.right)) dfs(cur.right);
|
||||
|
@ -444,23 +450,13 @@ export class BST<
|
|||
const stack = [beginRoot];
|
||||
while (stack.length > 0) {
|
||||
const cur = stack.pop()!;
|
||||
const callbackResult = callback(cur);
|
||||
if (callbackResult === identifier) {
|
||||
if (callback(cur)) {
|
||||
ans.push(cur);
|
||||
if (onlyOne) return ans;
|
||||
}
|
||||
// TODO potential bug
|
||||
if (callback === this._DEFAULT_CALLBACK) {
|
||||
if (this.isRealNode(cur.right) && this.comparator(cur.key, identifier as K) < 0) stack.push(cur.right);
|
||||
if (this.isRealNode(cur.left) && this.comparator(cur.key, identifier as K) > 0) stack.push(cur.left);
|
||||
|
||||
// if (this.isRealNode(cur.right) && this._lt(cur.key, identifier as K)) stack.push(cur.right);
|
||||
// if (this.isRealNode(cur.left) && this._gt(cur.key, identifier as K)) stack.push(cur.left);
|
||||
|
||||
// // @ts-ignore
|
||||
// if (this.isRealNode(cur.right) && cur.key > identifier) stack.push(cur.right);
|
||||
// // @ts-ignore
|
||||
// if (this.isRealNode(cur.left) && cur.key < identifier) stack.push(cur.left);
|
||||
if (this.isKey(predicate)) {
|
||||
if (this.isRealNode(cur.right) && this.comparator(cur.key, predicate) < 0) stack.push(cur.right);
|
||||
if (this.isRealNode(cur.left) && this.comparator(cur.key, predicate) > 0) stack.push(cur.left);
|
||||
} else {
|
||||
if (this.isRealNode(cur.right)) stack.push(cur.right);
|
||||
if (this.isRealNode(cur.left)) stack.push(cur.left);
|
||||
|
@ -475,30 +471,28 @@ export class BST<
|
|||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `getNode` returns the first node that matches the given identifier and callback
|
||||
* function in a binary search tree.
|
||||
* @param {ReturnType<C> | undefined} identifier - The `identifier` parameter is the value that you
|
||||
* want to search for in the binary search tree. It can be of any type that is compatible with the
|
||||
* type returned by the callback function.
|
||||
* @param {C} callback - The `callback` parameter is a function that will be used to determine if a
|
||||
* node matches the desired criteria. It should be a function that takes a node as an argument and
|
||||
* returns a boolean value indicating whether the node matches the criteria or not. If no callback is
|
||||
* provided, the default callback will be
|
||||
* @param beginRoot - The `beginRoot` parameter is the starting point for the search in the binary
|
||||
* search tree. It can be either a key or a node. If it is a key, the search will start from the node
|
||||
* with that key. If it is a node, the search will start from that node.
|
||||
* @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
|
||||
* of iteration to be performed when searching for nodes in the binary search tree. It can have one
|
||||
* of the following values:
|
||||
* @returns The method is returning a NODE object or undefined.
|
||||
* This function retrieves a node based on a given predicate within a binary search tree structure.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`
|
||||
* parameter can be of type `BTNKeyOrNodeOrEntry<K, V, NODE>`, `R`, or `BTNPredicate<NODE>`.
|
||||
* @param {R | BSTNKeyOrNode<K, NODE>} beginRoot - The `beginRoot` parameter in the `getNode` method
|
||||
* is used to specify the starting point for searching nodes in the binary search tree. If no
|
||||
* specific starting point is provided, the default value is set to `this._root`, which is the root
|
||||
* node of the binary search tree.
|
||||
* @param {IterationType} iterationType - The `iterationType` parameter in the `getNode` method is a
|
||||
* parameter that specifies the type of iteration to be used. It has a default value of
|
||||
* `this.iterationType`, which means it will use the iteration type defined in the class instance if
|
||||
* no value is provided when calling the method.
|
||||
* @returns The `getNode` method is returning an optional binary search tree node (`OptBSTN<NODE>`).
|
||||
* It is using the `getNodes` method to find the node based on the provided predicate, beginning at
|
||||
* the specified root node (`beginRoot`) and using the specified iteration type. The method then
|
||||
* returns the first node found or `undefined` if no node is found.
|
||||
*/
|
||||
override getNode<C extends BTNCallback<NODE>>(
|
||||
identifier: ReturnType<C> | undefined,
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
beginRoot: R | BSTNKeyOrNode<K, NODE> = this.root,
|
||||
override getNode(
|
||||
predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,
|
||||
beginRoot: R | BSTNKeyOrNode<K, NODE> = this._root,
|
||||
iterationType: IterationType = this.iterationType
|
||||
): OptBSTN<NODE> {
|
||||
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? undefined;
|
||||
return this.getNodes(predicate, true, beginRoot, iterationType)[0] ?? undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -515,7 +509,7 @@ export class BST<
|
|||
* @returns The method is returning a NODE object or undefined.
|
||||
*/
|
||||
override getNodeByKey(key: K, iterationType: IterationType = this.iterationType): OptBSTN<NODE> {
|
||||
return this.getNode(key, this._DEFAULT_CALLBACK, this.root, iterationType);
|
||||
return this.getNode(key, this._root, iterationType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -526,11 +520,11 @@ export class BST<
|
|||
* the callback function.
|
||||
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
||||
* during the depth-first search traversal. It is an optional parameter and defaults to
|
||||
* `this._DEFAULT_CALLBACK`. The type `C` represents the type of the callback function.
|
||||
* `this._DEFAULT_BTN_CALLBACK`. The type `C` represents the type of the callback function.
|
||||
* @param {DFSOrderPattern} [pattern=IN] - The "pattern" parameter in the code snippet refers to the
|
||||
* order in which the Depth-First Search (DFS) algorithm visits the nodes in a tree or graph. It can
|
||||
* take one of the following values:
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting
|
||||
* point for the depth-first search traversal. It can be either a root node, a key-value pair, or a
|
||||
* node entry. If not specified, the default value is the root of the tree.
|
||||
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter specifies the
|
||||
|
@ -539,9 +533,9 @@ export class BST<
|
|||
* @returns The method is returning an array of the return type of the callback function.
|
||||
*/
|
||||
override dfs<C extends BTNCallback<NODE>>(
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
callback: C = this._DEFAULT_BTN_CALLBACK as C,
|
||||
pattern: DFSOrderPattern = 'IN',
|
||||
beginRoot: R | BTNKeyOrNodeOrEntry<K, V, NODE> = this.root,
|
||||
beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,
|
||||
iterationType: IterationType = this.iterationType
|
||||
): ReturnType<C>[] {
|
||||
return super.dfs(callback, pattern, beginRoot, iterationType);
|
||||
|
@ -556,7 +550,7 @@ export class BST<
|
|||
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
||||
* visited during the breadth-first search. It should take a single argument, which is the current
|
||||
* node being visited, and it can return a value of any type.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting
|
||||
* point for the breadth-first search. It can be either a root node, a key-value pair, or an entry
|
||||
* object. If no value is provided, the default value is the root of the tree.
|
||||
* @param {IterationType} iterationType - The `iterationType` parameter is used to specify the type
|
||||
|
@ -565,8 +559,8 @@ export class BST<
|
|||
* @returns an array of the return type of the callback function.
|
||||
*/
|
||||
override bfs<C extends BTNCallback<NODE>>(
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
beginRoot: R | BTNKeyOrNodeOrEntry<K, V, NODE> = this.root,
|
||||
callback: C = this._DEFAULT_BTN_CALLBACK as C,
|
||||
beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,
|
||||
iterationType: IterationType = this.iterationType
|
||||
): ReturnType<C>[] {
|
||||
return super.bfs(callback, beginRoot, iterationType, false);
|
||||
|
@ -581,7 +575,7 @@ export class BST<
|
|||
* @param {C} callback - The `callback` parameter is a generic type `C` that extends
|
||||
* `BTNCallback<NODE>`. It represents a callback function that will be called for each node in the
|
||||
* tree during the iteration process.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} beginRoot - The `beginRoot` parameter is the starting
|
||||
* point for listing the levels of the binary tree. It can be either a root node of the tree, a
|
||||
* key-value pair representing a node in the tree, or a key representing a node in the tree. If no
|
||||
* value is provided, the root of
|
||||
|
@ -591,8 +585,8 @@ export class BST<
|
|||
* function.
|
||||
*/
|
||||
override listLevels<C extends BTNCallback<NODE>>(
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
beginRoot: R | BTNKeyOrNodeOrEntry<K, V, NODE> = this.root,
|
||||
callback: C = this._DEFAULT_BTN_CALLBACK as C,
|
||||
beginRoot: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,
|
||||
iterationType: IterationType = this.iterationType
|
||||
): ReturnType<C>[][] {
|
||||
return super.listLevels(callback, beginRoot, iterationType, false);
|
||||
|
@ -610,7 +604,7 @@ export class BST<
|
|||
* @param {CP} lesserOrGreater - The `lesserOrGreater` parameter is used to determine whether to
|
||||
* traverse nodes that are lesser, greater, or both than the `targetNode`. It accepts the values -1,
|
||||
* 0, or 1, where:
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} targetNode - The `targetNode` parameter is the node in
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} targetNode - The `targetNode` parameter is the node in
|
||||
* the binary tree that you want to start traversing from. It can be specified either by providing
|
||||
* the key of the node, the node itself, or an entry containing the key and value of the node. If no
|
||||
* `targetNode` is provided,
|
||||
|
@ -620,14 +614,14 @@ export class BST<
|
|||
* `ReturnType<C>`, which is the return type of the callback function passed as an argument.
|
||||
*/
|
||||
lesserOrGreaterTraverse<C extends BTNCallback<NODE>>(
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
callback: C = this._DEFAULT_BTN_CALLBACK as C,
|
||||
lesserOrGreater: CP = -1,
|
||||
targetNode: R | BTNKeyOrNodeOrEntry<K, V, NODE> = this.root,
|
||||
targetNode: BTNKeyOrNodeOrEntry<K, V, NODE> | R = this._root,
|
||||
iterationType: IterationType = this.iterationType
|
||||
): ReturnType<C>[] {
|
||||
const targetNodeEnsured = this.ensureNode(targetNode);
|
||||
const ans: ReturnType<BTNCallback<NODE>>[] = [];
|
||||
if (!this.root) return ans;
|
||||
if (!this._root) return ans;
|
||||
if (!targetNodeEnsured) return ans;
|
||||
|
||||
const targetKey = targetNodeEnsured.key;
|
||||
|
@ -641,10 +635,10 @@ export class BST<
|
|||
if (this.isRealNode(cur.right)) dfs(cur.right);
|
||||
};
|
||||
|
||||
dfs(this.root);
|
||||
dfs(this._root);
|
||||
return ans;
|
||||
} else {
|
||||
const queue = new Queue<NODE>([this.root]);
|
||||
const queue = new Queue<NODE>([this._root]);
|
||||
while (queue.size > 0) {
|
||||
const cur = queue.shift();
|
||||
if (this.isRealNode(cur)) {
|
||||
|
@ -721,7 +715,7 @@ export class BST<
|
|||
* @returns a boolean value.
|
||||
*/
|
||||
isAVLBalanced(iterationType: IterationType = this.iterationType): boolean {
|
||||
if (!this.root) return true;
|
||||
if (!this._root) return true;
|
||||
|
||||
let balanced = true;
|
||||
|
||||
|
@ -733,10 +727,10 @@ export class BST<
|
|||
if (Math.abs(leftHeight - rightHeight) > 1) balanced = false;
|
||||
return Math.max(leftHeight, rightHeight) + 1;
|
||||
};
|
||||
_height(this.root);
|
||||
_height(this._root);
|
||||
} else {
|
||||
const stack: NODE[] = [];
|
||||
let node: OptBSTN<NODE> = this.root,
|
||||
let node: OptBSTN<NODE> = this._root,
|
||||
last: OptBSTN<NODE> = undefined;
|
||||
const depths: Map<NODE, number> = new Map();
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import type {
|
||||
BinaryTreeDeleteResult,
|
||||
BTNCallback,
|
||||
BTNKeyOrNodeOrEntry,
|
||||
BTNPredicate,
|
||||
CRUD,
|
||||
OptBSTN,
|
||||
RBTNColor,
|
||||
RBTreeOptions,
|
||||
RedBlackTreeNested,
|
||||
RedBlackTreeNodeNested
|
||||
RedBlackTreeNodeNested,
|
||||
BTNEntry
|
||||
} from '../../types';
|
||||
import { BTNEntry } from '../../types';
|
||||
import { BST, BSTNode } from './bst';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
|
||||
|
@ -64,7 +65,7 @@ export class RedBlackTree<
|
|||
{
|
||||
/**
|
||||
* This is the constructor function for a Red-Black Tree data structure in TypeScript.
|
||||
* @param keysOrNodesOrEntriesOrRawElements - The `keysOrNodesOrEntriesOrRawElements` parameter is an
|
||||
* @param keysOrNodesOrEntriesOrRaws - The `keysOrNodesOrEntriesOrRaws` parameter is an
|
||||
* iterable object that can contain either keys, nodes, entries, or raw elements. It is used to
|
||||
* initialize the RBTree with the provided elements.
|
||||
* @param [options] - The `options` parameter is an optional object that can be passed to the
|
||||
|
@ -73,15 +74,15 @@ export class RedBlackTree<
|
|||
* depend on the implementation
|
||||
*/
|
||||
constructor(
|
||||
keysOrNodesOrEntriesOrRawElements: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
keysOrNodesOrEntriesOrRaws: Iterable<R | BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
options?: RBTreeOptions<K, V, R>
|
||||
) {
|
||||
super([], options);
|
||||
|
||||
this._root = this.NIL;
|
||||
|
||||
if (keysOrNodesOrEntriesOrRawElements) {
|
||||
this.addMany(keysOrNodesOrEntriesOrRawElements);
|
||||
if (keysOrNodesOrEntriesOrRaws) {
|
||||
this.addMany(keysOrNodesOrEntriesOrRaws);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +123,8 @@ export class RedBlackTree<
|
|||
override createTree(options?: RBTreeOptions<K, V, R>): TREE {
|
||||
return new RedBlackTree<K, V, R, NODE, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this._comparator,
|
||||
toEntryFn: this._toEntryFn,
|
||||
...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
@ -131,15 +134,13 @@ export class RedBlackTree<
|
|||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function checks if the input is an instance of the RedBlackTreeNode class.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is
|
||||
* an instance of the `RedBlackTreeNode` class.
|
||||
*/
|
||||
override isNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>
|
||||
): keyOrNodeOrEntryOrRawElement is NODE {
|
||||
return keyOrNodeOrEntryOrRawElement instanceof RedBlackTreeNode;
|
||||
override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {
|
||||
return keyOrNodeOrEntryOrRaw instanceof RedBlackTreeNode;
|
||||
}
|
||||
|
||||
// /**
|
||||
|
@ -153,27 +154,27 @@ export class RedBlackTree<
|
|||
// *
|
||||
// * The function `keyValueOrEntryOrRawElementToNode` takes a key, value, or entry and returns a node if it is
|
||||
// * valid, otherwise it returns undefined.
|
||||
// * @param {BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The key, value, or entry to convert.
|
||||
// * @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntryOrRawElement` is a key).
|
||||
// * @param {BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRaw - The key, value, or entry to convert.
|
||||
// * @param {V} [value] - The value associated with the key (if `keyOrNodeOrEntryOrRaw` is a key).
|
||||
// * @returns {NODE | undefined} - The corresponding Red-Black Tree node, or `undefined` if conversion fails.
|
||||
// */
|
||||
// override keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>, value?: V): NODE | undefined {
|
||||
// override keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): NODE | undefined {
|
||||
//
|
||||
// if (keyOrNodeOrEntryOrRawElement === null || keyOrNodeOrEntryOrRawElement === undefined) return;
|
||||
// if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement;
|
||||
// if (keyOrNodeOrEntryOrRaw === null || keyOrNodeOrEntryOrRaw === undefined) return;
|
||||
// if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;
|
||||
//
|
||||
// if (this.toEntryFn) {
|
||||
// const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R);
|
||||
// if (this._toEntryFn) {
|
||||
// const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);
|
||||
// if (this.isKey(key)) return this.createNode(key, entryValue ?? value, 'RED');
|
||||
// }
|
||||
//
|
||||
// if (this.isEntry(keyOrNodeOrEntryOrRawElement)) {
|
||||
// const [key, value] = keyOrNodeOrEntryOrRawElement;
|
||||
// if (this.isEntry(keyOrNodeOrEntryOrRaw)) {
|
||||
// const [key, value] = keyOrNodeOrEntryOrRaw;
|
||||
// if (key === undefined || key === null) return;
|
||||
// else return this.createNode(key, value, 'RED');
|
||||
// }
|
||||
//
|
||||
// if (this.isKey(keyOrNodeOrEntryOrRawElement)) return this.createNode(keyOrNodeOrEntryOrRawElement, value, 'RED');
|
||||
// if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'RED');
|
||||
//
|
||||
// return ;
|
||||
// }
|
||||
|
@ -196,8 +197,8 @@ export class RedBlackTree<
|
|||
*
|
||||
* The function adds a new node to a binary search tree and returns true if the node was successfully
|
||||
* added.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can accept a value of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {V} [value] - The `value` parameter is an optional value that you want to associate with
|
||||
* the key in the data structure. It represents the value that you want to add or update in the data
|
||||
* structure.
|
||||
|
@ -205,8 +206,8 @@ export class RedBlackTree<
|
|||
* the method returns true. If the node already exists and its value is updated, the method also
|
||||
* returns true. If the node cannot be added or updated, the method returns false.
|
||||
*/
|
||||
override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>, value?: V): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value);
|
||||
override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value);
|
||||
if (!this.isRealNode(newNode)) return false;
|
||||
|
||||
const insertStatus = this._insert(newNode);
|
||||
|
@ -227,26 +228,23 @@ export class RedBlackTree<
|
|||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function overrides the delete method of a binary tree data structure, allowing for the
|
||||
* deletion of a node and maintaining the balance of the tree.
|
||||
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value
|
||||
* that identifies the node to be deleted from the binary tree. It can be of any type that is
|
||||
* returned by the callback function `C`. It can also be `null` or `undefined` if there is no node to
|
||||
* delete.
|
||||
* @param {C} callback - The `callback` parameter is a function that is used to determine the
|
||||
* equality of nodes in the binary tree. It is optional and has a default value of
|
||||
* `this._DEFAULT_CALLBACK`. The type of the `callback` parameter is `C`, which is a generic type
|
||||
* that extends the `BTNCallback
|
||||
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
|
||||
* The function overrides the delete method in a binary tree data structure to remove a node based on
|
||||
* a given predicate and maintain the binary search tree properties.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`
|
||||
* parameter in the `override delete` method is used to specify the condition or key based on which a
|
||||
* node should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate
|
||||
* function that determines which node(s) should be deleted.
|
||||
* @returns The `override delete` method is returning an array of `BinaryTreeDeleteResult<NODE>`
|
||||
* objects. Each object in the array contains information about the deleted node and whether
|
||||
* balancing is needed.
|
||||
*/
|
||||
override delete<C extends BTNCallback<NODE>>(
|
||||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C = this._DEFAULT_CALLBACK as C
|
||||
): BinaryTreeDeleteResult<NODE>[] {
|
||||
if (identifier === null) return [];
|
||||
override delete(predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>): BinaryTreeDeleteResult<NODE>[] {
|
||||
if (predicate === null) return [];
|
||||
|
||||
const results: BinaryTreeDeleteResult<NODE>[] = [];
|
||||
callback = this._ensureCallback(identifier, callback);
|
||||
const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
|
||||
let nodeToDelete: OptBSTN<NODE>;
|
||||
if (this._isPredicated(predicate)) nodeToDelete = this.getNode(predicate);
|
||||
else nodeToDelete = this.isRealNode(predicate) ? predicate : this.getNode(predicate);
|
||||
|
||||
if (!nodeToDelete) {
|
||||
return results;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {
|
||||
BinaryTreeDeleteResult,
|
||||
BSTNKeyOrNode,
|
||||
BTNCallback,
|
||||
BTNKeyOrNodeOrEntry,
|
||||
BTNPredicate,
|
||||
IterationType,
|
||||
OptBSTN,
|
||||
RBTNColor,
|
||||
TreeMultiMapNested,
|
||||
TreeMultiMapNodeNested,
|
||||
TreeMultiMapOptions
|
||||
TreeMultiMapOptions,
|
||||
BTNEntry
|
||||
} from '../../types';
|
||||
import { BTNEntry } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { RedBlackTree, RedBlackTreeNode } from './rb-tree';
|
||||
|
||||
|
@ -74,7 +75,7 @@ export class TreeMultiMap<
|
|||
{
|
||||
/**
|
||||
* The constructor function initializes a TreeMultiMap object with optional initial data.
|
||||
* @param keysOrNodesOrEntriesOrRawElements - The parameter `keysOrNodesOrEntriesOrRawElements` is an
|
||||
* @param keysOrNodesOrEntriesOrRaws - The parameter `keysOrNodesOrEntriesOrRaws` is an
|
||||
* iterable that can contain keys, nodes, entries, or raw elements. It is used to initialize the
|
||||
* TreeMultiMap with initial data.
|
||||
* @param [options] - The `options` parameter is an optional object that can be used to customize the
|
||||
|
@ -82,11 +83,11 @@ export class TreeMultiMap<
|
|||
* `compareValues`, which are functions used to compare keys and values respectively.
|
||||
*/
|
||||
constructor(
|
||||
keysOrNodesOrEntriesOrRawElements: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
keysOrNodesOrEntriesOrRaws: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE>> = [],
|
||||
options?: TreeMultiMapOptions<K, V, R>
|
||||
) {
|
||||
super([], options);
|
||||
if (keysOrNodesOrEntriesOrRawElements) this.addMany(keysOrNodesOrEntriesOrRawElements);
|
||||
if (keysOrNodesOrEntriesOrRaws) this.addMany(keysOrNodesOrEntriesOrRaws);
|
||||
}
|
||||
|
||||
protected _count = 0;
|
||||
|
@ -142,6 +143,8 @@ export class TreeMultiMap<
|
|||
override createTree(options?: TreeMultiMapOptions<K, V, R>): TREE {
|
||||
return new TreeMultiMap<K, V, R, NODE, TREE>([], {
|
||||
iterationType: this.iterationType,
|
||||
comparator: this._comparator,
|
||||
toEntryFn: this._toEntryFn,
|
||||
...options
|
||||
}) as TREE;
|
||||
}
|
||||
|
@ -149,8 +152,8 @@ export class TreeMultiMap<
|
|||
/**
|
||||
* The function `keyValueOrEntryOrRawElementToNode` takes in a key, value, and count and returns a
|
||||
* node based on the input.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @param {V} [value] - The `value` parameter is an optional value that represents the value
|
||||
* associated with the key in the node. It is used when creating a new node or updating the value of
|
||||
* an existing node.
|
||||
|
@ -159,42 +162,39 @@ export class TreeMultiMap<
|
|||
* @returns either a NODE object or undefined.
|
||||
*/
|
||||
override keyValueOrEntryOrRawElementToNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>,
|
||||
keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R,
|
||||
value?: V,
|
||||
count = 1
|
||||
): NODE | undefined {
|
||||
if (keyOrNodeOrEntryOrRawElement === undefined || keyOrNodeOrEntryOrRawElement === null) return;
|
||||
if (keyOrNodeOrEntryOrRaw === undefined || keyOrNodeOrEntryOrRaw === null) return;
|
||||
|
||||
if (this.isNode(keyOrNodeOrEntryOrRawElement)) return keyOrNodeOrEntryOrRawElement;
|
||||
if (this.isNode(keyOrNodeOrEntryOrRaw)) return keyOrNodeOrEntryOrRaw;
|
||||
|
||||
if (this.isEntry(keyOrNodeOrEntryOrRawElement)) {
|
||||
const [key, entryValue] = keyOrNodeOrEntryOrRawElement;
|
||||
if (this.isEntry(keyOrNodeOrEntryOrRaw)) {
|
||||
const [key, entryValue] = keyOrNodeOrEntryOrRaw;
|
||||
if (key === undefined || key === null) return;
|
||||
if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count);
|
||||
}
|
||||
|
||||
if (this.toEntryFn) {
|
||||
const [key, entryValue] = this.toEntryFn(keyOrNodeOrEntryOrRawElement as R);
|
||||
if (this._toEntryFn) {
|
||||
const [key, entryValue] = this._toEntryFn(keyOrNodeOrEntryOrRaw as R);
|
||||
if (this.isKey(key)) return this.createNode(key, value ?? entryValue, 'BLACK', count);
|
||||
}
|
||||
|
||||
if (this.isKey(keyOrNodeOrEntryOrRawElement))
|
||||
return this.createNode(keyOrNodeOrEntryOrRawElement, value, 'BLACK', count);
|
||||
if (this.isKey(keyOrNodeOrEntryOrRaw)) return this.createNode(keyOrNodeOrEntryOrRaw, value, 'BLACK', count);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function checks if the input is an instance of the TreeMultiMapNode class.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The parameter
|
||||
* `keyOrNodeOrEntryOrRawElement` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRawElement` is
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The parameter
|
||||
* `keyOrNodeOrEntryOrRaw` can be of type `R` or `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value indicating whether the input parameter `keyOrNodeOrEntryOrRaw` is
|
||||
* an instance of the `TreeMultiMapNode` class.
|
||||
*/
|
||||
override isNode(
|
||||
keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>
|
||||
): keyOrNodeOrEntryOrRawElement is NODE {
|
||||
return keyOrNodeOrEntryOrRawElement instanceof TreeMultiMapNode;
|
||||
override isNode(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R): keyOrNodeOrEntryOrRaw is NODE {
|
||||
return keyOrNodeOrEntryOrRaw instanceof TreeMultiMapNode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,8 +203,8 @@ export class TreeMultiMap<
|
|||
*
|
||||
* The function overrides the add method of a class and adds a new node to a data structure, updating
|
||||
* the count and returning a boolean indicating success.
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} keyOrNodeOrEntryOrRawElement - The
|
||||
* `keyOrNodeOrEntryOrRawElement` parameter can accept one of the following types:
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R} keyOrNodeOrEntryOrRaw - The
|
||||
* `keyOrNodeOrEntryOrRaw` parameter can accept one of the following types:
|
||||
* @param {V} [value] - The `value` parameter represents the value associated with the key in the
|
||||
* data structure. It is an optional parameter, so it can be omitted if not needed.
|
||||
* @param [count=1] - The `count` parameter represents the number of times the key-value pair should
|
||||
|
@ -213,8 +213,8 @@ export class TreeMultiMap<
|
|||
* @returns The method is returning a boolean value. It returns true if the addition of the new node
|
||||
* was successful, and false otherwise.
|
||||
*/
|
||||
override add(keyOrNodeOrEntryOrRawElement: R | BTNKeyOrNodeOrEntry<K, V, NODE>, value?: V, count = 1): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRawElement, value, count);
|
||||
override add(keyOrNodeOrEntryOrRaw: BTNKeyOrNodeOrEntry<K, V, NODE> | R, value?: V, count = 1): boolean {
|
||||
const newNode = this.keyValueOrEntryOrRawElementToNode(keyOrNodeOrEntryOrRaw, value, count);
|
||||
const orgCount = newNode?.count || 0;
|
||||
const isSuccessAdded = super.add(newNode);
|
||||
|
||||
|
@ -230,30 +230,29 @@ export class TreeMultiMap<
|
|||
* Time Complexity: O(log n)
|
||||
* Space Complexity: O(1)
|
||||
*
|
||||
* The function `delete` is used to remove a node from a binary tree and fix the tree if necessary.
|
||||
* @param {ReturnType<C> | null | undefined} identifier - The `identifier` parameter is the value or
|
||||
* key that is used to identify the node that needs to be deleted from the binary tree. It can be of
|
||||
* any type that is returned by the callback function `C`. It can also be `null` or `undefined` if
|
||||
* the node to be deleted
|
||||
* @param {C} callback - The `callback` parameter is a function that is used to determine the
|
||||
* equality of nodes in the binary tree. It is optional and has a default value of
|
||||
* `this._DEFAULT_CALLBACK`. The `callback` function is used to compare nodes when searching for a
|
||||
* specific node or when performing other operations on the
|
||||
* @param [ignoreCount=false] - A boolean flag indicating whether to ignore the count of the node
|
||||
* being deleted. If set to true, the count of the node will not be taken into account when deleting
|
||||
* it. If set to false, the count of the node will be decremented by 1 before deleting it.
|
||||
* @returns an array of BinaryTreeDeleteResult<NODE> objects.
|
||||
* The function `delete` in TypeScript overrides the deletion operation in a binary tree data
|
||||
* structure, handling cases where nodes have children and maintaining balance in the tree.
|
||||
* @param {BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>} predicate - The `predicate`
|
||||
* parameter in the `delete` method is used to specify the condition or key based on which a node
|
||||
* should be deleted from the binary tree. It can be a key, a node, an entry, or a predicate
|
||||
* function.
|
||||
* @param [ignoreCount=false] - The `ignoreCount` parameter in the `override delete` method is a
|
||||
* boolean flag that determines whether to ignore the count of nodes when performing deletion. If
|
||||
* `ignoreCount` is set to `true`, the method will delete the node regardless of its count. If
|
||||
* `ignoreCount` is `false
|
||||
* @returns The `override delete` method returns an array of `BinaryTreeDeleteResult<NODE>` objects.
|
||||
*/
|
||||
override delete<C extends BTNCallback<NODE>>(
|
||||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
override delete(
|
||||
predicate: BTNKeyOrNodeOrEntry<K, V, NODE> | R | BTNPredicate<NODE>,
|
||||
ignoreCount = false
|
||||
): BinaryTreeDeleteResult<NODE>[] {
|
||||
if (identifier === null) return [];
|
||||
const results: BinaryTreeDeleteResult<NODE>[] = [];
|
||||
callback = this._ensureCallback(identifier, callback);
|
||||
if (predicate === null) return [];
|
||||
|
||||
const nodeToDelete = this.isRealNode(identifier) ? identifier : this.getNode(identifier, callback);
|
||||
const results: BinaryTreeDeleteResult<NODE>[] = [];
|
||||
|
||||
let nodeToDelete: OptBSTN<NODE>;
|
||||
if (this._isPredicated(predicate)) nodeToDelete = this.getNode(predicate);
|
||||
else nodeToDelete = this.isRealNode(predicate) ? predicate : this.getNode(predicate);
|
||||
|
||||
if (!nodeToDelete) {
|
||||
return results;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { DijkstraResult, EntryCallback, VertexKey } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { TopologicalStatus, VertexKey } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { VertexKey } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type {
|
||||
|
@ -111,7 +111,7 @@ export class HashMap<K = any, V = any, R = [K, V]> extends IterableEntryBase<K,
|
|||
* @returns A boolean value indicating whether the size of the object is 0 or not.
|
||||
*/
|
||||
isEmpty(): boolean {
|
||||
return this.size === 0;
|
||||
return this._size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -626,7 +626,7 @@ export class FibonacciHeap<E> {
|
|||
* @returns The top element or undefined if the heap is empty.
|
||||
*/
|
||||
pop(): E | undefined {
|
||||
if (this.size === 0) return undefined;
|
||||
if (this._size === 0) return undefined;
|
||||
|
||||
const z = this.min!;
|
||||
if (z.child) {
|
||||
|
@ -770,7 +770,7 @@ export class FibonacciHeap<E> {
|
|||
* @protected
|
||||
*/
|
||||
protected _consolidate(): void {
|
||||
const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this.size);
|
||||
const A: (FibonacciHeapNode<E> | undefined)[] = new Array(this._size);
|
||||
const elements = this.consumeLinkedList(this.root);
|
||||
let x: FibonacciHeapNode<E> | undefined,
|
||||
y: FibonacciHeapNode<E> | undefined,
|
||||
|
@ -798,7 +798,7 @@ export class FibonacciHeap<E> {
|
|||
A[d] = x;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.size; i++) {
|
||||
for (let i = 0; i < this._size; i++) {
|
||||
if (A[i] && this.comparator(A[i]!.element, this.min!.element) <= 0) {
|
||||
this._min = A[i]!;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { DoublyLinkedListOptions, ElementCallback } from '../../types';
|
||||
|
@ -267,7 +267,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* or the linked list is empty, it will return undefined.
|
||||
*/
|
||||
at(index: number): E | undefined {
|
||||
if (index < 0 || index >= this.size) return undefined;
|
||||
if (index < 0 || index >= this._size) return undefined;
|
||||
let current = this.head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current!.next;
|
||||
|
@ -287,7 +287,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* valid range of the linked list, otherwise it returns `undefined`.
|
||||
*/
|
||||
getNodeAt(index: number): DoublyLinkedListNode<E> | undefined {
|
||||
if (index < 0 || index >= this.size) return undefined;
|
||||
if (index < 0 || index >= this._size) return undefined;
|
||||
let current = this.head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current!.next;
|
||||
|
@ -331,12 +331,12 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* if the index is out of bounds.
|
||||
*/
|
||||
addAt(index: number, value: E): boolean {
|
||||
if (index < 0 || index > this.size) return false;
|
||||
if (index < 0 || index > this._size) return false;
|
||||
if (index === 0) {
|
||||
this.unshift(value);
|
||||
return true;
|
||||
}
|
||||
if (index === this.size) {
|
||||
if (index === this._size) {
|
||||
this.push(value);
|
||||
return true;
|
||||
}
|
||||
|
@ -442,12 +442,12 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* bounds.
|
||||
*/
|
||||
deleteAt(index: number): boolean {
|
||||
if (index < 0 || index >= this.size) return false;
|
||||
if (index < 0 || index >= this._size) return false;
|
||||
if (index === 0) {
|
||||
this.shift();
|
||||
return true;
|
||||
}
|
||||
if (index === this.size - 1) {
|
||||
if (index === this._size - 1) {
|
||||
this.pop();
|
||||
return true;
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ export class DoublyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* @returns A boolean value is being returned.
|
||||
*/
|
||||
isEmpty(): boolean {
|
||||
return this.size === 0;
|
||||
return this._size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { ElementCallback, SinglyLinkedListOptions } from '../../types';
|
||||
|
@ -237,7 +237,7 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* `undefined` if the index is out of bounds.
|
||||
*/
|
||||
at(index: number): E | undefined {
|
||||
if (index < 0 || index >= this.size) return undefined;
|
||||
if (index < 0 || index >= this._size) return undefined;
|
||||
let current = this.head;
|
||||
for (let i = 0; i < index; i++) {
|
||||
current = current!.next;
|
||||
|
@ -274,12 +274,12 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* bounds.
|
||||
*/
|
||||
deleteAt(index: number): boolean {
|
||||
if (index < 0 || index >= this.size) return false;
|
||||
if (index < 0 || index >= this._size) return false;
|
||||
if (index === 0) {
|
||||
this.shift();
|
||||
return true;
|
||||
}
|
||||
if (index === this.size - 1) {
|
||||
if (index === this._size - 1) {
|
||||
this.pop();
|
||||
return true;
|
||||
}
|
||||
|
@ -348,12 +348,12 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* if the index is out of bounds.
|
||||
*/
|
||||
addAt(index: number, value: E): boolean {
|
||||
if (index < 0 || index > this.size) return false;
|
||||
if (index < 0 || index > this._size) return false;
|
||||
if (index === 0) {
|
||||
this.unshift(value);
|
||||
return true;
|
||||
}
|
||||
if (index === this.size) {
|
||||
if (index === this._size) {
|
||||
this.push(value);
|
||||
return true;
|
||||
}
|
||||
|
@ -372,7 +372,7 @@ export class SinglyLinkedList<E = any, R = any> extends IterableElementBase<E, R
|
|||
* @returns A boolean value indicating whether the length of the object is equal to 0.
|
||||
*/
|
||||
isEmpty(): boolean {
|
||||
return this.size === 0;
|
||||
return this._size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { SkipLinkedListOptions } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { MatrixOptions } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { Direction, NavigatorParams, Turning } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { DequeOptions, ElementCallback, IterableWithSizeOrLength } from '../../types';
|
||||
|
@ -163,7 +163,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The first element of the collection, of type E, is being returned.
|
||||
*/
|
||||
get first(): E | undefined {
|
||||
if (this.size === 0) return;
|
||||
if (this._size === 0) return;
|
||||
return this._buckets[this._bucketFirst][this._firstInBucket];
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @return The last element in the array
|
||||
*/
|
||||
get last(): E | undefined {
|
||||
if (this.size === 0) return;
|
||||
if (this._size === 0) return;
|
||||
return this._buckets[this._bucketLast][this._lastInBucket];
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The size of the data structure after the element has been pushed.
|
||||
*/
|
||||
push(element: E): boolean {
|
||||
if (this.size) {
|
||||
if (this._size) {
|
||||
if (this._lastInBucket < this._bucketSize - 1) {
|
||||
this._lastInBucket += 1;
|
||||
} else if (this._bucketLast < this._bucketCount - 1) {
|
||||
|
@ -213,9 +213,9 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The element that was removed from the data structure is being returned.
|
||||
*/
|
||||
pop(): E | undefined {
|
||||
if (this.size === 0) return;
|
||||
if (this._size === 0) return;
|
||||
const element = this._buckets[this._bucketLast][this._lastInBucket];
|
||||
if (this.size !== 1) {
|
||||
if (this._size !== 1) {
|
||||
if (this._lastInBucket > 0) {
|
||||
this._lastInBucket -= 1;
|
||||
} else if (this._bucketLast > 0) {
|
||||
|
@ -241,7 +241,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The size of the data structure after the element has been added.
|
||||
*/
|
||||
unshift(element: E): boolean {
|
||||
if (this.size) {
|
||||
if (this._size) {
|
||||
if (this._firstInBucket > 0) {
|
||||
this._firstInBucket -= 1;
|
||||
} else if (this._bucketFirst > 0) {
|
||||
|
@ -269,9 +269,9 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* returned.
|
||||
*/
|
||||
shift(): E | undefined {
|
||||
if (this.size === 0) return;
|
||||
if (this._size === 0) return;
|
||||
const element = this._buckets[this._bucketFirst][this._firstInBucket];
|
||||
if (this.size !== 1) {
|
||||
if (this._size !== 1) {
|
||||
if (this._firstInBucket < this._bucketSize - 1) {
|
||||
this._firstInBucket += 1;
|
||||
} else if (this._bucketFirst < this._bucketCount - 1) {
|
||||
|
@ -294,7 +294,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns A boolean value indicating whether the size of the object is 0 or not.
|
||||
*/
|
||||
isEmpty(): boolean {
|
||||
return this.size === 0;
|
||||
return this._size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -316,7 +316,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
*/
|
||||
*begin(): Generator<E> {
|
||||
let index = 0;
|
||||
while (index < this.size) {
|
||||
while (index < this._size) {
|
||||
yield this.at(index);
|
||||
index++;
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* the last element.
|
||||
*/
|
||||
*reverseBegin(): Generator<E> {
|
||||
let index = this.size - 1;
|
||||
let index = this._size - 1;
|
||||
while (index >= 0) {
|
||||
yield this.at(index);
|
||||
index--;
|
||||
|
@ -345,7 +345,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The element at the specified position in the data structure is being returned.
|
||||
*/
|
||||
at(pos: number): E {
|
||||
rangeCheck(pos, 0, this.size - 1);
|
||||
rangeCheck(pos, 0, this._size - 1);
|
||||
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
|
||||
return this._buckets[bucketIndex][indexInBucket]!;
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* position in the data structure.
|
||||
*/
|
||||
setAt(pos: number, element: E): boolean {
|
||||
rangeCheck(pos, 0, this.size - 1);
|
||||
rangeCheck(pos, 0, this._size - 1);
|
||||
const { bucketIndex, indexInBucket } = this._getBucketAndPosition(pos);
|
||||
this._buckets[bucketIndex][indexInBucket] = element;
|
||||
return true;
|
||||
|
@ -383,15 +383,15 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The size of the array after the insertion is being returned.
|
||||
*/
|
||||
addAt(pos: number, element: E, num = 1): boolean {
|
||||
const length = this.size;
|
||||
const length = this._size;
|
||||
rangeCheck(pos, 0, length);
|
||||
if (pos === 0) {
|
||||
while (num--) this.unshift(element);
|
||||
} else if (pos === this.size) {
|
||||
} else if (pos === this._size) {
|
||||
while (num--) this.push(element);
|
||||
} else {
|
||||
const arr: E[] = [];
|
||||
for (let i = pos; i < this.size; ++i) {
|
||||
for (let i = pos; i < this._size; ++i) {
|
||||
arr.push(this.at(i));
|
||||
}
|
||||
this.cut(pos - 1, true);
|
||||
|
@ -462,7 +462,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
} else {
|
||||
const newDeque = new Deque<E>([], { bucketSize: this._bucketSize });
|
||||
if (pos < 0) pos = 0;
|
||||
for (let i = pos; i < this.size; i++) {
|
||||
for (let i = pos; i < this._size; i++) {
|
||||
newDeque.push(this.at(i));
|
||||
}
|
||||
|
||||
|
@ -482,11 +482,11 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The size of the data structure after the deletion operation is performed.
|
||||
*/
|
||||
deleteAt(pos: number): boolean {
|
||||
rangeCheck(pos, 0, this.size - 1);
|
||||
rangeCheck(pos, 0, this._size - 1);
|
||||
if (pos === 0) this.shift();
|
||||
else if (pos === this.size - 1) this.pop();
|
||||
else if (pos === this._size - 1) this.pop();
|
||||
else {
|
||||
const length = this.size - 1;
|
||||
const length = this._size - 1;
|
||||
let { bucketIndex: curBucket, indexInBucket: curPointer } = this._getBucketAndPosition(pos);
|
||||
for (let i = pos; i < length; ++i) {
|
||||
const { bucketIndex: nextBucket, indexInBucket: nextPointer } = this._getBucketAndPosition(pos + 1);
|
||||
|
@ -510,7 +510,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The size of the data structure after the element has been deleted.
|
||||
*/
|
||||
delete(element: E): boolean {
|
||||
const size = this.size;
|
||||
const size = this._size;
|
||||
if (size === 0) return false;
|
||||
let i = 0;
|
||||
let index = 0;
|
||||
|
@ -556,12 +556,12 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* @returns The size of the modified array is being returned.
|
||||
*/
|
||||
unique(): this {
|
||||
if (this.size <= 1) {
|
||||
if (this._size <= 1) {
|
||||
return this;
|
||||
}
|
||||
let index = 1;
|
||||
let prev = this.at(0);
|
||||
for (let i = 1; i < this.size; ++i) {
|
||||
for (let i = 1; i < this._size; ++i) {
|
||||
const cur = this.at(i);
|
||||
if (cur !== prev) {
|
||||
prev = cur;
|
||||
|
@ -584,11 +584,11 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
*/
|
||||
sort(comparator?: (x: E, y: E) => number): this {
|
||||
const arr: E[] = [];
|
||||
for (let i = 0; i < this.size; ++i) {
|
||||
for (let i = 0; i < this._size; ++i) {
|
||||
arr.push(this.at(i));
|
||||
}
|
||||
arr.sort(comparator);
|
||||
for (let i = 0; i < this.size; ++i) {
|
||||
for (let i = 0; i < this._size; ++i) {
|
||||
this.setAt(i, arr[i]);
|
||||
}
|
||||
return this;
|
||||
|
@ -601,10 +601,10 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* The `shrinkToFit` function reorganizes the elements in an array-like data structure to minimize
|
||||
* memory usage.
|
||||
* @returns Nothing is being returned. The function is using the `return` statement to exit early if
|
||||
* `this.size` is 0, but it does not return any value.
|
||||
* `this._size` is 0, but it does not return any value.
|
||||
*/
|
||||
shrinkToFit(): void {
|
||||
if (this.size === 0) return;
|
||||
if (this._size === 0) return;
|
||||
const newBuckets = [];
|
||||
if (this._bucketFirst === this._bucketLast) return;
|
||||
else if (this._bucketFirst < this._bucketLast) {
|
||||
|
@ -636,7 +636,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* in the data structure. If the element is not found, it returns -1.
|
||||
*/
|
||||
indexOf(element: E): number {
|
||||
for (let i = 0; i < this.size; ++i) {
|
||||
for (let i = 0; i < this._size; ++i) {
|
||||
if (this.at(i) === element) {
|
||||
return i;
|
||||
}
|
||||
|
@ -736,7 +736,7 @@ export class Deque<E = any, R = any> extends IterableElementBase<E, R, Deque<E,
|
|||
* object to be iterated over using a for...of loop.
|
||||
*/
|
||||
protected *_getIterator(): IterableIterator<E> {
|
||||
for (let i = 0; i < this.size; ++i) {
|
||||
for (let i = 0; i < this._size; ++i) {
|
||||
yield this.at(i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* @license MIT
|
||||
* @copyright Tyler Zeng <zrwusa@gmail.com>
|
||||
* @copyright Pablo Zeng <zrwusa@gmail.com>
|
||||
* @class
|
||||
*/
|
||||
import type { ElementCallback, QueueOptions } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { ElementCallback, StackOptions } from '../../types';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**
|
||||
* data-structure-typed
|
||||
*
|
||||
* @author Tyler Zeng
|
||||
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
|
||||
* @author Pablo Zeng
|
||||
* @copyright Copyright (c) 2022 Pablo Zeng <zrwusa@gmail.com>
|
||||
* @license MIT License
|
||||
*/
|
||||
import type { ElementCallback, TrieOptions } from '../../types';
|
||||
|
@ -202,7 +202,7 @@ export class Trie<R = any> extends IterableElementBase<string, R, Trie<R>> {
|
|||
* @return True if the size of the queue is 0
|
||||
*/
|
||||
isEmpty(): boolean {
|
||||
return this.size === 0;
|
||||
return this._size === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,3 +2,4 @@ export * from './data-structures';
|
|||
export * from './utils';
|
||||
export * from './interfaces';
|
||||
export * from './types';
|
||||
export * from './constants';
|
||||
|
|
|
@ -5,7 +5,8 @@ import type {
|
|||
BinaryTreeNodeNested,
|
||||
BinaryTreeOptions,
|
||||
BTNCallback,
|
||||
BTNKeyOrNodeOrEntry
|
||||
BTNKeyOrNodeOrEntry,
|
||||
BTNPredicate
|
||||
} from '../types';
|
||||
|
||||
export interface IBinaryTree<
|
||||
|
@ -23,5 +24,5 @@ export interface IBinaryTree<
|
|||
|
||||
addMany(nodes: Iterable<BTNKeyOrNodeOrEntry<K, V, NODE>>, values?: Iterable<V | undefined>): boolean[];
|
||||
|
||||
delete<C extends BTNCallback<NODE>>(identifier: ReturnType<C> | null, callback: C): BinaryTreeDeleteResult<NODE>[];
|
||||
delete(predicate: R | BTNKeyOrNodeOrEntry<K, V, NODE> | BTNPredicate<NODE>): BinaryTreeDeleteResult<NODE>[];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { BinaryTree, BinaryTreeNode } from '../../../data-structures';
|
||||
import { IterationType, OptValue } from '../../common';
|
||||
import {DFSOperation} from "bst-typed";
|
||||
|
||||
export type BinaryTreeNodeNested<K, V> = BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, BinaryTreeNode<K, V, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
@ -30,9 +31,6 @@ export type BinaryTreeDeleteResult<NODE> = { deleted: OptBTNOrNull<NODE>; needBa
|
|||
|
||||
export type BTNCallback<NODE, D = any> = (node: NODE) => D;
|
||||
|
||||
export enum DFSOperation {
|
||||
VISIT = 0,
|
||||
PROCESS = 1,
|
||||
}
|
||||
export type BTNPredicate<NODE> = (node: NODE) => boolean;
|
||||
|
||||
export type DFSStackItem<NODE> = { opt: DFSOperation; node: OptBTNOrNull<NODE> }
|
||||
export type DFSStackItem<NODE> = { opt: DFSOperation; node: OptBTNOrNull<NODE> }
|
||||
|
|
|
@ -75,13 +75,13 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
const nodeId10 = treeMultimap.getNode(10);
|
||||
expect(nodeId10?.key).toBe(10);
|
||||
|
||||
const nodeVal9 = treeMultimap.getNode(9, node => node.value);
|
||||
const nodeVal9 = treeMultimap.getNode(node => node.value === 9);
|
||||
expect(nodeVal9?.key).toBe(9);
|
||||
|
||||
const nodesByCount1 = treeMultimap.getNodes(1, node => node.count);
|
||||
const nodesByCount1 = treeMultimap.getNodes(node => node.count === 1);
|
||||
expect(nodesByCount1.length).toBe(14);
|
||||
|
||||
const nodesByCount2 = treeMultimap.getNodes(2, node => node.count);
|
||||
const nodesByCount2 = treeMultimap.getNodes(node => node.count === 2);
|
||||
expect(nodesByCount2.length).toBe(2);
|
||||
const leftMost = treeMultimap.getLeftMost();
|
||||
expect(leftMost).toBe(1);
|
||||
|
@ -123,7 +123,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
||||
const removed11 = treeMultimap.delete(11, undefined, true);
|
||||
const removed11 = treeMultimap.delete(11, true);
|
||||
expect(removed11 instanceof Array);
|
||||
expect(removed11[0]);
|
||||
expect(removed11[0].deleted);
|
||||
|
@ -134,7 +134,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
|
||||
expect(treeMultimap.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = treeMultimap.delete(1, undefined, true);
|
||||
const removed1 = treeMultimap.delete(1, true);
|
||||
expect(removed1 instanceof Array);
|
||||
expect(removed1[0]);
|
||||
expect(removed1[0].deleted);
|
||||
|
@ -144,7 +144,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
|
||||
expect(treeMultimap.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = treeMultimap.delete(4, undefined, true);
|
||||
const removed4 = treeMultimap.delete(4, true);
|
||||
expect(removed4 instanceof Array);
|
||||
expect(removed4[0]);
|
||||
expect(removed4[0].deleted);
|
||||
|
@ -153,7 +153,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = treeMultimap.delete(10, undefined, true);
|
||||
const removed10 = treeMultimap.delete(10, true);
|
||||
expect(removed10 instanceof Array);
|
||||
expect(removed10[0]);
|
||||
expect(removed10[0].deleted);
|
||||
|
@ -162,7 +162,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed15 = treeMultimap.delete(15, undefined, true);
|
||||
const removed15 = treeMultimap.delete(15, true);
|
||||
expect(removed15 instanceof Array);
|
||||
expect(removed15[0]);
|
||||
expect(removed15[0].deleted);
|
||||
|
@ -171,7 +171,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = treeMultimap.delete(5, undefined, true);
|
||||
const removed5 = treeMultimap.delete(5, true);
|
||||
expect(removed5 instanceof Array);
|
||||
expect(removed5[0]);
|
||||
expect(removed5[0].deleted);
|
||||
|
@ -180,7 +180,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = treeMultimap.delete(13, undefined, true);
|
||||
const removed13 = treeMultimap.delete(13, true);
|
||||
expect(removed13 instanceof Array);
|
||||
expect(removed13[0]);
|
||||
expect(removed13[0].deleted);
|
||||
|
@ -188,7 +188,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = treeMultimap.delete(3, undefined, true);
|
||||
const removed3 = treeMultimap.delete(3, true);
|
||||
expect(removed3 instanceof Array);
|
||||
expect(removed3[0]);
|
||||
expect(removed3[0].deleted);
|
||||
|
@ -196,7 +196,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = treeMultimap.delete(8, undefined, true);
|
||||
const removed8 = treeMultimap.delete(8, true);
|
||||
expect(removed8 instanceof Array);
|
||||
expect(removed8[0]);
|
||||
expect(removed8[0].deleted);
|
||||
|
@ -204,17 +204,17 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = treeMultimap.delete(6, undefined, true);
|
||||
const removed6 = treeMultimap.delete(6, true);
|
||||
expect(removed6 instanceof Array);
|
||||
expect(removed6[0]);
|
||||
expect(removed6[0].deleted);
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6);
|
||||
expect(treeMultimap.delete(6, undefined, true).length).toBe(0);
|
||||
expect(treeMultimap.delete(6, true).length).toBe(0);
|
||||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(treeMultimap.getHeight()).toBe(2);
|
||||
|
||||
const removed7 = treeMultimap.delete(7, undefined, true);
|
||||
const removed7 = treeMultimap.delete(7, true);
|
||||
expect(removed7 instanceof Array);
|
||||
expect(removed7[0]);
|
||||
expect(removed7[0].deleted);
|
||||
|
@ -222,7 +222,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(2);
|
||||
|
||||
const removed9 = treeMultimap.delete(9, undefined, true);
|
||||
const removed9 = treeMultimap.delete(9, true);
|
||||
expect(removed9 instanceof Array);
|
||||
expect(removed9[0]);
|
||||
expect(removed9[0].deleted);
|
||||
|
@ -230,7 +230,7 @@ describe('AVLTreeMultiMap operations test1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(2);
|
||||
|
||||
const removed14 = treeMultimap.delete(14, undefined, true);
|
||||
const removed14 = treeMultimap.delete(14, true);
|
||||
expect(removed14 instanceof Array);
|
||||
expect(removed14[0]);
|
||||
expect(removed14[0].deleted);
|
||||
|
@ -331,13 +331,13 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
const nodeId10 = treeMultimap.getNode(10);
|
||||
expect(nodeId10?.key).toBe(10);
|
||||
|
||||
const nodeVal9 = treeMultimap.getNode(9, node => node.value);
|
||||
const nodeVal9 = treeMultimap.getNode(node => node.value === 9);
|
||||
expect(nodeVal9?.key).toBe(9);
|
||||
|
||||
const nodesByCount1 = treeMultimap.getNodes(1, node => node.count);
|
||||
const nodesByCount1 = treeMultimap.getNodes(node => node.count === 1);
|
||||
expect(nodesByCount1.length).toBe(14);
|
||||
|
||||
const nodesByCount2 = treeMultimap.getNodes(2, node => node.count);
|
||||
const nodesByCount2 = treeMultimap.getNodes(node => node.count === 2);
|
||||
expect(nodesByCount2.length).toBe(2);
|
||||
const leftMost = treeMultimap.getLeftMost();
|
||||
expect(leftMost).toBe(1);
|
||||
|
@ -379,7 +379,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(bfsNodesAfterBalanced[0].key).toBe(8);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
||||
const removed11 = treeMultimap.delete(11, undefined, true);
|
||||
const removed11 = treeMultimap.delete(11, true);
|
||||
expect(removed11 instanceof Array);
|
||||
expect(removed11[0]);
|
||||
expect(removed11[0].deleted);
|
||||
|
@ -390,7 +390,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
|
||||
expect(treeMultimap.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = treeMultimap.delete(1, undefined, true);
|
||||
const removed1 = treeMultimap.delete(1, true);
|
||||
expect(removed1 instanceof Array);
|
||||
expect(removed1[0]);
|
||||
expect(removed1[0].deleted);
|
||||
|
@ -400,7 +400,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
|
||||
expect(treeMultimap.getHeight()).toBe(4);
|
||||
|
||||
const removed4 = treeMultimap.delete(4, undefined, true);
|
||||
const removed4 = treeMultimap.delete(4, true);
|
||||
expect(removed4 instanceof Array);
|
||||
expect(removed4[0]);
|
||||
expect(removed4[0].deleted);
|
||||
|
@ -409,7 +409,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(4);
|
||||
|
||||
const removed10 = treeMultimap.delete(10, undefined, true);
|
||||
const removed10 = treeMultimap.delete(10, true);
|
||||
expect(removed10 instanceof Array);
|
||||
expect(removed10[0]);
|
||||
expect(removed10[0].deleted);
|
||||
|
@ -418,7 +418,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed15 = treeMultimap.delete(15, undefined, true);
|
||||
const removed15 = treeMultimap.delete(15, true);
|
||||
expect(removed15 instanceof Array);
|
||||
expect(removed15[0]);
|
||||
expect(removed15[0].deleted);
|
||||
|
@ -427,7 +427,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = treeMultimap.delete(5, undefined, true);
|
||||
const removed5 = treeMultimap.delete(5, true);
|
||||
expect(removed5 instanceof Array);
|
||||
expect(removed5[0]);
|
||||
expect(removed5[0].deleted);
|
||||
|
@ -436,7 +436,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = treeMultimap.delete(13, undefined, true);
|
||||
const removed13 = treeMultimap.delete(13, true);
|
||||
expect(removed13 instanceof Array);
|
||||
expect(removed13[0]);
|
||||
expect(removed13[0].deleted);
|
||||
|
@ -444,7 +444,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = treeMultimap.delete(3, undefined, true);
|
||||
const removed3 = treeMultimap.delete(3, true);
|
||||
expect(removed3 instanceof Array);
|
||||
expect(removed3[0]);
|
||||
expect(removed3[0].deleted);
|
||||
|
@ -452,7 +452,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = treeMultimap.delete(8, undefined, true);
|
||||
const removed8 = treeMultimap.delete(8, true);
|
||||
expect(removed8 instanceof Array);
|
||||
expect(removed8[0]);
|
||||
expect(removed8[0].deleted);
|
||||
|
@ -460,17 +460,17 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = treeMultimap.delete(6, undefined, true);
|
||||
const removed6 = treeMultimap.delete(6, true);
|
||||
expect(removed6 instanceof Array);
|
||||
expect(removed6[0]);
|
||||
expect(removed6[0].deleted);
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6);
|
||||
expect(treeMultimap.delete(6, undefined, true).length).toBe(0);
|
||||
expect(treeMultimap.delete(6, true).length).toBe(0);
|
||||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
|
||||
expect(treeMultimap.getHeight()).toBe(2);
|
||||
|
||||
const removed7 = treeMultimap.delete(7, undefined, true);
|
||||
const removed7 = treeMultimap.delete(7, true);
|
||||
expect(removed7 instanceof Array);
|
||||
expect(removed7[0]);
|
||||
expect(removed7[0].deleted);
|
||||
|
@ -478,7 +478,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(2);
|
||||
|
||||
const removed9 = treeMultimap.delete(9, undefined, true);
|
||||
const removed9 = treeMultimap.delete(9, true);
|
||||
expect(removed9 instanceof Array);
|
||||
expect(removed9[0]);
|
||||
expect(removed9[0].deleted);
|
||||
|
@ -486,7 +486,7 @@ describe('AVLTreeMultiMap operations test recursively1', () => {
|
|||
expect(treeMultimap.isAVLBalanced()).toBe(true);
|
||||
expect(treeMultimap.getHeight()).toBe(2);
|
||||
|
||||
const removed14 = treeMultimap.delete(14, undefined, true);
|
||||
const removed14 = treeMultimap.delete(14, true);
|
||||
expect(removed14 instanceof Array);
|
||||
expect(removed14[0]);
|
||||
expect(removed14[0].deleted);
|
||||
|
|
|
@ -169,8 +169,8 @@ describe('BinaryTree', () => {
|
|||
expect(tree.has(4)).toBe(false);
|
||||
const node4 = tree.getNode(4);
|
||||
expect(tree.has(node4)).toBe(false);
|
||||
expect(tree.has(node4, node => node)).toBe(false);
|
||||
expect(tree.has('3', node => node.value?.toString())).toBe(true);
|
||||
expect(tree.has(node => node === node4)).toBe(false);
|
||||
expect(tree.has(node => node.value?.toString() === '3')).toBe(true);
|
||||
});
|
||||
|
||||
it('should the clone method work fine', () => {
|
||||
|
@ -323,9 +323,9 @@ describe('BinaryTree', () => {
|
|||
|
||||
expect(tree.isBST(tree.getNode(4), 'RECURSIVE')).toBe(true);
|
||||
expect(tree.isBST(tree.getNode(4), 'ITERATIVE')).toBe(true);
|
||||
expect(tree.getNodes(2, undefined, false, null)).toEqual([]);
|
||||
expect(tree.getNodes(2, false, null)).toEqual([]);
|
||||
expect(tree.getNodes(undefined)).toEqual([]);
|
||||
expect(tree.getNodes(tree.getNodeByKey(2), undefined, false, tree.root)).toEqual([tree.getNodeByKey(2)]);
|
||||
expect(tree.getNodes(tree.getNodeByKey(2), false, tree.root)).toEqual([tree.getNodeByKey(2)]);
|
||||
});
|
||||
|
||||
describe('should isKey', () => {
|
||||
|
@ -1130,17 +1130,17 @@ describe('BinaryTree', () => {
|
|||
tree.add([2, 'B']);
|
||||
tree.add([null, 'null']);
|
||||
|
||||
const nodes = tree.getNodes('B', node => node.value);
|
||||
const nodes = tree.getNodes(node => node.value === 'B');
|
||||
|
||||
expect(nodes.length).toBe(1);
|
||||
expect(nodes[0].key).toBe(2);
|
||||
|
||||
const nodesRec = tree.getNodes('B', node => node.value, false, tree.root, 'RECURSIVE');
|
||||
const nodesRec = tree.getNodes(node => node.value === 'B', false, tree.root, 'RECURSIVE');
|
||||
|
||||
expect(nodesRec.length).toBe(1);
|
||||
expect(nodesRec[0].key).toBe(2);
|
||||
|
||||
const nodesItr = tree.getNodes('B', node => node.value, false, tree.root, 'ITERATIVE');
|
||||
const nodesItr = tree.getNodes(node => node.value === 'B', false, tree.root, 'ITERATIVE');
|
||||
|
||||
expect(nodesItr.length).toBe(1);
|
||||
expect(nodesItr[0].key).toBe(2);
|
||||
|
|
|
@ -69,7 +69,7 @@ describe('BST operations test', () => {
|
|||
const nodeId10 = bst.getNode(10);
|
||||
expect(nodeId10?.key).toBe(10);
|
||||
|
||||
const nodeVal9 = bst.getNode(9, node => node.value);
|
||||
const nodeVal9 = bst.getNode(node => node.value === 9);
|
||||
expect(nodeVal9?.key).toBe(9);
|
||||
|
||||
const leftMost = bst.getLeftMost();
|
||||
|
@ -81,7 +81,7 @@ describe('BST operations test', () => {
|
|||
const minNodeBySpecificNode = node15 && bst.getLeftMost(node => node, node15);
|
||||
expect(minNodeBySpecificNode?.key).toBe(12);
|
||||
|
||||
const nodes = bst.getNodes(15, node => node.value);
|
||||
const nodes = bst.getNodes(node => node.value === 15);
|
||||
expect(nodes.map(node => node.key)).toEqual([15]);
|
||||
|
||||
let subTreeSum = 0;
|
||||
|
@ -490,7 +490,7 @@ describe('BST operations test recursively', () => {
|
|||
expect(bst.get(10)).toBe(undefined);
|
||||
expect(nodeId10?.key).toBe(10);
|
||||
|
||||
const nodeVal9 = bst.getNode(9, node => node.value);
|
||||
const nodeVal9 = bst.getNode(node => node.value === 9);
|
||||
expect(nodeVal9?.key).toBe(undefined);
|
||||
|
||||
const leftMost = bst.getLeftMost();
|
||||
|
|
|
@ -87,7 +87,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
tmm.delete(11);
|
||||
expect(tmm.count).toBe(17);
|
||||
expect(tmm.getComputedCount()).toBe(17);
|
||||
tmm.delete(3, undefined, true);
|
||||
tmm.delete(3, true);
|
||||
expect(tmm.count).toBe(15);
|
||||
expect(tmm.getComputedCount()).toBe(15);
|
||||
});
|
||||
|
@ -133,13 +133,13 @@ describe('TreeMultiMap operations test1', () => {
|
|||
const nodeId10 = tmm.getNode(10);
|
||||
expect(nodeId10?.key).toBe(10);
|
||||
|
||||
const nodeVal9 = tmm.getNode(9, node => node.value);
|
||||
const nodeVal9 = tmm.getNode(node => node.value === 9);
|
||||
expect(nodeVal9?.key).toBe(9);
|
||||
|
||||
const nodesByCount1 = tmm.getNodes(1, node => node.count);
|
||||
const nodesByCount1 = tmm.getNodes(node => node.count === 1);
|
||||
expect(nodesByCount1.length).toBe(14);
|
||||
|
||||
const nodesByCount2 = tmm.getNodes(2, node => node.count);
|
||||
const nodesByCount2 = tmm.getNodes(node => node.count === 2);
|
||||
expect(nodesByCount2.length).toBe(2);
|
||||
const leftMost = tmm.getLeftMost();
|
||||
expect(leftMost).toBe(1);
|
||||
|
@ -180,7 +180,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(bfsNodesAfterBalanced[0].key).toBe(6);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
||||
const removed11 = tmm.delete(11, undefined, true);
|
||||
const removed11 = tmm.delete(11, true);
|
||||
expect(removed11 instanceof Array);
|
||||
expect(removed11[0]);
|
||||
expect(removed11[0].deleted);
|
||||
|
@ -191,7 +191,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
|
||||
expect(tmm.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = tmm.delete(1, undefined, true);
|
||||
const removed1 = tmm.delete(1, true);
|
||||
expect(removed1 instanceof Array);
|
||||
expect(removed1[0]);
|
||||
expect(removed1[0].deleted);
|
||||
|
@ -201,7 +201,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
|
||||
expect(tmm.getHeight()).toBe(5);
|
||||
|
||||
const removed4 = tmm.delete(4, undefined, true);
|
||||
const removed4 = tmm.delete(4, true);
|
||||
expect(removed4 instanceof Array);
|
||||
expect(removed4[0]);
|
||||
expect(removed4[0].deleted);
|
||||
|
@ -210,7 +210,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(5);
|
||||
|
||||
const removed10 = tmm.delete(10, undefined, true);
|
||||
const removed10 = tmm.delete(10, true);
|
||||
expect(removed10 instanceof Array);
|
||||
expect(removed10[0]);
|
||||
expect(removed10[0].deleted);
|
||||
|
@ -219,7 +219,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
|
||||
expect(tmm.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = tmm.delete(15, undefined, true);
|
||||
const removed15 = tmm.delete(15, true);
|
||||
expect(removed15 instanceof Array);
|
||||
expect(removed15[0]);
|
||||
expect(removed15[0].deleted);
|
||||
|
@ -228,7 +228,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = tmm.delete(5, undefined, true);
|
||||
const removed5 = tmm.delete(5, true);
|
||||
expect(removed5 instanceof Array);
|
||||
expect(removed5[0]);
|
||||
expect(removed5[0].deleted);
|
||||
|
@ -237,7 +237,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(true);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = tmm.delete(13, undefined, true);
|
||||
const removed13 = tmm.delete(13, true);
|
||||
expect(removed13 instanceof Array);
|
||||
expect(removed13[0]);
|
||||
expect(removed13[0].deleted);
|
||||
|
@ -245,7 +245,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(true);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = tmm.delete(3, undefined, true);
|
||||
const removed3 = tmm.delete(3, true);
|
||||
expect(removed3 instanceof Array);
|
||||
expect(removed3[0]);
|
||||
expect(removed3[0].deleted);
|
||||
|
@ -253,7 +253,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = tmm.delete(8, undefined, true);
|
||||
const removed8 = tmm.delete(8, true);
|
||||
expect(removed8 instanceof Array);
|
||||
expect(removed8[0]);
|
||||
expect(removed8[0].deleted);
|
||||
|
@ -261,17 +261,17 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = tmm.delete(6, undefined, true);
|
||||
const removed6 = tmm.delete(6, true);
|
||||
expect(removed6 instanceof Array);
|
||||
expect(removed6[0]);
|
||||
expect(removed6[0].deleted);
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6);
|
||||
expect(tmm.delete(6, undefined, true).length).toBe(0);
|
||||
expect(tmm.delete(6, true).length).toBe(0);
|
||||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = tmm.delete(7, undefined, true);
|
||||
const removed7 = tmm.delete(7, true);
|
||||
expect(removed7 instanceof Array);
|
||||
expect(removed7[0]);
|
||||
expect(removed7[0].deleted);
|
||||
|
@ -279,7 +279,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = tmm.delete(9, undefined, true);
|
||||
const removed9 = tmm.delete(9, true);
|
||||
expect(removed9 instanceof Array);
|
||||
expect(removed9[0]);
|
||||
expect(removed9[0].deleted);
|
||||
|
@ -287,7 +287,7 @@ describe('TreeMultiMap operations test1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(true);
|
||||
expect(tmm.getHeight()).toBe(2);
|
||||
|
||||
const removed14 = tmm.delete(14, undefined, true);
|
||||
const removed14 = tmm.delete(14, true);
|
||||
expect(removed14 instanceof Array);
|
||||
expect(removed14[0]);
|
||||
expect(removed14[0].deleted);
|
||||
|
@ -391,13 +391,13 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
const nodeId10 = tmm.getNode(10);
|
||||
expect(nodeId10?.key).toBe(10);
|
||||
|
||||
const nodeVal9 = tmm.getNode(9, node => node.value);
|
||||
const nodeVal9 = tmm.getNode(node => node.value === 9);
|
||||
expect(nodeVal9?.key).toBe(9);
|
||||
|
||||
const nodesByCount1 = tmm.getNodes(1, node => node.count);
|
||||
const nodesByCount1 = tmm.getNodes(node => node.count === 1);
|
||||
expect(nodesByCount1.length).toBe(14);
|
||||
|
||||
const nodesByCount2 = tmm.getNodes(2, node => node.count);
|
||||
const nodesByCount2 = tmm.getNodes(node => node.count === 2);
|
||||
expect(nodesByCount2.length).toBe(2);
|
||||
const leftMost = tmm.getLeftMost();
|
||||
expect(leftMost).toBe(1);
|
||||
|
@ -447,7 +447,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(bfsNodesAfterBalanced[0].key).toBe(6);
|
||||
expect(bfsNodesAfterBalanced[bfsNodesAfterBalanced.length - 1].key).toBe(16);
|
||||
|
||||
const removed11 = tmm.delete(11, undefined, true);
|
||||
const removed11 = tmm.delete(11, true);
|
||||
expect(removed11 instanceof Array);
|
||||
expect(removed11[0]);
|
||||
expect(removed11[0].deleted);
|
||||
|
@ -458,7 +458,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
|
||||
expect(tmm.getHeight(15)).toBe(1);
|
||||
|
||||
const removed1 = tmm.delete(1, undefined, true);
|
||||
const removed1 = tmm.delete(1, true);
|
||||
expect(removed1 instanceof Array);
|
||||
expect(removed1[0]);
|
||||
expect(removed1[0].deleted);
|
||||
|
@ -468,7 +468,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
|
||||
expect(tmm.getHeight()).toBe(5);
|
||||
|
||||
const removed4 = tmm.delete(4, undefined, true);
|
||||
const removed4 = tmm.delete(4, true);
|
||||
expect(removed4 instanceof Array);
|
||||
expect(removed4[0]);
|
||||
expect(removed4[0].deleted);
|
||||
|
@ -477,7 +477,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(5);
|
||||
|
||||
const removed10 = tmm.delete(10, undefined, true);
|
||||
const removed10 = tmm.delete(10, true);
|
||||
expect(removed10 instanceof Array);
|
||||
expect(removed10[0]);
|
||||
expect(removed10[0].deleted);
|
||||
|
@ -486,7 +486,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
|
||||
expect(tmm.getHeight()).toBe(4);
|
||||
|
||||
const removed15 = tmm.delete(15, undefined, true);
|
||||
const removed15 = tmm.delete(15, true);
|
||||
expect(removed15 instanceof Array);
|
||||
expect(removed15[0]);
|
||||
expect(removed15[0].deleted);
|
||||
|
@ -495,7 +495,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed5 = tmm.delete(5, undefined, true);
|
||||
const removed5 = tmm.delete(5, true);
|
||||
expect(removed5 instanceof Array);
|
||||
expect(removed5[0]);
|
||||
expect(removed5[0].deleted);
|
||||
|
@ -504,7 +504,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(true);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed13 = tmm.delete(13, undefined, true);
|
||||
const removed13 = tmm.delete(13, true);
|
||||
expect(removed13 instanceof Array);
|
||||
expect(removed13[0]);
|
||||
expect(removed13[0].deleted);
|
||||
|
@ -512,7 +512,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(true);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed3 = tmm.delete(3, undefined, true);
|
||||
const removed3 = tmm.delete(3, true);
|
||||
expect(removed3 instanceof Array);
|
||||
expect(removed3[0]);
|
||||
expect(removed3[0].deleted);
|
||||
|
@ -520,7 +520,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed8 = tmm.delete(8, undefined, true);
|
||||
const removed8 = tmm.delete(8, true);
|
||||
expect(removed8 instanceof Array);
|
||||
expect(removed8[0]);
|
||||
expect(removed8[0].deleted);
|
||||
|
@ -528,17 +528,17 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed6 = tmm.delete(6, undefined, true);
|
||||
const removed6 = tmm.delete(6, true);
|
||||
expect(removed6 instanceof Array);
|
||||
expect(removed6[0]);
|
||||
expect(removed6[0].deleted);
|
||||
if (removed6[0].deleted) expect(removed6[0].deleted.key).toBe(6);
|
||||
expect(tmm.delete(6, undefined, true).length).toBe(0);
|
||||
expect(tmm.delete(6, true).length).toBe(0);
|
||||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed7 = tmm.delete(7, undefined, true);
|
||||
const removed7 = tmm.delete(7, true);
|
||||
expect(removed7 instanceof Array);
|
||||
expect(removed7[0]);
|
||||
expect(removed7[0].deleted);
|
||||
|
@ -546,7 +546,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(false);
|
||||
expect(tmm.getHeight()).toBe(3);
|
||||
|
||||
const removed9 = tmm.delete(9, undefined, true);
|
||||
const removed9 = tmm.delete(9, true);
|
||||
expect(removed9 instanceof Array);
|
||||
expect(removed9[0]);
|
||||
expect(removed9[0].deleted);
|
||||
|
@ -554,7 +554,7 @@ describe('TreeMultiMap operations test recursively1', () => {
|
|||
expect(tmm.isAVLBalanced()).toBe(true);
|
||||
expect(tmm.getHeight()).toBe(2);
|
||||
|
||||
const removed14 = tmm.delete(14, undefined, true);
|
||||
const removed14 = tmm.delete(14, true);
|
||||
expect(removed14 instanceof Array);
|
||||
expect(removed14[0]);
|
||||
expect(removed14[0].deleted);
|
||||
|
@ -664,7 +664,7 @@ describe('TreeMultiMap delete test', function () {
|
|||
}
|
||||
|
||||
for (let i = 0; i < inputSize; i++) {
|
||||
tmm.delete(i, undefined, true);
|
||||
tmm.delete(i, true);
|
||||
}
|
||||
|
||||
let nilCount = 0;
|
||||
|
|
|
@ -44,6 +44,8 @@ describe('UndirectedGraph Operation Test', () => {
|
|||
|
||||
expect(graph.hasEdge('A', 'B')).toBe(true);
|
||||
expect(graph.hasEdge('B', 'A')).toBe(true);
|
||||
expect(graph.has('A')).toBe(true);
|
||||
expect(graph.get('A')).toBe(undefined);
|
||||
});
|
||||
|
||||
it('should delete edges', () => {
|
||||
|
|
Loading…
Reference in a new issue