refactor: The parameters for the add and addMany methods in all binary tree data structures have been changed to the entry style, and the first test has passed.

This commit is contained in:
Revone 2023-11-25 14:38:32 +08:00
parent cd14ec79ec
commit 18b895cb4c
15 changed files with 459 additions and 470 deletions

View file

@ -626,52 +626,52 @@ Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.key) // ['A', 'B', '
[//]: # (No deletion!!! Start of Replace Section)
<div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>avl-tree</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>31.32</td><td>31.93</td><td>3.67e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>70.90</td><td>14.10</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>40.58</td><td>24.64</td><td>4.87e-4</td></tr><tr><td>10,000 get</td><td>27.31</td><td>36.62</td><td>2.00e-4</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>33.09</td><td>30.22</td><td>4.32e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>74.12</td><td>13.49</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>41.71</td><td>23.97</td><td>0.00</td></tr><tr><td>10,000 get</td><td>28.37</td><td>35.25</td><td>2.37e-4</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>binary-tree</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 add randomly</td><td>12.35</td><td>80.99</td><td>7.17e-5</td></tr><tr><td>1,000 add & delete randomly</td><td>15.98</td><td>62.58</td><td>7.98e-4</td></tr><tr><td>1,000 addMany</td><td>10.96</td><td>91.27</td><td>0.00</td></tr><tr><td>1,000 get</td><td>18.61</td><td>53.73</td><td>0.00</td></tr><tr><td>1,000 dfs</td><td>164.20</td><td>6.09</td><td>0.04</td></tr><tr><td>1,000 bfs</td><td>58.84</td><td>17.00</td><td>0.01</td></tr><tr><td>1,000 morris</td><td>256.66</td><td>3.90</td><td>7.70e-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>1,000 add randomly</td><td>14.50</td><td>68.96</td><td>1.33e-4</td></tr><tr><td>1,000 add & delete randomly</td><td>16.20</td><td>61.72</td><td>2.03e-4</td></tr><tr><td>1,000 addMany</td><td>10.51</td><td>95.12</td><td>8.76e-5</td></tr><tr><td>1,000 get</td><td>18.28</td><td>54.69</td><td>1.82e-4</td></tr><tr><td>1,000 dfs</td><td>157.23</td><td>6.36</td><td>7.06e-4</td></tr><tr><td>1,000 bfs</td><td>58.06</td><td>17.22</td><td>0.01</td></tr><tr><td>1,000 morris</td><td>256.36</td><td>3.90</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>bst</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>31.59</td><td>31.66</td><td>2.74e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>74.56</td><td>13.41</td><td>8.32e-4</td></tr><tr><td>10,000 addMany</td><td>29.16</td><td>34.30</td><td>0.00</td></tr><tr><td>10,000 get</td><td>29.24</td><td>34.21</td><td>0.00</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>30.48</td><td>32.81</td><td>4.13e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>71.84</td><td>13.92</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>29.54</td><td>33.85</td><td>5.25e-4</td></tr><tr><td>10,000 get</td><td>30.53</td><td>32.75</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>85.85</td><td>11.65</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>211.54</td><td>4.73</td><td>0.00</td></tr><tr><td>100,000 getNode</td><td>37.92</td><td>26.37</td><td>1.65e-4</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add</td><td>90.89</td><td>11.00</td><td>0.00</td></tr><tr><td>100,000 CPT add</td><td>50.65</td><td>19.74</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>230.08</td><td>4.35</td><td>0.02</td></tr><tr><td>100,000 getNode</td><td>38.97</td><td>25.66</td><td>5.82e-4</td></tr><tr><td>100,000 add & iterator</td><td>118.32</td><td>8.45</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'>comparison</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>SRC PQ 10,000 add</td><td>0.57</td><td>1748.73</td><td>4.96e-6</td></tr><tr><td>CJS PQ 10,000 add</td><td>0.57</td><td>1746.69</td><td>4.91e-6</td></tr><tr><td>MJS PQ 10,000 add</td><td>0.57</td><td>1749.68</td><td>4.43e-6</td></tr><tr><td>SRC PQ 10,000 add & pop</td><td>3.47</td><td>288.14</td><td>6.38e-4</td></tr><tr><td>CJS PQ 10,000 add & pop</td><td>3.39</td><td>295.36</td><td>3.90e-5</td></tr><tr><td>MJS PQ 10,000 add & pop</td><td>3.37</td><td>297.17</td><td>3.03e-5</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>SRC PQ 10,000 add</td><td>0.14</td><td>6939.33</td><td>1.74e-6</td></tr><tr><td>CJS PQ 10,000 add</td><td>0.15</td><td>6881.64</td><td>1.91e-6</td></tr><tr><td>MJS PQ 10,000 add</td><td>0.57</td><td>1745.92</td><td>1.60e-5</td></tr><tr><td>CPT PQ 10,000 add</td><td>0.57</td><td>1744.71</td><td>1.01e-5</td></tr><tr><td>SRC PQ 10,000 add & pop</td><td>3.51</td><td>284.93</td><td>6.79e-4</td></tr><tr><td>CJS PQ 10,000 add & pop</td><td>3.42</td><td>292.55</td><td>4.04e-5</td></tr><tr><td>MJS PQ 10,000 add & pop</td><td>3.41</td><td>293.38</td><td>5.11e-5</td></tr><tr><td>CPT PQ 10,000 add & pop</td><td>2.09</td><td>478.76</td><td>2.28e-5</td></tr><tr><td>CPT OM 100,000 add</td><td>43.22</td><td>23.14</td><td>0.00</td></tr><tr><td>CPT HM 10,000 set</td><td>0.58</td><td>1721.25</td><td>1.85e-5</td></tr><tr><td>CPT HM 10,000 set & get</td><td>0.68</td><td>1477.31</td><td>1.26e-5</td></tr><tr><td>CPT LL 1,000,000 unshift</td><td>81.38</td><td>12.29</td><td>0.02</td></tr><tr><td>CPT PQ 10,000 add & pop</td><td>2.10</td><td>476.50</td><td>1.60e-4</td></tr><tr><td>CPT DQ 1,000,000 push</td><td>22.51</td><td>44.42</td><td>0.00</td></tr><tr><td>CPT Q 1,000,000 push</td><td>47.85</td><td>20.90</td><td>0.01</td></tr><tr><td>CPT ST 1,000,000 push</td><td>42.54</td><td>23.51</td><td>0.01</td></tr><tr><td>CPT ST 1,000,000 push & pop</td><td>50.08</td><td>19.97</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>9534.93</td><td>8.72e-7</td></tr><tr><td>1,000 addEdge</td><td>6.30</td><td>158.67</td><td>0.00</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.16e+4</td><td>3.03e-7</td></tr><tr><td>1,000 getEdge</td><td>22.31</td><td>44.82</td><td>0.00</td></tr><tr><td>tarjan</td><td>210.90</td><td>4.74</td><td>0.01</td></tr><tr><td>tarjan all</td><td>214.72</td><td>4.66</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>172.52</td><td>5.80</td><td>0.00</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000 addVertex</td><td>0.11</td><td>9501.34</td><td>6.10e-6</td></tr><tr><td>1,000 addEdge</td><td>6.35</td><td>157.55</td><td>6.69e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.14e+4</td><td>2.50e-6</td></tr><tr><td>1,000 getEdge</td><td>25.00</td><td>39.99</td><td>0.01</td></tr><tr><td>tarjan</td><td>219.46</td><td>4.56</td><td>0.01</td></tr><tr><td>tarjan all</td><td>218.15</td><td>4.58</td><td>0.00</td></tr><tr><td>topologicalSort</td><td>176.83</td><td>5.66</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'>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>275.88</td><td>3.62</td><td>0.12</td></tr><tr><td>1,000,000 Map set</td><td>211.66</td><td>4.72</td><td>0.01</td></tr><tr><td>1,000,000 Set add</td><td>177.72</td><td>5.63</td><td>0.02</td></tr><tr><td>1,000,000 set & get</td><td>317.60</td><td>3.15</td><td>0.02</td></tr><tr><td>1,000,000 Map set & get</td><td>274.99</td><td>3.64</td><td>0.03</td></tr><tr><td>1,000,000 Set add & has</td><td>172.23</td><td>5.81</td><td>0.02</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>929.40</td><td>1.08</td><td>0.07</td></tr><tr><td>1,000,000 Map ObjKey set & get</td><td>310.02</td><td>3.23</td><td>0.05</td></tr><tr><td>1,000,000 Set ObjKey add & has</td><td>283.28</td><td>3.53</td><td>0.04</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 set</td><td>254.46</td><td>3.93</td><td>0.04</td></tr><tr><td>1,000,000 CPT set</td><td>251.21</td><td>3.98</td><td>0.03</td></tr><tr><td>1,000,000 Map set</td><td>211.27</td><td>4.73</td><td>0.01</td></tr><tr><td>1,000,000 Set add</td><td>175.15</td><td>5.71</td><td>0.02</td></tr><tr><td>1,000,000 set & get</td><td>370.54</td><td>2.70</td><td>0.11</td></tr><tr><td>1,000,000 CPT set & get</td><td>283.34</td><td>3.53</td><td>0.07</td></tr><tr><td>1,000,000 Map set & get</td><td>287.09</td><td>3.48</td><td>0.04</td></tr><tr><td>1,000,000 Set add & has</td><td>190.50</td><td>5.25</td><td>0.01</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>880.47</td><td>1.14</td><td>0.10</td></tr><tr><td>1,000,000 Map ObjKey set & get</td><td>334.47</td><td>2.99</td><td>0.05</td></tr><tr><td>1,000,000 Set ObjKey add & has</td><td>310.12</td><td>3.22</td><td>0.06</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>heap</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add & pop</td><td>5.80</td><td>172.35</td><td>8.78e-5</td></tr><tr><td>10,000 fib add & pop</td><td>357.92</td><td>2.79</td><td>0.00</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & pop</td><td>80.13</td><td>12.48</td><td>0.00</td></tr><tr><td>100,000 add & dfs</td><td>35.08</td><td>28.50</td><td>0.00</td></tr><tr><td>10,000 fib add & pop</td><td>367.84</td><td>2.72</td><td>0.01</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>doubly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>221.57</td><td>4.51</td><td>0.03</td></tr><tr><td>1,000,000 unshift</td><td>229.02</td><td>4.37</td><td>0.07</td></tr><tr><td>1,000,000 unshift & shift</td><td>169.21</td><td>5.91</td><td>0.02</td></tr><tr><td>1,000,000 insertBefore</td><td>314.48</td><td>3.18</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>237.28</td><td>4.21</td><td>0.07</td></tr><tr><td>1,000,000 CPT push</td><td>75.66</td><td>13.22</td><td>0.03</td></tr><tr><td>1,000,000 unshift</td><td>226.38</td><td>4.42</td><td>0.05</td></tr><tr><td>1,000,000 CPT unshift</td><td>93.34</td><td>10.71</td><td>0.07</td></tr><tr><td>1,000,000 unshift & shift</td><td>188.34</td><td>5.31</td><td>0.05</td></tr><tr><td>1,000,000 insertBefore</td><td>329.60</td><td>3.03</td><td>0.05</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>singly-linked-list</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 push & pop</td><td>212.98</td><td>4.70</td><td>0.01</td></tr><tr><td>10,000 insertBefore</td><td>250.68</td><td>3.99</td><td>0.01</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 push & pop</td><td>221.32</td><td>4.52</td><td>0.01</td></tr><tr><td>10,000 insertBefore</td><td>255.52</td><td>3.91</td><td>0.01</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>max-priority-queue</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>8.91</td><td>112.29</td><td>2.26e-4</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>9.07</td><td>110.24</td><td>2.71e-4</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>priority-queue</span></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add & pop</td><td>103.59</td><td>9.65</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 & pop</td><td>101.93</td><td>9.81</td><td>7.95e-4</td></tr><tr><td>100,000 CPT add & pop</td><td>28.54</td><td>35.04</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'>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>14.55</td><td>68.72</td><td>6.91e-4</td></tr><tr><td>1,000,000 push & pop</td><td>23.40</td><td>42.73</td><td>5.94e-4</td></tr><tr><td>1,000,000 push & shift</td><td>24.41</td><td>40.97</td><td>1.45e-4</td></tr><tr><td>1,000,000 unshift & shift</td><td>22.56</td><td>44.32</td><td>1.30e-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>1,000,000 push</td><td>14.43</td><td>69.29</td><td>2.36e-4</td></tr><tr><td>1,000,000 CPT push</td><td>25.08</td><td>39.87</td><td>0.01</td></tr><tr><td>1,000,000 push & pop</td><td>22.87</td><td>43.72</td><td>6.05e-4</td></tr><tr><td>1,000,000 push & shift</td><td>25.28</td><td>39.55</td><td>0.01</td></tr><tr><td>1,000,000 unshift & shift</td><td>21.88</td><td>45.71</td><td>2.05e-4</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>39.90</td><td>25.07</td><td>0.01</td></tr><tr><td>1,000,000 push & shift</td><td>81.79</td><td>12.23</td><td>0.00</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>38.49</td><td>25.98</td><td>9.08e-4</td></tr><tr><td>1,000,000 CPT push</td><td>43.93</td><td>22.76</td><td>0.01</td></tr><tr><td>1,000,000 push & shift</td><td>82.85</td><td>12.07</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>37.60</td><td>26.60</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>47.01</td><td>21.27</td><td>0.00</td></tr></table></div>
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>40.19</td><td>24.88</td><td>0.01</td></tr><tr><td>1,000,000 CPT push</td><td>39.87</td><td>25.08</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>41.67</td><td>24.00</td><td>0.01</td></tr><tr><td>1,000,000 CPT push & pop</td><td>46.65</td><td>21.44</td><td>0.00</td></tr></table></div>
</div><div class="json-to-html-collapse clearfix 0">
<div class='collapsible level0' ><span class='json-to-html-label'>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>45.97</td><td>21.76</td><td>0.00</td></tr><tr><td>100,000 getWords</td><td>66.20</td><td>15.11</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>43.42</td><td>23.03</td><td>7.57e-4</td></tr><tr><td>100,000 getWords</td><td>93.41</td><td>10.71</td><td>0.00</td></tr></table></div>
</div>
[//]: # (No deletion!!! End of Replace Section)

View file

@ -11,10 +11,9 @@ import type {
AVLTreeNodeNested,
AVLTreeOptions,
BiTreeDeleteResult,
BSTNKeyOrNode,
BTNExemplar,
BTNKey,
BTNKeyOrNode
BSTNodeKeyOrNode,
BTNodeExemplar,
BTNKey
} from '../../types';
import { BTNCallback } from '../../types';
import { IBinaryTree } from '../../interfaces';
@ -38,9 +37,9 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
* constructor of the AVLTree class. It allows you to customize the behavior of the AVL tree by providing different
* options.
*/
constructor(elements?: Iterable<BTNExemplar<V, N>>, options?: Partial<AVLTreeOptions>) {
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<AVLTreeOptions>) {
super([], options);
if (elements) this.init(elements);
if (elements) this.addMany(elements);
}
/**
@ -75,9 +74,9 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
* added to the binary search tree.
* @returns The method is returning either a node (N) or undefined.
*/
override add(keyOrNode: BTNKeyOrNode<N>, value?: V): N | undefined {
if (keyOrNode === null) return undefined;
const inserted = super.add(keyOrNode, value);
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
if (keyOrNodeOrEntry === null) return undefined;
const inserted = super.add(keyOrNodeOrEntry);
if (inserted) this._balancePath(inserted);
return inserted;
}
@ -116,23 +115,6 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
return deletedResults;
}
/**
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (BST) has logarithmic time complexity.
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
*/
init(elements: Iterable<BTNExemplar<V, N>>): void {
if (elements) {
for (const entryOrKey of elements) {
if (Array.isArray(entryOrKey)) {
const [key, value] = entryOrKey;
this.add(key, value);
} else {
this.add(entryOrKey);
}
}
}
}
/**
* The `_swap` function swaps the key, value, and height properties between two nodes in a binary
@ -144,7 +126,7 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
* @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`
* if either `srcNode` or `destNode` is undefined.
*/
protected override _swap(srcNode: BSTNKeyOrNode<N>, destNode: BSTNKeyOrNode<N>): N | undefined {
protected override _swap(srcNode: BSTNodeKeyOrNode<N>, destNode: BSTNodeKeyOrNode<N>): N | undefined {
srcNode = this.ensureNotKey(srcNode);
destNode = this.ensureNotKey(destNode);

View file

@ -10,9 +10,10 @@ import type {
BinaryTreeNodeNested,
BinaryTreeOptions,
BTNCallback,
BTNExemplar,
BTNodeEntry,
BTNodeExemplar,
BTNKey,
BTNKeyOrNode
BTNodeKeyOrNode
} from '../../types';
import {
BinaryTreeNested,
@ -131,7 +132,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* Creates a new instance of BinaryTree.
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
*/
constructor(elements?: Iterable<BTNExemplar<V, N>>, options?: Partial<BinaryTreeOptions>) {
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BinaryTreeOptions>) {
if (options) {
const { iterationType } = options;
@ -142,7 +143,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
this._size = 0;
if (elements) this.init(elements);
if (elements) this.addMany(elements);
}
protected _root?: N | null;
@ -177,6 +178,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
return new BinaryTree<V, N, TREE>([], { iterationType: this.iterationType, ...options }) as TREE;
}
isEntry(kne: BTNodeExemplar<V, N>): kne is BTNodeEntry<V> {
return Array.isArray(kne) && kne.length === 2;
}
/**
* Time Complexity: O(n)
* Space Complexity: O(1)
@ -190,7 +195,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* @returns The function `add` returns a node (`N`) if it was successfully inserted into the binary
* tree, or `null` or `undefined` if the insertion was not successful.
*/
add(keyOrNode: BTNKeyOrNode<N>, value?: V): N | null | undefined {
add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | null | undefined {
const _bfs = (root: N, newNode: N | null): N | undefined | null => {
const queue = new Queue<N>([root]);
while (queue.size > 0) {
@ -208,12 +213,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
let inserted: N | null | undefined, needInsert: N | null | undefined;
if (keyOrNode === null) {
if (keyOrNodeOrEntry === null) {
needInsert = null;
} else if (this.isNodeKey(keyOrNode)) {
needInsert = this.createNode(keyOrNode, value);
} else if (keyOrNode instanceof BinaryTreeNode) {
needInsert = keyOrNode;
} else if (this.isNodeKey(keyOrNodeOrEntry)) {
needInsert = this.createNode(keyOrNodeOrEntry);
} else if (keyOrNodeOrEntry instanceof BinaryTreeNode) {
needInsert = keyOrNodeOrEntry;
} else if (this.isEntry(keyOrNodeOrEntry)) {
const [key, value] = keyOrNodeOrEntry;
if (key === undefined) {
return;
} else if (key === null) {
needInsert = null;
} else {
needInsert = this.createNode(key, value);
}
} else {
return;
}
@ -252,19 +266,19 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* keys or nodes during the add operation.
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
*/
addMany(keysOrNodes: (BTNKeyOrNode<N>)[], values?: (V | undefined)[]): (N | null | undefined)[] {
addMany(nodes: Iterable<BTNodeExemplar<V, N>>): (N | null | undefined)[] {
// TODO not sure addMany not be run multi times
const keysOrNodes = [...nodes];
return keysOrNodes.map((keyOrNode, i) => {
if (keyOrNode instanceof BinaryTreeNode) {
return this.add(keyOrNode.key, keyOrNode.value);
return this.add(keyOrNode);
}
if (keyOrNode === null) {
return this.add(null);
}
const value = values?.[i];
return this.add(keyOrNode, value);
return this.add(keyOrNode);
});
}
@ -285,9 +299,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* array. Each value in the `data` array will be assigned to the
* @returns The method is returning a boolean value.
*/
refill(keysOrNodes: (BTNKeyOrNode<N>)[], values?: (V | undefined)[]): boolean {
refill(nodesOrKeysOrEntries: Iterable<BTNodeExemplar<V, N>>): void {
this.clear();
return keysOrNodes.length === this.addMany(keysOrNodes, values).length;
this.addMany(nodesOrKeysOrEntries);
}
/**
@ -384,7 +398,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* `N` (binary tree node) or `null` or `undefined`. If no value is provided for `beginRoot
* @returns the depth of the `distNode` relative to the `beginRoot`.
*/
getDepth(distNode: BTNKeyOrNode<N>, beginRoot: BTNKeyOrNode<N> = this.root): number {
getDepth(distNode: BTNodeKeyOrNode<N>, beginRoot: BTNodeKeyOrNode<N> = this.root): number {
distNode = this.ensureNotKey(distNode);
beginRoot = this.ensureNotKey(beginRoot);
let depth = 0;
@ -417,7 +431,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* values:
* @returns the height of the binary tree.
*/
getHeight(beginRoot: BTNKeyOrNode<N> = this.root, iterationType = this.iterationType): number {
getHeight(beginRoot: BTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): number {
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return -1;
@ -466,7 +480,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* to calculate the minimum height of a binary tree. It can have two possible values:
* @returns The function `getMinHeight` returns the minimum height of a binary tree.
*/
getMinHeight(beginRoot: BTNKeyOrNode<N> = this.root, iterationType = this.iterationType): number {
getMinHeight(beginRoot: BTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): number {
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return -1;
@ -526,7 +540,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* value of a binary tree node), `N` (a node of a binary tree), `null`, or `undefined`. If
* @returns a boolean value.
*/
isPerfectlyBalanced(beginRoot: BTNKeyOrNode<N> = this.root): boolean {
isPerfectlyBalanced(beginRoot: BTNodeKeyOrNode<N> = this.root): boolean {
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
}
@ -539,7 +553,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
identifier: BTNKey,
callback?: C,
onlyOne?: boolean,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): N[];
@ -547,7 +561,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
identifier: N | null | undefined,
callback?: C,
onlyOne?: boolean,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): N[];
@ -555,7 +569,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
identifier: ReturnType<C>,
callback: C,
onlyOne?: boolean,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): N[];
@ -588,7 +602,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
onlyOne = false,
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): N[] {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@ -636,21 +650,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
has<C extends BTNCallback<N, BTNKey>>(
identifier: BTNKey,
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): boolean;
has<C extends BTNCallback<N, N>>(
identifier: N | null | undefined,
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): boolean;
has<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
callback: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): boolean;
@ -677,7 +691,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
has<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): boolean {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@ -694,21 +708,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
getNode<C extends BTNCallback<N, BTNKey>>(
identifier: BTNKey,
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): N | null | undefined;
getNode<C extends BTNCallback<N, N>>(
identifier: N | null | undefined,
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): N | null | undefined;
getNode<C extends BTNCallback<N>>(
identifier: ReturnType<C>,
callback: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): N | null | undefined;
@ -736,7 +750,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
getNode<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): N | null | undefined {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@ -805,28 +819,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* @returns either the node corresponding to the given key if it is a valid node key, or the key
* itself if it is not a valid node key.
*/
ensureNotKey(key: BTNKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | null | undefined {
ensureNotKey(key: BTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | null | undefined {
return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
}
get<C extends BTNCallback<N, BTNKey>>(
identifier: BTNKey,
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): V | undefined;
get<C extends BTNCallback<N, N>>(
identifier: N | null | undefined,
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): V | undefined;
get<C extends BTNCallback<N>>(
identifier: ReturnType<C>,
callback: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType
): V | undefined;
@ -855,7 +869,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
get<C extends BTNCallback<N>>(
identifier: ReturnType<C> | null | undefined,
callback: C = this._defaultOneParamCallback as C,
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): V | undefined {
if ((!callback || callback === this._defaultOneParamCallback) && (identifier as any) instanceof BinaryTreeNode)
@ -899,7 +913,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* reversed before returning it. If `isReverse` is set to `false`, the path will be returned as is
* @returns The function `getPathToRoot` returns an array of nodes (`N[]`).
*/
getPathToRoot(beginRoot: BTNKeyOrNode<N>, isReverse = true): N[] {
getPathToRoot(beginRoot: BTNodeKeyOrNode<N>, isReverse = true): N[] {
// TODO to support get path through passing key
const result: N[] = [];
beginRoot = this.ensureNotKey(beginRoot);
@ -936,7 +950,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* is no leftmost node, it returns `null` or `undefined` depending on the input.
*/
getLeftMost(
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): N | null | undefined {
beginRoot = this.ensureNotKey(beginRoot);
@ -982,7 +996,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* is no rightmost node, it returns `null` or `undefined`, depending on the input.
*/
getRightMost(
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): N | null | undefined {
// TODO support get right most by passing key in
@ -1024,7 +1038,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* possible values:
* @returns a boolean value.
*/
isSubtreeBST(beginRoot: BTNKeyOrNode<N>, iterationType = this.iterationType): boolean {
isSubtreeBST(beginRoot: BTNodeKeyOrNode<N>, iterationType = this.iterationType): boolean {
// TODO there is a bug
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return true;
@ -1083,21 +1097,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
subTreeTraverse<C extends BTNCallback<N>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: false
): ReturnType<C>[];
subTreeTraverse<C extends BTNCallback<N>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType<C>[];
subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: true
): ReturnType<C>[];
@ -1126,7 +1140,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
*/
subTreeTraverse<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType,
includeNull = false
): ReturnType<C>[] {
@ -1216,7 +1230,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
dfs<C extends BTNCallback<N>>(
callback?: C,
pattern?: DFSOrderPattern,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: false
): ReturnType<C>[];
@ -1224,7 +1238,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
dfs<C extends BTNCallback<N>>(
callback?: C,
pattern?: DFSOrderPattern,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType<C>[];
@ -1232,7 +1246,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
dfs<C extends BTNCallback<N | null | undefined>>(
callback?: C,
pattern?: DFSOrderPattern,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: true
): ReturnType<C>[];
@ -1263,7 +1277,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
dfs<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
pattern: DFSOrderPattern = 'in',
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType: IterationType = IterationType.ITERATIVE,
includeNull = false
): ReturnType<C>[] {
@ -1362,21 +1376,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
bfs<C extends BTNCallback<N>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: false
): ReturnType<C>[];
bfs<C extends BTNCallback<N>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType<C>[];
bfs<C extends BTNCallback<N | null | undefined>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: true
): ReturnType<C>[];
@ -1404,7 +1418,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
*/
bfs<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType,
includeNull = false
): ReturnType<C>[] {
@ -1463,21 +1477,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
listLevels<C extends BTNCallback<N>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: false
): ReturnType<C>[][];
listLevels<C extends BTNCallback<N>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: undefined
): ReturnType<C>[][];
listLevels<C extends BTNCallback<N | null | undefined>>(
callback?: C,
beginRoot?: BTNKeyOrNode<N>,
beginRoot?: BTNodeKeyOrNode<N>,
iterationType?: IterationType,
includeNull?: true
): ReturnType<C>[][];
@ -1505,7 +1519,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
*/
listLevels<C extends BTNCallback<N | null | undefined>>(
callback: C = this._defaultOneParamCallback as C,
beginRoot: BTNKeyOrNode<N> = this.root,
beginRoot: BTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType,
includeNull = false
): ReturnType<C>[][] {
@ -1563,7 +1577,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* `null`, or `undefined`.
* @returns The function `getPredecessor` returns a value of type `N | undefined`.
*/
getPredecessor(node: BTNKeyOrNode<N>): N | undefined {
getPredecessor(node: BTNodeKeyOrNode<N>): N | undefined {
node = this.ensureNotKey(node);
if (!this.isRealNode(node)) return undefined;
@ -1623,7 +1637,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
morris<C extends BTNCallback<N>>(
callback: C = this._defaultOneParamCallback as C,
pattern: DFSOrderPattern = 'in',
beginRoot: BTNKeyOrNode<N> = this.root
beginRoot: BTNodeKeyOrNode<N> = this.root
): ReturnType<C>[] {
beginRoot = this.ensureNotKey(beginRoot);
if (beginRoot === null) return [];
@ -1735,7 +1749,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
const newTree = this.createTree();
for (const [key, value] of this) {
if (predicate([key, value], this)) {
newTree.add(key, value);
newTree.add([key, value]);
}
}
return newTree;
@ -1750,7 +1764,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
map(callback: (entry: [BTNKey, V | undefined], tree: this) => V) {
const newTree = this.createTree();
for (const [key, value] of this) {
newTree.add(key, callback([key, value], this));
newTree.add([key, callback([key, value], this)]);
}
return newTree;
}
@ -1831,7 +1845,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* following types:
* @param {BinaryTreePrintOptions} [options={ isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false}] - Options object that controls printing behavior. You can specify whether to display undefined, null, or sentinel nodes.
*/
print(beginRoot: BTNKeyOrNode<N> = this.root, options?: BinaryTreePrintOptions): void {
print(beginRoot: BTNodeKeyOrNode<N> = this.root, options?: BinaryTreePrintOptions): void {
const opts = { isShowUndefined: false, isShowNull: false, isShowRedBlackNIL: false, ...options };
beginRoot = this.ensureNotKey(beginRoot);
if (!beginRoot) return;
@ -1853,19 +1867,6 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
display(beginRoot);
}
init(elements: Iterable<BTNExemplar<V, N>>): void {
if (elements) {
for (const entryOrKey of elements) {
if (Array.isArray(entryOrKey)) {
const [key, value] = entryOrKey;
this.add(key, value);
} else {
this.add(entryOrKey);
}
}
}
}
protected _displayAux(node: N | null | undefined, options: BinaryTreePrintOptions): NodeDisplayLayout {
const { isShowNull, isShowUndefined, isShowRedBlackNIL } = options;
const emptyDisplayLayout = <NodeDisplayLayout>[['─'], 1, 0, 0];
@ -1924,7 +1925,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* @param {N} destNode - The destination node to swap.
* @returns {N} - The destination node after the swap.
*/
protected _swap(srcNode: BTNKeyOrNode<N>, destNode: BTNKeyOrNode<N>): N | undefined {
protected _swap(srcNode: BTNodeKeyOrNode<N>, destNode: BTNodeKeyOrNode<N>): N | undefined {
srcNode = this.ensureNotKey(srcNode);
destNode = this.ensureNotKey(destNode);
@ -1956,7 +1957,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
* the binary tree. If neither the left nor right child is available, the function returns undefined.
* If the parent node is null, the function also returns undefined.
*/
protected _addTo(newNode: N | null | undefined, parent: BTNKeyOrNode<N>): N | null | undefined {
protected _addTo(newNode: N | null | undefined, parent: BTNodeKeyOrNode<N>): N | null | undefined {
if (this.isNodeKey(parent)) parent = this.getNode(parent);
if (parent) {

View file

@ -7,14 +7,14 @@
*/
import type {
BSTNested,
BSTNKeyOrNode,
BSTNodeKeyOrNode,
BSTNodeNested,
BSTOptions,
BTNCallback,
BTNExemplar,
BTNodeExemplar,
BTNKey,
BTNKeyOrNode,
Comparator
Comparator,
BTNodePureExemplar
} from '../../types';
import { CP, IterationType } from '../../types';
import { BinaryTree, BinaryTreeNode } from './binary-tree';
@ -76,12 +76,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
extends BinaryTree<V, N, TREE>
implements IBinaryTree<V, N, TREE> {
/**
* The constructor function initializes a binary search tree with an optional comparator function.
* @param {BSTOptions} [options] - An optional object that contains additional configuration options
* for the binary search tree.
*/
constructor(elements?: Iterable<BTNExemplar<V, N>>, options?: Partial<BSTOptions>) {
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<BSTOptions>) {
super([], options);
if (options) {
@ -92,7 +88,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
}
this._root = undefined;
if (elements) this.init(elements);
if (elements) this.addMany(elements);
}
protected override _root?: N;
@ -137,15 +134,23 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* @returns The method `add` returns a node (`N`) that was inserted into the binary search tree. If
* no node was inserted, it returns `undefined`.
*/
override add(keyOrNode: BTNKeyOrNode<N>, value?: V): N | undefined {
if (keyOrNode === null) return undefined;
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
if (keyOrNodeOrEntry === null) return undefined;
// TODO support node as a parameter
let inserted: N | undefined;
let newNode: N | undefined;
if (keyOrNode instanceof BSTNode) {
newNode = keyOrNode;
} else if (this.isNodeKey(keyOrNode)) {
newNode = this.createNode(keyOrNode, value);
if (keyOrNodeOrEntry instanceof BSTNode) {
newNode = keyOrNodeOrEntry;
} else if (this.isNodeKey(keyOrNodeOrEntry)) {
newNode = this.createNode(keyOrNodeOrEntry);
} else if (this.isEntry(keyOrNodeOrEntry)) {
const [key, value] = keyOrNodeOrEntry;
if (key === undefined || key === null) {
return;
} else {
newNode = this.createNode(key, value);
}
} else {
newNode = undefined;
}
@ -230,57 +235,55 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.
*/
override addMany(
keysOrNodes: (BSTNKeyOrNode<N>)[],
data?: (V | undefined)[],
keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>,
isBalanceAdd = true,
iterationType = this.iterationType
): (N | undefined)[] {
const inserted: (N | undefined)[] = []
if (!isBalanceAdd) {
for (const kve of keysOrNodesOrEntries) {
const nn = this.add(kve)
inserted.push(nn);
}
return inserted;
}
const realBTNExemplars: BTNodePureExemplar<V, N>[] = [];
const isRealBTNExemplar = (kve: BTNodeExemplar<V, N>): kve is BTNodePureExemplar<V, N> => {
if (kve === undefined || kve === null) return false;
return !(this.isEntry(kve) && (kve[0] === undefined || kve[0] === null));
}
for (const kve of keysOrNodesOrEntries) {
isRealBTNExemplar(kve) && realBTNExemplars.push(kve);
}
// TODO this addMany function is inefficient, it should be optimized
function hasNoUndefined(arr: (BSTNKeyOrNode<N>)[]): arr is (BTNKey | N)[] {
return arr.indexOf(undefined) === -1;
}
let sorted: BTNodePureExemplar<V, N>[] = [];
if (!isBalanceAdd || !hasNoUndefined(keysOrNodes)) {
return super.addMany(keysOrNodes, data).map(n => n ?? undefined);
}
sorted = realBTNExemplars.sort((a, b) => {
let aR: number, bR: number;
if (this.isEntry(a)) aR = a[0]
else if (this.isRealNode(a)) aR = a.key
else aR = a;
const inserted: (N | undefined)[] = [];
const combinedArr: [BTNKey | N, V][] = keysOrNodes.map(
(value: BTNKey | N, index) => [value, data?.[index]] as [BTNKey | N, V]
);
if (this.isEntry(b)) bR = b[0]
else if (this.isRealNode(b)) bR = b.key
else bR = b;
let sorted = [];
return aR - bR;
})
function _isNodeOrUndefinedTuple(arr: [BTNKey | N, V][]): arr is [N, V][] {
for (const [keyOrNode] of arr) if (keyOrNode instanceof BSTNode) return true;
return false;
}
const _isBinaryTreeKeyOrNullTuple = (arr: [BTNKey | N, V][]): arr is [BTNKey, V][] => {
for (const [keyOrNode] of arr) if (this.isNodeKey(keyOrNode)) return true;
return false;
};
let sortedKeysOrNodes: (number | N | undefined)[] = [],
sortedData: (V | undefined)[] | undefined = [];
if (_isNodeOrUndefinedTuple(combinedArr)) {
sorted = combinedArr.sort((a, b) => a[0].key - b[0].key);
} else if (_isBinaryTreeKeyOrNullTuple(combinedArr)) {
sorted = combinedArr.sort((a, b) => a[0] - b[0]);
} else {
throw new Error('Invalid input keysOrNodes');
}
sortedKeysOrNodes = sorted.map(([keyOrNode]) => keyOrNode);
sortedData = sorted.map(([, value]) => value);
const _dfs = (arr: (BSTNKeyOrNode<N>)[], data?: (V | undefined)[]) => {
const _dfs = (arr: BTNodePureExemplar<V, N>[]) => {
if (arr.length === 0) return;
const mid = Math.floor((arr.length - 1) / 2);
const newNode = this.add(arr[mid], data?.[mid]);
const newNode = this.add(arr[mid]);
inserted.push(newNode);
_dfs(arr.slice(0, mid), data?.slice(0, mid));
_dfs(arr.slice(mid + 1), data?.slice(mid + 1));
_dfs(arr.slice(0, mid));
_dfs(arr.slice(mid + 1));
};
const _iterate = () => {
const n = sorted.length;
@ -291,7 +294,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
const [l, r] = popped;
if (l <= r) {
const m = l + Math.floor((r - l) / 2);
const newNode = this.add(sortedKeysOrNodes[m], sortedData?.[m]);
const newNode = this.add(realBTNExemplars[m]);
inserted.push(newNode);
stack.push([m + 1, r]);
stack.push([l, m - 1]);
@ -300,7 +303,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
}
};
if (iterationType === IterationType.RECURSIVE) {
_dfs(sortedKeysOrNodes, sortedData);
_dfs(sorted);
} else {
_iterate();
}
@ -328,7 +331,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* the key of the leftmost node if the comparison result is greater than, and the key of the
* rightmost node otherwise. If no node is found, it returns 0.
*/
lastKey(beginRoot: BSTNKeyOrNode<N> = this.root, iterationType = this.iterationType): BTNKey {
lastKey(beginRoot: BSTNodeKeyOrNode<N> = this.root, iterationType = this.iterationType): BTNKey {
if (this._compare(0, 1) === CP.lt) return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
else if (this._compare(0, 1) === CP.gt) return this.getLeftMost(beginRoot, iterationType)?.key ?? 0;
else return this.getRightMost(beginRoot, iterationType)?.key ?? 0;
@ -392,7 +395,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
* type of iteration to be performed. It has a default value of `IterationType.ITERATIVE`.
* @returns either a node object (N) or undefined.
*/
override ensureNotKey(key: BSTNKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | undefined {
override ensureNotKey(key: BSTNodeKeyOrNode<N>, iterationType = IterationType.ITERATIVE): N | undefined {
return this.isNodeKey(key) ? this.getNodeByKey(key, iterationType) : key;
}
@ -423,7 +426,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
identifier: ReturnType<C> | undefined,
callback: C = this._defaultOneParamCallback as C,
onlyOne = false,
beginRoot: BSTNKeyOrNode<N> = this.root,
beginRoot: BSTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): N[] {
beginRoot = this.ensureNotKey(beginRoot);
@ -504,7 +507,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
lesserOrGreaterTraverse<C extends BTNCallback<N>>(
callback: C = this._defaultOneParamCallback as C,
lesserOrGreater: CP = CP.lt,
targetNode: BSTNKeyOrNode<N> = this.root,
targetNode: BSTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): ReturnType<C>[] {
targetNode = this.ensureNotKey(targetNode);
@ -569,7 +572,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
if (l > r) return;
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
this.add(midNode.key, midNode.value);
this.add([midNode.key, midNode.value]);
buildBalanceBST(l, m - 1);
buildBalanceBST(m + 1, r);
};
@ -586,7 +589,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
debugger;
this.add(midNode.key, midNode.value);
this.add([midNode.key, midNode.value]);
stack.push([m + 1, r]);
stack.push([l, m - 1]);
}
@ -664,23 +667,6 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
return balanced;
}
/**
* Time Complexity: O(n) - Visiting each node once.
* Space Complexity: O(log n) - Space for the recursive call stack in the worst case.
*/
override init(elements: Iterable<BTNExemplar<V, N>>): void {
if (elements) {
for (const entryOrKey of elements) {
if (Array.isArray(entryOrKey)) {
const [key, value] = entryOrKey;
this.add(key, value);
} else {
this.add(entryOrKey);
}
}
}
}
protected _setRoot(v: N | undefined) {
if (v) {

View file

@ -8,11 +8,10 @@
import {
BiTreeDeleteResult,
BSTNKeyOrNode,
BSTNodeKeyOrNode,
BTNCallback,
BTNExemplar,
BTNodeExemplar,
BTNKey,
BTNKeyOrNode,
IterationType,
RBTNColor,
RBTreeOptions,
@ -53,11 +52,11 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
* @param {RBTreeOptions} [options] - The `options` parameter is an optional object that can be
* passed to the constructor. It is used to configure the RBTree object with specific options.
*/
constructor(elements?: Iterable<BTNExemplar<V, N>>, options?: Partial<RBTreeOptions>) {
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<RBTreeOptions>) {
super([], options);
this._root = this.Sentinel;
if (elements) this.init(elements);
if (elements) this.addMany(elements);
}
protected _root: N;
@ -94,16 +93,21 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
* key in the node being added to the Red-Black Tree.
* @returns The method returns either a node (`N`) or `undefined`.
*/
override add(keyOrNode: BTNKeyOrNode<N>, value?: V): N | undefined {
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>): N | undefined {
let node: N;
if (this.isNodeKey(keyOrNode)) {
node = this.createNode(keyOrNode, value, RBTNColor.RED);
} else if (keyOrNode instanceof RedBlackTreeNode) {
node = keyOrNode;
} else if (keyOrNode === null) {
return;
} else if (keyOrNode === undefined) {
if (this.isNodeKey(keyOrNodeOrEntry)) {
node = this.createNode(keyOrNodeOrEntry, undefined, RBTNColor.RED);
} else if (keyOrNodeOrEntry instanceof RedBlackTreeNode) {
node = keyOrNodeOrEntry;
} else if (keyOrNodeOrEntry === null || keyOrNodeOrEntry === undefined) {
return;
} else if (this.isEntry(keyOrNodeOrEntry)) {
const [key, value] = keyOrNodeOrEntry;
if (key === undefined || key === null) {
return;
} else {
node = this.createNode(key, value, RBTNColor.RED);
}
} else {
return;
}
@ -287,7 +291,7 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
getNode<C extends BTNCallback<N>>(
identifier: ReturnType<C> | undefined,
callback: C = this._defaultOneParamCallback as C,
beginRoot: BSTNKeyOrNode<N> = this.root,
beginRoot: BSTNodeKeyOrNode<N> = this.root,
iterationType = this.iterationType
): N | null | undefined {
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
@ -359,19 +363,6 @@ export class RedBlackTree<V = any, N extends RedBlackTreeNode<V, N> = RedBlackTr
this._size = 0;
}
init(elements: Iterable<BTNExemplar<V, N>>): void {
if (elements) {
for (const entryOrKey of elements) {
if (Array.isArray(entryOrKey)) {
const [key, value] = entryOrKey;
this.add(key, value);
} else {
this.add(entryOrKey);
}
}
}
}
protected override _setRoot(v: N) {
if (v) {
v.parent = undefined;

View file

@ -5,14 +5,7 @@
* @copyright Copyright (c) 2022 Tyler Zeng <zrwusa@gmail.com>
* @license MIT License
*/
import type {
BSTNKeyOrNode,
BTNExemplar,
BTNKey,
BTNKeyOrNode,
TreeMultimapNodeNested,
TreeMultimapOptions
} from '../../types';
import type { BSTNodeKeyOrNode, BTNodeExemplar, BTNKey, TreeMultimapNodeNested, TreeMultimapOptions } from '../../types';
import { BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType, TreeMultimapNested } from '../../types';
import { IBinaryTree } from '../../interfaces';
import { AVLTree, AVLTreeNode } from './avl-tree';
@ -53,15 +46,18 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
* @param {TreeMultimapOptions} [options] - An optional object that contains additional configuration options for the
* TreeMultimap.
*/
constructor(elements?: Iterable<BTNExemplar<V, N>>, options?: Partial<TreeMultimapOptions>) {
constructor(elements?: Iterable<BTNodeExemplar<V, N>>, options?: Partial<TreeMultimapOptions>) {
super([], options);
if (elements) this.init(elements);
if (elements) this.addMany(elements);
}
private _count = 0;
// TODO the _count is not accurate after nodes count modified
get count(): number {
return this._count;
let sum = 0;
this.subTreeTraverse(node => sum += node.count);
return sum;
}
/**
@ -98,17 +94,28 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
* times the key-value pair should be added to the multimap. If not provided, the default value is 1.
* @returns a node (`N`) or `undefined`.
*/
override add(keyOrNode: BTNKeyOrNode<N>, value?: V, count = 1): N | undefined {
if (keyOrNode === null) return undefined;
override add(keyOrNodeOrEntry: BTNodeExemplar<V, N>, count = 1): N | undefined {
if (keyOrNodeOrEntry === null) return;
let inserted: N | undefined = undefined,
newNode: N | undefined;
if (keyOrNode instanceof TreeMultimapNode) {
newNode = this.createNode(keyOrNode.key, keyOrNode.value, keyOrNode.count);
} else if (keyOrNode === undefined) {
newNode = undefined;
if (keyOrNodeOrEntry instanceof TreeMultimapNode) {
newNode = this.createNode(keyOrNodeOrEntry.key, keyOrNodeOrEntry.value, keyOrNodeOrEntry.count);
} else if (keyOrNodeOrEntry === undefined) {
return;
} else if (this.isEntry(keyOrNodeOrEntry)) {
const [key, value] = keyOrNodeOrEntry;
if (key === null || key === undefined) {
return
} else {
newNode = this.createNode(key, value, count);
}
} else if (typeof keyOrNodeOrEntry === 'number') {
newNode = this.createNode(keyOrNodeOrEntry, undefined, 1);
} else {
newNode = this.createNode(keyOrNode, value, count);
return
}
if (!this.root) {
this._setRoot(newNode);
this._size = this.size + 1;
@ -185,23 +192,22 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
* TreeMultimap. If provided, the length of the `data` array should be the same as the length of the
* @returns The function `addMany` returns an array of nodes (`N`) or `undefined` values.
*/
override addMany(keysOrNodes: (BSTNKeyOrNode<N>)[], data?: V[]): (N | undefined)[] {
override addMany(keysOrNodesOrEntries: Iterable<BTNodeExemplar<V, N>>): (N | undefined)[] {
const inserted: (N | undefined)[] = [];
for (let i = 0; i < keysOrNodes.length; i++) {
const keyOrNode = keysOrNodes[i];
for (const keyOrNode of keysOrNodesOrEntries) {
if (keyOrNode instanceof TreeMultimapNode) {
inserted.push(this.add(keyOrNode.key, keyOrNode.value, keyOrNode.count));
inserted.push(this.add(keyOrNode, keyOrNode.count));
continue;
}
if (keyOrNode === undefined) {
inserted.push(this.add(NaN, undefined, 0));
if (keyOrNode === undefined || keyOrNode === null) {
inserted.push(this.add(NaN, 0));
continue;
}
inserted.push(this.add(keyOrNode, data?.[i], 1));
inserted.push(this.add(keyOrNode, 1));
}
return inserted;
}
@ -234,7 +240,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
if (l > r) return;
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
this.add(midNode.key, midNode.value, midNode.count);
this.add([midNode.key, midNode.value], midNode.count);
buildBalanceBST(l, m - 1);
buildBalanceBST(m + 1, r);
};
@ -250,7 +256,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
if (l <= r) {
const m = l + Math.floor((r - l) / 2);
const midNode = sorted[m];
this.add(midNode.key, midNode.value, midNode.count);
this.add([midNode.key, midNode.value], midNode.count);
stack.push([m + 1, r]);
stack.push([l, m - 1]);
}
@ -357,24 +363,6 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
this._count = 0;
}
/**
* Time Complexity: O(log n) - logarithmic time, where "n" is the number of nodes in the tree. The delete method of the superclass (AVLTree) has logarithmic time complexity.
* Space Complexity: O(1) - constant space, as it doesn't use additional data structures that scale with input size.
*/
init(elements: Iterable<BTNExemplar<V, N>>): void {
if (elements) {
for (const entryOrKey of elements) {
if (Array.isArray(entryOrKey)) {
const [key, value] = entryOrKey;
this.add(key, value);
} else {
this.add(entryOrKey);
}
}
}
}
/**
* Time Complexity: O(1) - constant time, as it performs basic pointer assignments.
* Space Complexity: O(1) - constant space, as it only uses a constant amount of memory.
@ -390,7 +378,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
* @returns The method `_addTo` returns either the `parent.left` or `parent.right` node that was
* added, or `undefined` if no node was added.
*/
protected override _addTo(newNode: N | undefined, parent: BSTNKeyOrNode<N>): N | undefined {
protected override _addTo(newNode: N | undefined, parent: BSTNodeKeyOrNode<N>): N | undefined {
parent = this.ensureNotKey(parent);
if (parent) {
if (parent.left === undefined) {
@ -425,7 +413,7 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
* @returns either the `destNode` object if both `srcNode` and `destNode` are defined, or `undefined`
* if either `srcNode` or `destNode` is undefined.
*/
protected _swap(srcNode: BSTNKeyOrNode<N>, destNode: BSTNKeyOrNode<N>): N | undefined {
protected _swap(srcNode: BSTNodeKeyOrNode<N>, destNode: BSTNodeKeyOrNode<N>): N | undefined {
srcNode = this.ensureNotKey(srcNode);
destNode = this.ensureNotKey(destNode);
if (srcNode && destNode) {

View file

@ -5,7 +5,7 @@ import {
BinaryTreeOptions,
BiTreeDeleteResult,
BTNCallback,
BTNExemplar,
BTNodeExemplar,
BTNKey,
} from '../types';
@ -14,9 +14,9 @@ export interface IBinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTre
createTree(options?: Partial<BinaryTreeOptions>): TREE;
init(elements: Iterable<BTNExemplar<V, N>>): void;
add(keyOrNodeOrEntry: BTNodeExemplar<V, N>, count?: number): N | null | undefined;
add(keyOrNode: BTNKey | N | null, value?: N['value']): N | null | undefined;
addMany(nodes: Iterable<BTNodeExemplar<V, N>>): (N | null | undefined)[];
delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null, callback: C): BiTreeDeleteResult<N>[];
}

View file

@ -24,8 +24,14 @@ export type IterableWithSizeOrLength<T> = IterableWithSize<T> | IterableWithLeng
export type BinaryTreePrintOptions = { isShowUndefined?: boolean, isShowNull?: boolean, isShowRedBlackNIL?: boolean }
export type BTNExemplar<T, N> = [BTNKey | null | undefined, T | undefined] | BTNKeyOrNode<N>
export type BTNodeEntry<T> = [BTNKey | null | undefined, T | undefined];
export type BTNKeyOrNode<N> = BTNKey | null | undefined | N;
export type BTNodeKeyOrNode<N> = BTNKey | null | undefined | N;
export type BSTNKeyOrNode<N> = BTNKey | undefined | N;
export type BTNodeExemplar<T, N> = BTNodeEntry<T> | BTNodeKeyOrNode<N>
export type BTNodePureExemplar<T, N> = [BTNKey, T | undefined] | BTNodePureKeyOrNode<N>
export type BTNodePureKeyOrNode<N> = BTNKey | N;
export type BSTNodeKeyOrNode<N> = BTNKey | undefined | N;

View file

@ -34,7 +34,7 @@ suite
})
.add(`MJS PQ ${TEN_THOUSAND.toLocaleString()} add`, () => {
const pq = new MJSPriorityQueue<number>([],{ comparator: (a, b) => b - a });
const pq = new MJSPriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
});
@ -54,13 +54,13 @@ suite
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
})
.add(`CJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
const pq = new CJSPriorityQueue<number>([],{ comparator: (a, b) => b - a });
const pq = new CJSPriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();
})
.add(`MJS PQ ${TEN_THOUSAND.toLocaleString()} add & pop`, () => {
const pq = new MJSPriorityQueue<number>([],{ comparator: (a, b) => b - a });
const pq = new MJSPriorityQueue<number>([], { comparator: (a, b) => b - a });
for (let i = 0; i < TEN_THOUSAND; i++) pq.add(i);
for (let i = 0; i < TEN_THOUSAND; i++) pq.pop();

View file

@ -5,7 +5,7 @@ describe('AVL Tree Test', () => {
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
const tree = new AVLTree<number>();
for (const i of arr) tree.add(i, i);
for (const i of arr) tree.add([i, i]);
tree.add(null);
const node6 = tree.getNode(6);
@ -114,7 +114,7 @@ describe('AVL Tree Test recursively', () => {
const arr = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
const tree = new AVLTree<number>([], { iterationType: IterationType.RECURSIVE });
for (const i of arr) tree.add(i, i);
for (const i of arr) tree.add([i, i]);
const node6 = tree.getNode(6);
@ -230,7 +230,7 @@ describe('AVLTree APIs test', () => {
avl.add(node2);
const node3 = new AVLTreeNode(3, { id: 3, text: 'text3' });
avl.add(node3);
avl.add(node3, { id: 3, text: 'text33' });
avl.add([3, { id: 3, text: 'text33' }]);
const bfsRes = avl.bfs(node => node.key);
expect(bfsRes[0]).toBe(2);
@ -240,26 +240,26 @@ describe('AVLTree APIs test', () => {
describe('AVLTree', () => {
it('should balance the tree using _balanceLR when nodes are added', () => {
const avlTree = new AVLTree();
avlTree.add(10, 'A');
avlTree.add(5, 'B');
avlTree.add(15, 'C');
avlTree.add(3, 'D');
avlTree.add(7, 'E');
avlTree.add([10, 'A']);
avlTree.add([5, 'B']);
avlTree.add([15, 'C']);
avlTree.add([3, 'D']);
avlTree.add([7, 'E']);
// Adding nodes to trigger _balanceLR
avlTree.add(12, 'F');
avlTree.add([12, 'F']);
// You can add more specific assertions to check the tree's balance and structure.
});
it('should balance the tree using _balanceLR when nodes are deleted', () => {
const avlTree = new AVLTree();
avlTree.add(10, 'A');
avlTree.add(5, 'B');
avlTree.add(15, 'C');
avlTree.add(3, 'D');
avlTree.add(7, 'E');
avlTree.add(12, 'F');
avlTree.add([10, 'A']);
avlTree.add([5, 'B']);
avlTree.add([15, 'C']);
avlTree.add([3, 'D']);
avlTree.add([7, 'E']);
avlTree.add([12, 'F']);
// Deleting nodes to trigger _balanceLR
avlTree.delete(3);
@ -279,7 +279,7 @@ describe('AVLTree', () => {
avl.add(node2);
const node3 = new AVLTreeNode(3, { id: 3, text: 'text3' });
avl.add(node3);
avl.add(node3, { id: 3, text: 'text33' });
avl.add([3, { id: 3, text: 'text33' }]);
const bfsRes = avl.bfs(node => node);
expect(bfsRes[0]?.key).toBe(2);
@ -291,9 +291,9 @@ describe('AVLTree iterative methods test', () => {
let avl: AVLTree<string>;
beforeEach(() => {
avl = new AVLTree();
avl.add(1, 'a');
avl.add(2, 'b');
avl.add(3, 'c');
avl.add([1, 'a']);
avl.add([2, 'b']);
avl.add([3, 'c']);
});
test('The node obtained by get Node should match the node type', () => {

View file

@ -1,6 +1,5 @@
import { BinaryTree, BinaryTreeNode, IterationType } from '../../../../src';
import { BinaryTree, BinaryTreeNode, FamilyPosition, IterationType } from '../../../../src';
import { getRandomIntArray } from '../../../utils';
import { FamilyPosition } from 'binary-tree-typed';
// import {isDebugTest} from '../../../config';
// const isDebug = isDebugTest;
@ -137,10 +136,10 @@ describe('BinaryTree', () => {
});
it('should add and find nodes', () => {
tree.add(1, 1);
tree.add([1, 1]);
tree.add(undefined);
tree.add(2, 2);
tree.add(3, 3);
tree.add([2, 2]);
tree.add([3, 3]);
expect(tree.has(1)).toBe(true);
expect(tree.has(2)).toBe(true);
@ -395,9 +394,9 @@ describe('BinaryTree', () => {
});
it('should add nodes to the tree', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
expect(tree.size).toBe(3);
expect(tree.isEmpty()).toBe(false);
@ -405,9 +404,9 @@ describe('BinaryTree', () => {
});
it('should clear the BinaryTree', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
tree.clear();
@ -417,9 +416,9 @@ describe('BinaryTree', () => {
});
it('should get nodes by key', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
const nodeA = tree.getNode(5);
const nodeB = tree.getNode(3);
@ -431,7 +430,7 @@ describe('BinaryTree', () => {
});
it('should return null when getting a non-existent node', () => {
tree.add(5, 'A');
tree.add([5, 'A']);
const node = tree.getNode(3);
@ -439,18 +438,18 @@ describe('BinaryTree', () => {
});
it('should get the depth of a node', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
expect(tree.getDepth(7)).toBe(1);
expect(tree.getDepth(3)).toBe(1);
});
it('should get the height of the tree', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
expect(tree.getHeight()).toBe(1);
expect(tree.getHeight(undefined, IterationType.RECURSIVE)).toBe(1);
@ -458,17 +457,17 @@ describe('BinaryTree', () => {
});
it('should check if the tree is a binary search tree', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
expect(tree.isBST()).toBe(true);
});
it('should perform a depth-first traversal', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
const result = tree.dfs();
expect(result).toEqual([3, 5, 7]);
@ -476,9 +475,9 @@ describe('BinaryTree', () => {
});
it('should perform a breadth-first traversal', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
const result = tree.bfs(node => node.key);
expect(result).toEqual([5, 3, 7]);
@ -486,9 +485,9 @@ describe('BinaryTree', () => {
});
it('should list levels of the tree', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
const levels = tree.listLevels();
expect(levels).toEqual([[5], [3, 7]]);
@ -496,9 +495,9 @@ describe('BinaryTree', () => {
});
it('should delete nodes from the tree', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
tree.delete(3);
@ -507,17 +506,17 @@ describe('BinaryTree', () => {
});
it('should check if the tree is perfectly balanced', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
expect(tree.isPerfectlyBalanced()).toBe(true);
});
it('should get nodes by a custom callback', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
const nodes = tree.getNodes('B', (node: BinaryTreeNode<string>) => node.value);
@ -537,9 +536,9 @@ describe('BinaryTree', () => {
});
it('should perform Morris traversal', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
tree.iterationType = IterationType.ITERATIVE;
expect([...tree]).toEqual([[3, "B"], [5, "A"], [7, "C"]]);
@ -553,9 +552,9 @@ describe('BinaryTree', () => {
});
it('should perform delete all', () => {
tree.add(5, 'A');
tree.add(3, 'B');
tree.add(7, 'C');
tree.add([5, 'A']);
tree.add([3, 'B']);
tree.add([7, 'C']);
tree.delete(5);
tree.delete(7);
@ -570,9 +569,9 @@ describe('BinaryTree iterative methods test', () => {
let binaryTree: BinaryTree<string>;
beforeEach(() => {
binaryTree = new BinaryTree();
binaryTree.add(1, 'a');
binaryTree.add(2, 'b');
binaryTree.add(3, 'c');
binaryTree.add([1, 'a']);
binaryTree.add([2, 'b']);
binaryTree.add([3, 'c']);
});
test('The node obtained by get Node should match the node type', () => {

View file

@ -7,10 +7,10 @@ describe('BST operations test', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {
const bst = new BST();
expect(bst).toBeInstanceOf(BST);
bst.add(11, 11);
bst.add(3, 3);
const idsAndValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
bst.addMany(idsAndValues, idsAndValues, false);
bst.add([11, 11]);
bst.add([3, 3]);
const idsAndValues: [number, number][] = [[15, 15], [1, 1], [8, 8], [13, 13], [16, 16], [2, 2], [6, 6], [9, 9], [12, 12], [14, 14], [4, 4], [7, 7], [10, 10], [5, 5]];
bst.addMany(idsAndValues, false);
expect(bst.root).toBeInstanceOf(BSTNode);
if (bst.root) expect(bst.root.key).toBe(11);
@ -191,30 +191,26 @@ describe('BST operations test', () => {
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<{ key: number; keyA: number }>();
expect(objBST).toBeInstanceOf(BST);
objBST.add(11, { key: 11, keyA: 11 });
objBST.add(3, { key: 3, keyA: 3 });
const values = [
{ key: 15, keyA: 15 },
{ key: 1, keyA: 1 },
{ key: 8, keyA: 8 },
{ key: 13, keyA: 13 },
{ key: 16, keyA: 16 },
{ key: 2, keyA: 2 },
{ key: 6, keyA: 6 },
{ key: 9, keyA: 9 },
{ key: 12, keyA: 12 },
{ key: 14, keyA: 14 },
{ key: 4, keyA: 4 },
{ key: 7, keyA: 7 },
{ key: 10, keyA: 10 },
{ key: 5, keyA: 5 }
objBST.add([11, { key: 11, keyA: 11 }]);
objBST.add([3, { key: 3, keyA: 3 }]);
const values: [number, { key: number; keyA: number }][] = [
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
[13, { key: 13, keyA: 13 }],
[16, { key: 16, keyA: 16 }],
[2, { key: 2, keyA: 2 }],
[6, { key: 6, keyA: 6 }],
[9, { key: 9, keyA: 9 }],
[12, { key: 12, keyA: 12 }],
[14, { key: 14, keyA: 14 }],
[4, { key: 4, keyA: 4 }],
[7, { key: 7, keyA: 7 }],
[10, { key: 10, keyA: 10 }],
[5, { key: 5, keyA: 5 }]
];
objBST.addMany(
values.map(item => item.key),
values,
false
);
objBST.addMany(values, false);
expect(objBST.root).toBeInstanceOf(BSTNode);
@ -395,12 +391,12 @@ describe('BST operations test', () => {
describe('BST operations test recursively', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {
const bst = new BST([], { iterationType: IterationType.RECURSIVE });
const bst = new BST<number>([], { iterationType: IterationType.RECURSIVE });
expect(bst).toBeInstanceOf(BST);
bst.add(11, 11);
bst.add(3, 3);
bst.add([11, 11]);
bst.add([3, 3]);
const idsAndValues = [15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
bst.addMany(idsAndValues, idsAndValues, false);
bst.addMany(idsAndValues, false);
expect(bst.root).toBeInstanceOf(BSTNode);
if (bst.root) expect(bst.root.key).toBe(11);
@ -414,11 +410,11 @@ describe('BST operations test recursively', () => {
expect(node6 && bst.getDepth(6)).toBe(3);
const nodeId10 = bst.getNode(10);
expect(bst.get(10)).toBe(10);
expect(bst.get(10)).toBe(undefined);
expect(nodeId10?.key).toBe(10);
const nodeVal9 = bst.getNode(9, node => node.value);
expect(nodeVal9?.key).toBe(9);
expect(nodeVal9?.key).toBe(undefined);
const leftMost = bst.getLeftMost();
expect(leftMost?.key).toBe(1);
@ -582,27 +578,26 @@ describe('BST operations test recursively', () => {
it('should perform various operations on a Binary Search Tree with object values', () => {
const objBST = new BST<{ key: number; keyA: number }>();
expect(objBST).toBeInstanceOf(BST);
objBST.add(11, { key: 11, keyA: 11 });
objBST.add(3, { key: 3, keyA: 3 });
const values = [
{ key: 15, keyA: 15 },
{ key: 1, keyA: 1 },
{ key: 8, keyA: 8 },
{ key: 13, keyA: 13 },
{ key: 16, keyA: 16 },
{ key: 2, keyA: 2 },
{ key: 6, keyA: 6 },
{ key: 9, keyA: 9 },
{ key: 12, keyA: 12 },
{ key: 14, keyA: 14 },
{ key: 4, keyA: 4 },
{ key: 7, keyA: 7 },
{ key: 10, keyA: 10 },
{ key: 5, keyA: 5 }
objBST.add([11, { key: 11, keyA: 11 }]);
objBST.add([3, { key: 3, keyA: 3 }]);
const values: [number, { key: number; keyA: number }][] = [
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
[13, { key: 13, keyA: 13 }],
[16, { key: 16, keyA: 16 }],
[2, { key: 2, keyA: 2 }],
[6, { key: 6, keyA: 6 }],
[9, { key: 9, keyA: 9 }],
[12, { key: 12, keyA: 12 }],
[14, { key: 14, keyA: 14 }],
[4, { key: 4, keyA: 4 }],
[7, { key: 7, keyA: 7 }],
[10, { key: 10, keyA: 10 }],
[5, { key: 5, keyA: 5 }]
];
objBST.addMany(
values.map(item => item.key),
values,
false
);
@ -834,7 +829,7 @@ describe('BST Performance test', function () {
it('should the lastKey of a BST to be the largest key', function () {
const bst = new BST();
bst.addMany([9, 8, 7, 3, 1, 2, 5, 4, 6], undefined, false);
bst.addMany([9, 8, 7, 3, 1, 2, 5, 4, 6], false);
expect(bst.lastKey()).toBe(9);
});
@ -856,9 +851,9 @@ describe('BST iterative methods test', () => {
let bst: BST<string>;
beforeEach(() => {
bst = new BST();
bst.add(1, 'a');
bst.add(2, 'b');
bst.add(3, 'c');
bst.add([1, 'a']);
bst.add([2, 'b']);
bst.add([3, 'c']);
});
test('The node obtained by get Node should match the node type', () => {

View file

@ -5,7 +5,7 @@ describe('Overall BinaryTree Test', () => {
const bst = new BST();
bst.add(11);
bst.add(3);
bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], undefined, false);
bst.addMany([15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5], false);
bst.size === 16; // true
expect(bst.size).toBe(16); // true
bst.has(6); // true
@ -30,26 +30,25 @@ describe('Overall BinaryTree Test', () => {
expect(bfsIDs[0]).toBe(11);
const objBST = new BST<{ key: number; keyA: number }>();
objBST.add(11, { key: 11, keyA: 11 });
objBST.add(3, { key: 3, keyA: 3 });
objBST.add([11, { key: 11, keyA: 11 }]);
objBST.add([3, { key: 3, keyA: 3 }]);
objBST.addMany(
[15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5],
[
{ key: 15, keyA: 15 },
{ key: 1, keyA: 1 },
{ key: 8, keyA: 8 },
{ key: 13, keyA: 13 },
{ key: 16, keyA: 16 },
{ key: 2, keyA: 2 },
{ key: 6, keyA: 6 },
{ key: 9, keyA: 9 },
{ key: 12, keyA: 12 },
{ key: 14, keyA: 14 },
{ key: 4, keyA: 4 },
{ key: 7, keyA: 7 },
{ key: 10, keyA: 10 },
{ key: 5, keyA: 5 }
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
[13, { key: 13, keyA: 13 }],
[16, { key: 16, keyA: 16 }],
[2, { key: 2, keyA: 2 }],
[6, { key: 6, keyA: 6 }],
[9, { key: 9, keyA: 9 }],
[12, { key: 12, keyA: 12 }],
[14, { key: 14, keyA: 14 }],
[4, { key: 4, keyA: 4 }],
[7, { key: 7, keyA: 7 }],
[10, { key: 10, keyA: 10 }],
[5, { key: 5, keyA: 5 }]
]
);

View file

@ -510,9 +510,9 @@ describe('RedBlackTree iterative methods test', () => {
let rbTree: RedBlackTree<string>;
beforeEach(() => {
rbTree = new RedBlackTree();
rbTree.add(1, 'a');
rbTree.add(2, 'b');
rbTree.add(3, 'c');
rbTree.add([1, 'a']);
rbTree.add([2, 'b']);
rbTree.add([3, 'c']);
});
test('The node obtained by get Node should match the node type', () => {

View file

@ -3,6 +3,16 @@ import { isDebugTest } from '../../../config';
const isDebug = isDebugTest;
describe('TreeMultimap count', () => {
const tm = new TreeMultimap<number>();
it('Should count', () => {
tm.addMany([[1, 1], [2, 2], [3, 3]]);
tm.lesserOrGreaterTraverse(node => node.count += 2, CP.gt, 1);
expect(tm.count).toBe(7)
})
})
describe('TreeMultimap operations test', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {
const treeMultimap = new TreeMultimap();
@ -10,8 +20,25 @@ describe('TreeMultimap operations test', () => {
expect(treeMultimap instanceof TreeMultimap);
treeMultimap.add(11, 11);
treeMultimap.add(3, 3);
const idAndValues = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
treeMultimap.addMany(idAndValues, idAndValues);
const idAndValues: [number, number][] = [
[11, 11],
[3, 3],
[15, 15],
[1, 1],
[8, 8],
[13, 13],
[16, 16],
[2, 2],
[6, 6],
[9, 9],
[12, 12],
[14, 14],
[4, 4],
[7, 7],
[10, 10],
[5, 5]
];
treeMultimap.addMany(idAndValues);
expect(treeMultimap.root instanceof TreeMultimapNode);
if (treeMultimap.root) expect(treeMultimap.root.key == 11);
@ -209,27 +236,26 @@ describe('TreeMultimap operations test', () => {
it('should perform various operations on a Binary Search Tree with object values', () => {
const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
objTreeMultimap.add(11, { key: 11, keyA: 11 });
objTreeMultimap.add(3, { key: 3, keyA: 3 });
const values = [
{ key: 15, keyA: 15 },
{ key: 1, keyA: 1 },
{ key: 8, keyA: 8 },
{ key: 13, keyA: 13 },
{ key: 16, keyA: 16 },
{ key: 2, keyA: 2 },
{ key: 6, keyA: 6 },
{ key: 9, keyA: 9 },
{ key: 12, keyA: 12 },
{ key: 14, keyA: 14 },
{ key: 4, keyA: 4 },
{ key: 7, keyA: 7 },
{ key: 10, keyA: 10 },
{ key: 5, keyA: 5 }
objTreeMultimap.add([11, { key: 11, keyA: 11 }]);
objTreeMultimap.add([3, { key: 3, keyA: 3 }]);
const values: [number, { key: number, keyA: number }][] = [
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
[13, { key: 13, keyA: 13 }],
[16, { key: 16, keyA: 16 }],
[2, { key: 2, keyA: 2 }],
[6, { key: 6, keyA: 6 }],
[9, { key: 9, keyA: 9 }],
[12, { key: 12, keyA: 12 }],
[14, { key: 14, keyA: 14 }],
[4, { key: 4, keyA: 4 }],
[7, { key: 7, keyA: 7 }],
[10, { key: 10, keyA: 10 }],
[5, { key: 5, keyA: 5 }]
];
objTreeMultimap.addMany(
values.map(item => item.key),
values
);
@ -245,14 +271,31 @@ describe('TreeMultimap operations test', () => {
describe('TreeMultimap operations test recursively', () => {
it('should perform various operations on a Binary Search Tree with numeric values', () => {
const treeMultimap = new TreeMultimap([], { iterationType: IterationType.RECURSIVE });
const treeMultimap = new TreeMultimap<number>([], { iterationType: IterationType.RECURSIVE });
expect(treeMultimap instanceof TreeMultimap);
treeMultimap.add(11, 11);
treeMultimap.add(3, 3);
const idAndValues = [11, 3, 15, 1, 8, 13, 16, 2, 6, 9, 12, 14, 4, 7, 10, 5];
treeMultimap.addMany(idAndValues, idAndValues);
expect(treeMultimap.root instanceof TreeMultimapNode);
const idAndValues: [number, number][] = [
[11, 11],
[3, 3],
[15, 15],
[1, 1],
[8, 8],
[13, 13],
[16, 16],
[2, 2],
[6, 6],
[9, 9],
[12, 12],
[14, 14],
[4, 4],
[7, 7],
[10, 10],
[5, 5]
];
treeMultimap.addMany(idAndValues);
expect(treeMultimap.root).toBeInstanceOf(TreeMultimapNode);
if (treeMultimap.root) expect(treeMultimap.root.key == 11);
@ -449,27 +492,26 @@ describe('TreeMultimap operations test recursively', () => {
it('should perform various operations on a Binary Search Tree with object values', () => {
const objTreeMultimap = new TreeMultimap<{ key: number; keyA: number }>();
expect(objTreeMultimap).toBeInstanceOf(TreeMultimap);
objTreeMultimap.add(11, { key: 11, keyA: 11 });
objTreeMultimap.add(3, { key: 3, keyA: 3 });
const values = [
{ key: 15, keyA: 15 },
{ key: 1, keyA: 1 },
{ key: 8, keyA: 8 },
{ key: 13, keyA: 13 },
{ key: 16, keyA: 16 },
{ key: 2, keyA: 2 },
{ key: 6, keyA: 6 },
{ key: 9, keyA: 9 },
{ key: 12, keyA: 12 },
{ key: 14, keyA: 14 },
{ key: 4, keyA: 4 },
{ key: 7, keyA: 7 },
{ key: 10, keyA: 10 },
{ key: 5, keyA: 5 }
objTreeMultimap.add([11, { key: 11, keyA: 11 }]);
objTreeMultimap.add([3, { key: 3, keyA: 3 }]);
const values: [number, { key: number; keyA: number }][] = [
[15, { key: 15, keyA: 15 }],
[1, { key: 1, keyA: 1 }],
[8, { key: 8, keyA: 8 }],
[13, { key: 13, keyA: 13 }],
[16, { key: 16, keyA: 16 }],
[2, { key: 2, keyA: 2 }],
[6, { key: 6, keyA: 6 }],
[9, { key: 9, keyA: 9 }],
[12, { key: 12, keyA: 12 }],
[14, { key: 14, keyA: 14 }],
[4, { key: 4, keyA: 4 }],
[7, { key: 7, keyA: 7 }],
[10, { key: 10, keyA: 10 }],
[5, { key: 5, keyA: 5 }]
];
objTreeMultimap.addMany(
values.map(item => item.key),
values
);