mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 04:44:04 +00:00
refactor: To standardize the _dfs method of the BinaryTree to achieve full generalization.
This commit is contained in:
parent
e271f73de0
commit
5a492c1801
26
README.md
26
README.md
|
@ -823,43 +823,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>7.60</td><td>131.64</td><td>2.41e-4</td></tr><tr><td>100,000 add & poll</td><td>44.04</td><td>22.71</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>7.49</td><td>133.43</td><td>2.10e-4</td></tr><tr><td>100,000 add & poll</td><td>44.08</td><td>22.69</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'>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>77.11</td><td>12.97</td><td>0.00</td></tr><tr><td>100,000 add randomly</td><td>81.38</td><td>12.29</td><td>0.00</td></tr><tr><td>100,000 get</td><td>112.22</td><td>8.91</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>28.64</td><td>34.91</td><td>0.00</td></tr><tr><td>100,000 add & delete orderly</td><td>158.80</td><td>6.30</td><td>0.02</td></tr><tr><td>100,000 add & delete randomly</td><td>230.07</td><td>4.35</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>79.16</td><td>12.63</td><td>0.00</td></tr><tr><td>100,000 add randomly</td><td>84.35</td><td>11.85</td><td>0.00</td></tr><tr><td>100,000 get</td><td>111.74</td><td>8.95</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>26.61</td><td>37.58</td><td>0.00</td></tr><tr><td>100,000 add & delete orderly</td><td>160.05</td><td>6.25</td><td>0.02</td></tr><tr><td>100,000 add & delete randomly</td><td>234.55</td><td>4.26</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>42.26</td><td>23.67</td><td>0.01</td></tr><tr><td>100,000 push & shift</td><td>5.07</td><td>197.32</td><td>5.97e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2252.79</td><td>0.44</td><td>0.17</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.70</td><td>24.57</td><td>0.01</td></tr><tr><td>100,000 push & shift</td><td>5.15</td><td>194.25</td><td>6.57e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2143.37</td><td>0.47</td><td>0.15</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>23.30</td><td>42.92</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>31.90</td><td>31.34</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>32.70</td><td>30.58</td><td>0.00</td></tr><tr><td>100,000 push & shift</td><td>3.40</td><td>293.73</td><td>2.64e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2225.02</td><td>0.45</td><td>0.08</td></tr><tr><td>100,000 unshift & shift</td><td>3.34</td><td>299.68</td><td>2.48e-4</td></tr><tr><td>Native JS Array 100,000 unshift & shift</td><td>3993.22</td><td>0.25</td><td>0.13</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>24.74</td><td>40.43</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>31.38</td><td>31.87</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>32.12</td><td>31.13</td><td>0.00</td></tr><tr><td>100,000 push & shift</td><td>3.39</td><td>295.24</td><td>3.62e-4</td></tr><tr><td>Native JS Array 100,000 push & shift</td><td>2348.52</td><td>0.43</td><td>0.21</td></tr><tr><td>100,000 unshift & shift</td><td>3.28</td><td>304.60</td><td>2.76e-4</td></tr><tr><td>Native JS Array 100,000 unshift & shift</td><td>4062.43</td><td>0.25</td><td>0.12</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>106.42</td><td>9.40</td><td>0.01</td></tr><tr><td>Native JS Map 1,000,000 set</td><td>204.68</td><td>4.89</td><td>0.01</td></tr><tr><td>Native JS Set 1,000,000 add</td><td>166.12</td><td>6.02</td><td>0.01</td></tr><tr><td>1,000,000 set & get</td><td>118.98</td><td>8.40</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set & get</td><td>265.16</td><td>3.77</td><td>0.01</td></tr><tr><td>Native JS Set 1,000,000 add & has</td><td>169.18</td><td>5.91</td><td>0.01</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>315.90</td><td>3.17</td><td>0.03</td></tr><tr><td>Native JS Map 1,000,000 ObjKey set & get</td><td>291.11</td><td>3.44</td><td>0.03</td></tr><tr><td>Native JS Set 1,000,000 ObjKey add & has</td><td>272.99</td><td>3.66</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>106.65</td><td>9.38</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set</td><td>201.70</td><td>4.96</td><td>0.01</td></tr><tr><td>Native JS Set 1,000,000 add</td><td>163.55</td><td>6.11</td><td>0.01</td></tr><tr><td>1,000,000 set & get</td><td>115.56</td><td>8.65</td><td>0.02</td></tr><tr><td>Native JS Map 1,000,000 set & get</td><td>264.29</td><td>3.78</td><td>0.01</td></tr><tr><td>Native JS Set 1,000,000 add & has</td><td>171.96</td><td>5.82</td><td>0.01</td></tr><tr><td>1,000,000 ObjKey set & get</td><td>326.27</td><td>3.06</td><td>0.05</td></tr><tr><td>Native JS Map 1,000,000 ObjKey set & get</td><td>322.17</td><td>3.10</td><td>0.06</td></tr><tr><td>Native JS Set 1,000,000 ObjKey add & has</td><td>241.34</td><td>4.14</td><td>0.03</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>44.81</td><td>22.31</td><td>0.00</td></tr><tr><td>100,000 getWords</td><td>83.75</td><td>11.94</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>44.21</td><td>22.62</td><td>0.00</td></tr><tr><td>100,000 getWords</td><td>85.22</td><td>11.73</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>270.91</td><td>3.69</td><td>0.02</td></tr><tr><td>100,000 add randomly</td><td>344.71</td><td>2.90</td><td>0.00</td></tr><tr><td>100,000 get</td><td>128.80</td><td>7.76</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>32.88</td><td>30.41</td><td>0.01</td></tr><tr><td>100,000 add & delete orderly</td><td>456.46</td><td>2.19</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>604.25</td><td>1.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</td><td>269.92</td><td>3.70</td><td>0.01</td></tr><tr><td>100,000 add randomly</td><td>317.13</td><td>3.15</td><td>0.00</td></tr><tr><td>100,000 get</td><td>127.74</td><td>7.83</td><td>0.00</td></tr><tr><td>100,000 iterator</td><td>29.99</td><td>33.34</td><td>0.01</td></tr><tr><td>100,000 add & delete orderly</td><td>431.27</td><td>2.32</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>580.91</td><td>1.72</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'>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>6.64</td><td>150.66</td><td>8.06e-5</td></tr><tr><td>10,000 RBTree get randomly</td><td>9.24</td><td>108.23</td><td>1.40e-4</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>18.25</td><td>54.79</td><td>2.59e-4</td></tr><tr><td>10,000 AVLTree add randomly</td><td>23.57</td><td>42.43</td><td>1.78e-4</td></tr><tr><td>10,000 AVLTree get randomly</td><td>9.69</td><td>103.21</td><td>8.94e-5</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>44.37</td><td>22.54</td><td>4.23e-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>6.73</td><td>148.59</td><td>1.04e-4</td></tr><tr><td>10,000 RBTree get randomly</td><td>9.48</td><td>105.50</td><td>1.07e-4</td></tr><tr><td>10,000 RBTree add & delete randomly</td><td>18.40</td><td>54.33</td><td>2.70e-4</td></tr><tr><td>10,000 AVLTree add randomly</td><td>23.57</td><td>42.43</td><td>1.73e-4</td></tr><tr><td>10,000 AVLTree get randomly</td><td>9.70</td><td>103.06</td><td>7.92e-5</td></tr><tr><td>10,000 AVLTree add & delete randomly</td><td>44.43</td><td>22.51</td><td>3.33e-4</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>9718.49</td><td>1.33e-6</td></tr><tr><td>1,000 addEdge</td><td>6.28</td><td>159.34</td><td>1.59e-4</td></tr><tr><td>1,000 getVertex</td><td>0.04</td><td>2.57e+4</td><td>5.33e-7</td></tr><tr><td>1,000 getEdge</td><td>22.43</td><td>44.58</td><td>0.00</td></tr><tr><td>tarjan</td><td>200.86</td><td>4.98</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>176.95</td><td>5.65</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>9723.27</td><td>2.46e-6</td></tr><tr><td>1,000 addEdge</td><td>6.26</td><td>159.78</td><td>7.28e-4</td></tr><tr><td>1,000 getVertex</td><td>0.04</td><td>2.54e+4</td><td>4.17e-7</td></tr><tr><td>1,000 getEdge</td><td>22.64</td><td>44.16</td><td>0.00</td></tr><tr><td>tarjan</td><td>200.14</td><td>5.00</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>175.91</td><td>5.68</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>205.86</td><td>4.86</td><td>0.07</td></tr><tr><td>1,000,000 unshift</td><td>199.96</td><td>5.00</td><td>0.03</td></tr><tr><td>1,000,000 unshift & shift</td><td>180.94</td><td>5.53</td><td>0.02</td></tr><tr><td>1,000,000 addBefore</td><td>308.98</td><td>3.24</td><td>0.10</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>196.17</td><td>5.10</td><td>0.03</td></tr><tr><td>1,000,000 unshift</td><td>203.73</td><td>4.91</td><td>0.04</td></tr><tr><td>1,000,000 unshift & shift</td><td>186.32</td><td>5.37</td><td>0.04</td></tr><tr><td>1,000,000 addBefore</td><td>298.35</td><td>3.35</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>1,000,000 push & shift</td><td>206.48</td><td>4.84</td><td>0.09</td></tr><tr><td>10,000 push & pop</td><td>224.13</td><td>4.46</td><td>0.01</td></tr><tr><td>10,000 addBefore</td><td>246.92</td><td>4.05</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 & shift</td><td>210.62</td><td>4.75</td><td>0.09</td></tr><tr><td>10,000 push & pop</td><td>226.02</td><td>4.42</td><td>0.02</td></tr><tr><td>10,000 addBefore</td><td>249.35</td><td>4.01</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>27.02</td><td>37.01</td><td>2.69e-4</td></tr><tr><td>100,000 add & poll</td><td>75.97</td><td>13.16</td><td>5.61e-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>27.23</td><td>36.72</td><td>7.64e-4</td></tr><tr><td>100,000 add & poll</td><td>76.66</td><td>13.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'>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>38.52</td><td>25.96</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>46.95</td><td>21.30</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>37.10</td><td>26.96</td><td>0.00</td></tr><tr><td>1,000,000 push & pop</td><td>44.72</td><td>22.36</td><td>0.01</td></tr></table></div>
|
||||
</div>
|
||||
|
||||
[//]: # (No deletion!!! End of Replace Section)
|
||||
|
|
|
@ -22,12 +22,12 @@ import type {
|
|||
NodeDisplayLayout,
|
||||
OptBTNOrNull
|
||||
} from '../../types';
|
||||
import { DFSOperation, DFSStackItem } from '../../types';
|
||||
import { IBinaryTree } from '../../interfaces';
|
||||
import { trampoline } from '../../utils';
|
||||
import { Queue } from '../queue';
|
||||
import { IterableEntryBase } from '../base';
|
||||
import * as console from 'console';
|
||||
import { DFSOperation, DFSStackItem } from '../../types';
|
||||
|
||||
/**
|
||||
* Represents a node in a binary tree.
|
||||
|
@ -340,7 +340,7 @@ export class BinaryTree<
|
|||
* `BTNKeyOrNodeOrEntry<K, V, NODE>`.
|
||||
* @returns a boolean value.
|
||||
*/
|
||||
isNodeOrNull(node: R | BTNKeyOrNodeOrEntry<K, V, NODE>): node is NODE | null {
|
||||
isRealNodeOrNull(node: R | BTNKeyOrNodeOrEntry<K, V, NODE>): node is NODE | null {
|
||||
return this.isRealNode(node) || node === null;
|
||||
}
|
||||
|
||||
|
@ -1487,8 +1487,8 @@ export class BinaryTree<
|
|||
ans.push(callback(current));
|
||||
|
||||
if (includeNull) {
|
||||
if (current && this.isNodeOrNull(current.left)) queue.push(current.left);
|
||||
if (current && this.isNodeOrNull(current.right)) queue.push(current.right);
|
||||
if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);
|
||||
if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);
|
||||
} else {
|
||||
if (this.isRealNode(current.left)) queue.push(current.left);
|
||||
if (this.isRealNode(current.right)) queue.push(current.right);
|
||||
|
@ -1508,8 +1508,8 @@ export class BinaryTree<
|
|||
ans.push(callback(current));
|
||||
|
||||
if (includeNull) {
|
||||
if (current && this.isNodeOrNull(current.left)) queue.push(current.left);
|
||||
if (current && this.isNodeOrNull(current.right)) queue.push(current.right);
|
||||
if (current && this.isRealNodeOrNull(current.left)) queue.push(current.left);
|
||||
if (current && this.isRealNodeOrNull(current.right)) queue.push(current.right);
|
||||
} else {
|
||||
if (this.isRealNode(current.left)) queue.push(current.left);
|
||||
if (this.isRealNode(current.right)) queue.push(current.right);
|
||||
|
@ -1637,8 +1637,8 @@ export class BinaryTree<
|
|||
if (!levelsNodes[level]) levelsNodes[level] = [];
|
||||
levelsNodes[level].push(callback(node));
|
||||
if (includeNull) {
|
||||
if (node && this.isNodeOrNull(node.left)) _recursive(node.left, level + 1);
|
||||
if (node && this.isNodeOrNull(node.right)) _recursive(node.right, level + 1);
|
||||
if (node && this.isRealNodeOrNull(node.left)) _recursive(node.left, level + 1);
|
||||
if (node && this.isRealNodeOrNull(node.right)) _recursive(node.right, level + 1);
|
||||
} else {
|
||||
if (node && node.left) _recursive(node.left, level + 1);
|
||||
if (node && node.right) _recursive(node.right, level + 1);
|
||||
|
@ -1657,8 +1657,8 @@ export class BinaryTree<
|
|||
levelsNodes[level].push(callback(node));
|
||||
|
||||
if (includeNull) {
|
||||
if (node && this.isNodeOrNull(node.right)) stack.push([node.right, level + 1]);
|
||||
if (node && this.isNodeOrNull(node.left)) stack.push([node.left, level + 1]);
|
||||
if (node && this.isRealNodeOrNull(node.right)) stack.push([node.right, level + 1]);
|
||||
if (node && this.isRealNodeOrNull(node.left)) stack.push([node.left, level + 1]);
|
||||
} else {
|
||||
if (node && node.right) stack.push([node.right, level + 1]);
|
||||
if (node && node.left) stack.push([node.left, level + 1]);
|
||||
|
@ -1945,83 +1945,89 @@ export class BinaryTree<
|
|||
* Time complexity: O(n)
|
||||
* Space complexity: O(n)
|
||||
*
|
||||
* The `dfs` function performs a depth-first search traversal on a binary tree, executing a callback
|
||||
* function on each node according to a specified pattern and iteration type.
|
||||
* @param {C} callback - The `callback` parameter is a function that will be called for each node
|
||||
* visited during the depth-first search. It takes a node as an argument and returns a value. The
|
||||
* return type of the callback function is determined by the generic type `C`.
|
||||
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter determines the order in which the
|
||||
* nodes are visited during the depth-first search. It can have one of the following values:
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter is the starting
|
||||
* point of the depth-first search. It can be either a node object, a key-value pair, or a key. If it
|
||||
* is a key or key-value pair, the method will find the corresponding node in the tree and start the
|
||||
* search from there.
|
||||
* @param {IterationType} [iterationType=ITERATIVE] - The `iterationType` parameter determines the
|
||||
* type of iteration to use during the depth-first search. It can have two possible values:
|
||||
* @param [includeNull=false] - The `includeNull` parameter is a boolean value that determines
|
||||
* whether or not to include null values in the depth-first search traversal. If `includeNull` is set
|
||||
* to `true`, null values will be included in the traversal. If `includeNull` is set to `false`, null
|
||||
* values will
|
||||
* @returns an array of the return types of the callback function.
|
||||
* The function `_dfs` performs a depth-first search traversal on a binary tree structure based on
|
||||
* the specified order pattern and callback function.
|
||||
* @param {C} callback - The `callback` parameter is a function that will be called on each node
|
||||
* visited during the depth-first search. It is of type `C`, which extends
|
||||
* `BTNCallback<OptBTNOrNull<NODE>>`. The default value is set to `this._DEFAULT_CALLBACK` if not
|
||||
* provided.
|
||||
* @param {DFSOrderPattern} [pattern=IN] - The `pattern` parameter in the `_dfs` method specifies the
|
||||
* order in which the Depth-First Search (DFS) algorithm should traverse the nodes in a binary tree.
|
||||
* It can have one of the following values:
|
||||
* @param {R | BTNKeyOrNodeOrEntry<K, V, NODE>} beginRoot - The `beginRoot` parameter in the `_dfs`
|
||||
* method is used to specify the starting point for the depth-first search traversal in a binary
|
||||
* tree. It can be provided as either the root node of the tree or a key, node, or entry that exists
|
||||
* in the tree. If no specific `
|
||||
* @param {IterationType} iterationType - The `iterationType` parameter in the `_dfs` method
|
||||
* specifies the type of iteration to be performed during the Depth-First Search (DFS) traversal. It
|
||||
* can have two possible values:
|
||||
* @param [includeNull=false] - The `includeNull` parameter in the `_dfs` method is a boolean flag
|
||||
* that determines whether null nodes should be included in the depth-first search traversal. If
|
||||
* `includeNull` is set to `true`, the traversal will consider null nodes as valid nodes to visit and
|
||||
* process. If set to `
|
||||
* @param shouldVisitLeft - The `shouldVisitLeft` parameter is a function that takes a node as input
|
||||
* and returns a boolean value. It is used to determine whether the left child of a node should be
|
||||
* visited during the depth-first search traversal. By default, it checks if the node is truthy (not
|
||||
* null or undefined
|
||||
* @param shouldVisitRight - The `shouldVisitRight` parameter is a function that takes a node as
|
||||
* input and returns a boolean value. It is used to determine whether the right child of a node
|
||||
* should be visited during the depth-first search traversal. The default implementation checks if
|
||||
* the node is truthy before visiting the right child.
|
||||
* @param shouldVisitRoot - The `shouldVisitRoot` parameter is a function that takes a node as an
|
||||
* argument and returns a boolean value. It is used to determine whether a given node should be
|
||||
* visited during the depth-first search traversal based on certain conditions. The default
|
||||
* implementation checks if the node is a real node or null based
|
||||
* @param shouldProcessRoot - The `shouldProcessRoot` parameter is a function that takes a node as
|
||||
* input and returns a boolean value indicating whether the node should be processed during the
|
||||
* depth-first search traversal. The default implementation of this function simply returns `true`,
|
||||
* meaning that by default all nodes will be processed. However, you can
|
||||
* @returns The `_dfs` method returns an array of the return type of the callback function provided
|
||||
* as input.
|
||||
*/
|
||||
protected _dfs<C extends BTNCallback<OptBTNOrNull<NODE>>>(
|
||||
callback: C = this._DEFAULT_CALLBACK as C,
|
||||
pattern: DFSOrderPattern = 'IN',
|
||||
beginRoot: R | BTNKeyOrNodeOrEntry<K, V, NODE> = this.root,
|
||||
iterationType: IterationType = this.iterationType,
|
||||
includeNull = false
|
||||
includeNull = false,
|
||||
shouldVisitLeft: (node: OptBTNOrNull<NODE>) => boolean = node => !!node,
|
||||
shouldVisitRight: (node: OptBTNOrNull<NODE>) => boolean = node => !!node,
|
||||
shouldVisitRoot: (node: OptBTNOrNull<NODE>) => boolean = node => {
|
||||
if (includeNull) return this.isRealNodeOrNull(node);
|
||||
return this.isRealNode(node);
|
||||
},
|
||||
shouldProcessRoot: (node: OptBTNOrNull<NODE>) => boolean = node => true
|
||||
): ReturnType<C>[] {
|
||||
beginRoot = this.ensureNode(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
const ans: ReturnType<C>[] = [];
|
||||
if (iterationType === 'RECURSIVE') {
|
||||
const visitNullableLeft = (node: OptBTNOrNull<NODE>) => {
|
||||
if (node && this.isNodeOrNull(node.left)) dfs(node.left);
|
||||
};
|
||||
const visitLeft = (node: OptBTNOrNull<NODE>) => {
|
||||
if (node && this.isRealNode(node.left)) dfs(node.left);
|
||||
};
|
||||
const visitNullableRight = (node: OptBTNOrNull<NODE>) => {
|
||||
if (node && this.isNodeOrNull(node.right)) dfs(node.right);
|
||||
};
|
||||
const visitRight = (node: OptBTNOrNull<NODE>) => {
|
||||
if (node && this.isRealNode(node.right)) dfs(node.right);
|
||||
};
|
||||
|
||||
if (iterationType === 'RECURSIVE') {
|
||||
const dfs = (node: OptBTNOrNull<NODE>) => {
|
||||
if (!shouldVisitRoot(node)) return;
|
||||
|
||||
const visitLeft = () => {
|
||||
if (shouldVisitLeft(node)) dfs(node?.left);
|
||||
};
|
||||
const visitRight = () => {
|
||||
if (shouldVisitRight(node)) dfs(node?.right);
|
||||
};
|
||||
|
||||
switch (pattern) {
|
||||
case 'IN':
|
||||
if (includeNull) {
|
||||
visitNullableLeft(node);
|
||||
ans.push(callback(node));
|
||||
visitNullableRight(node);
|
||||
} else {
|
||||
visitLeft(node);
|
||||
ans.push(callback(node));
|
||||
visitRight(node);
|
||||
}
|
||||
visitLeft();
|
||||
if (shouldProcessRoot(node)) ans.push(callback(node));
|
||||
visitRight();
|
||||
break;
|
||||
case 'PRE':
|
||||
if (includeNull) {
|
||||
ans.push(callback(node));
|
||||
visitNullableLeft(node);
|
||||
visitNullableRight(node);
|
||||
} else {
|
||||
ans.push(callback(node));
|
||||
visitLeft(node);
|
||||
visitRight(node);
|
||||
}
|
||||
if (shouldProcessRoot(node)) ans.push(callback(node));
|
||||
visitLeft();
|
||||
visitRight();
|
||||
break;
|
||||
case 'POST':
|
||||
if (includeNull) {
|
||||
visitNullableLeft(node);
|
||||
visitNullableRight(node);
|
||||
ans.push(callback(node));
|
||||
} else {
|
||||
visitLeft(node);
|
||||
visitRight(node);
|
||||
ans.push(callback(node));
|
||||
}
|
||||
visitLeft();
|
||||
visitRight();
|
||||
if (shouldProcessRoot(node)) ans.push(callback(node));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
@ -2029,47 +2035,40 @@ export class BinaryTree<
|
|||
dfs(beginRoot);
|
||||
} else {
|
||||
const stack: DFSStackItem<NODE>[] = [{ opt: DFSOperation.VISIT, node: beginRoot }];
|
||||
|
||||
const pushLeft = (cur: DFSStackItem<NODE>) => {
|
||||
cur.node && stack.push({ opt: DFSOperation.VISIT, node: cur.node.left });
|
||||
if (shouldVisitLeft(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.left });
|
||||
};
|
||||
const pushRight = (cur: DFSStackItem<NODE>) => {
|
||||
cur.node && stack.push({ opt: DFSOperation.VISIT, node: cur.node.right });
|
||||
if (shouldVisitRight(cur.node)) stack.push({ opt: DFSOperation.VISIT, node: cur.node?.right });
|
||||
};
|
||||
const pushParent = (cur: DFSStackItem<NODE>) => {
|
||||
stack.push({ opt: DFSOperation.PROCESS, node: cur.node });
|
||||
const pushRoot = (cur: DFSStackItem<NODE>) => {
|
||||
if (shouldVisitRoot(cur.node)) stack.push({ opt: DFSOperation.PROCESS, node: cur.node });
|
||||
};
|
||||
|
||||
while (stack.length > 0) {
|
||||
const cur = stack.pop();
|
||||
if (cur === undefined) continue;
|
||||
if (includeNull) {
|
||||
if (!this.isNodeOrNull(cur.node)) continue;
|
||||
} else {
|
||||
if (!this.isRealNode(cur.node)) continue;
|
||||
}
|
||||
if (cur.opt === 1) {
|
||||
ans.push(callback(cur.node));
|
||||
if (!shouldVisitRoot(cur.node)) continue;
|
||||
if (cur.opt === DFSOperation.PROCESS) {
|
||||
if (shouldProcessRoot(cur.node)) ans.push(callback(cur.node));
|
||||
} else {
|
||||
switch (pattern) {
|
||||
case 'IN':
|
||||
pushRight(cur);
|
||||
pushParent(cur);
|
||||
pushRoot(cur);
|
||||
pushLeft(cur);
|
||||
break;
|
||||
case 'PRE':
|
||||
pushRight(cur);
|
||||
pushLeft(cur);
|
||||
pushParent(cur);
|
||||
pushRoot(cur);
|
||||
break;
|
||||
case 'POST':
|
||||
pushParent(cur);
|
||||
pushRoot(cur);
|
||||
pushRight(cur);
|
||||
pushLeft(cur);
|
||||
break;
|
||||
default:
|
||||
pushRight(cur);
|
||||
pushParent(cur);
|
||||
pushLeft(cur);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue