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:
Revone 2024-10-30 20:52:23 +13:00
parent fc0d157295
commit 6428e0f228
32 changed files with 1160 additions and 1209 deletions

View file

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

@ -0,0 +1,4 @@
export enum DFSOperation {
VISIT = 0,
PROCESS = 1
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2,3 +2,4 @@ export * from './data-structures';
export * from './utils';
export * from './interfaces';
export * from './types';
export * from './constants';

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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