mirror of
https://github.com/zrwusa/data-structure-typed.git
synced 2024-11-23 12:54:04 +00:00
perf: Unified all APIs, all parameters that accept node types can also accept node keys as parameters.
This commit is contained in:
parent
8971dbb605
commit
28207b6d45
|
@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file.
|
|||
- [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
|
||||
- [`auto-changelog`](https://github.com/CookPete/auto-changelog)
|
||||
|
||||
## [v1.42.5](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
|
||||
## [v1.42.6](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming)
|
||||
|
||||
### Changes
|
||||
|
||||
|
|
244
README.md
244
README.md
|
@ -25,108 +25,6 @@ Now you can use this library in Node.js and browser environments in CommonJS(req
|
|||
[//]: # (![Lines](https://img.shields.io/badge/lines-68.6%25-red.svg?style=flat))
|
||||
|
||||
|
||||
## Built-in classic algorithms
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Algorithm</th>
|
||||
<th>Function Description</th>
|
||||
<th>Iteration Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Binary Tree DFS</td>
|
||||
<td>Traverse a binary tree in a depth-first manner, starting from the root node, first visiting the left subtree,
|
||||
and then the right subtree, using recursion.
|
||||
</td>
|
||||
<td>Recursion + Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Binary Tree BFS</td>
|
||||
<td>Traverse a binary tree in a breadth-first manner, starting from the root node, visiting nodes level by level
|
||||
from left to right.
|
||||
</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph DFS</td>
|
||||
<td>Traverse a graph in a depth-first manner, starting from a given node, exploring along one path as deeply as
|
||||
possible, and backtracking to explore other paths. Used for finding connected components, paths, etc.
|
||||
</td>
|
||||
<td>Recursion + Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Binary Tree Morris</td>
|
||||
<td>Morris traversal is an in-order traversal algorithm for binary trees with O(1) space complexity. It allows tree
|
||||
traversal without additional stack or recursion.
|
||||
</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph BFS</td>
|
||||
<td>Traverse a graph in a breadth-first manner, starting from a given node, first visiting nodes directly connected
|
||||
to the starting node, and then expanding level by level. Used for finding shortest paths, etc.
|
||||
</td>
|
||||
<td>Recursion + Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Tarjan's Algorithm</td>
|
||||
<td>Find strongly connected components in a graph, typically implemented using depth-first search.</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Bellman-Ford Algorithm</td>
|
||||
<td>Finding the shortest paths from a single source, can handle negative weight edges</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Dijkstra's Algorithm</td>
|
||||
<td>Finding the shortest paths from a single source, cannot handle negative weight edges</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Floyd-Warshall Algorithm</td>
|
||||
<td>Finding the shortest paths between all pairs of nodes</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getCycles</td>
|
||||
<td>Find all cycles in a graph or detect the presence of cycles.</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getCutVertexes</td>
|
||||
<td>Find cut vertices in a graph, which are nodes that, when removed, increase the number of connected components in
|
||||
the graph.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getSCCs</td>
|
||||
<td>Find strongly connected components in a graph, which are subgraphs where any two nodes can reach each other.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getBridges</td>
|
||||
<td>Find bridges in a graph, which are edges that, when removed, increase the number of connected components in the
|
||||
graph.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph topologicalSort</td>
|
||||
<td>Perform topological sorting on a directed acyclic graph (DAG) to find a linear order of nodes such that all
|
||||
directed edges go from earlier nodes to later nodes.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## Installation and Usage
|
||||
|
||||
### npm
|
||||
|
@ -174,13 +72,6 @@ const {
|
|||
![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/directed-graph-test.webp)
|
||||
![](https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/examples/videos/webp_output/map-graph-test.webp)
|
||||
|
||||
## API docs & Examples
|
||||
|
||||
[API Docs](https://data-structure-typed-docs.vercel.app)
|
||||
|
||||
[Live Examples](https://vivid-algorithm.vercel.app)
|
||||
|
||||
<a href="https://github.com/zrwusa/vivid-algorithm" target="_blank">Examples Repository</a>
|
||||
|
||||
## Code Snippets
|
||||
|
||||
|
@ -338,6 +229,115 @@ const dijkstraResult = graph.dijkstra('A');
|
|||
Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.key) // ['A', 'B', 'D']
|
||||
```
|
||||
|
||||
## Built-in classic algorithms
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Algorithm</th>
|
||||
<th>Function Description</th>
|
||||
<th>Iteration Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Binary Tree DFS</td>
|
||||
<td>Traverse a binary tree in a depth-first manner, starting from the root node, first visiting the left subtree,
|
||||
and then the right subtree, using recursion.
|
||||
</td>
|
||||
<td>Recursion + Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Binary Tree BFS</td>
|
||||
<td>Traverse a binary tree in a breadth-first manner, starting from the root node, visiting nodes level by level
|
||||
from left to right.
|
||||
</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph DFS</td>
|
||||
<td>Traverse a graph in a depth-first manner, starting from a given node, exploring along one path as deeply as
|
||||
possible, and backtracking to explore other paths. Used for finding connected components, paths, etc.
|
||||
</td>
|
||||
<td>Recursion + Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Binary Tree Morris</td>
|
||||
<td>Morris traversal is an in-order traversal algorithm for binary trees with O(1) space complexity. It allows tree
|
||||
traversal without additional stack or recursion.
|
||||
</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph BFS</td>
|
||||
<td>Traverse a graph in a breadth-first manner, starting from a given node, first visiting nodes directly connected
|
||||
to the starting node, and then expanding level by level. Used for finding shortest paths, etc.
|
||||
</td>
|
||||
<td>Recursion + Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Tarjan's Algorithm</td>
|
||||
<td>Find strongly connected components in a graph, typically implemented using depth-first search.</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Bellman-Ford Algorithm</td>
|
||||
<td>Finding the shortest paths from a single source, can handle negative weight edges</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Dijkstra's Algorithm</td>
|
||||
<td>Finding the shortest paths from a single source, cannot handle negative weight edges</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph Floyd-Warshall Algorithm</td>
|
||||
<td>Finding the shortest paths between all pairs of nodes</td>
|
||||
<td>Iteration</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getCycles</td>
|
||||
<td>Find all cycles in a graph or detect the presence of cycles.</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getCutVertexes</td>
|
||||
<td>Find cut vertices in a graph, which are nodes that, when removed, increase the number of connected components in
|
||||
the graph.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getSCCs</td>
|
||||
<td>Find strongly connected components in a graph, which are subgraphs where any two nodes can reach each other.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph getBridges</td>
|
||||
<td>Find bridges in a graph, which are edges that, when removed, increase the number of connected components in the
|
||||
graph.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Graph topologicalSort</td>
|
||||
<td>Perform topological sorting on a directed acyclic graph (DAG) to find a linear order of nodes such that all
|
||||
directed edges go from earlier nodes to later nodes.
|
||||
</td>
|
||||
<td>Recursion</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
## API docs & Examples
|
||||
|
||||
[API Docs](https://data-structure-typed-docs.vercel.app)
|
||||
|
||||
[Live Examples](https://vivid-algorithm.vercel.app)
|
||||
|
||||
<a href="https://github.com/zrwusa/vivid-algorithm" target="_blank">Examples Repository</a>
|
||||
|
||||
## Data Structures
|
||||
|
||||
<table>
|
||||
|
@ -376,7 +376,7 @@ Array.from(dijkstraResult?.seen ?? []).map(vertex => vertex.key) // ['A', 'B', '
|
|||
<td>Red Black Tree</td>
|
||||
<td><img src="https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/assets/tick.svg" alt=""></td>
|
||||
<td><img src="https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/assets/tick.svg" alt=""></td>
|
||||
<td><a href="https://data-structure-typed-docs.vercel.app/classes/RedBlackTree.html"><span>AVLTree</span></a></td>
|
||||
<td><a href="https://data-structure-typed-docs.vercel.app/classes/RedBlackTree.html"><span>RedBlackTree</span></a></td>
|
||||
<td><img src="https://raw.githubusercontent.com/zrwusa/assets/master/images/data-structure-typed/assets/tick.svg" alt=""></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -728,40 +728,40 @@ optimal approach to data structure design.
|
|||
[//]: # (No deletion!!! Start of Replace Section)
|
||||
<div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>avl-tree</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>30.52</td><td>32.76</td><td>3.28e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>66.96</td><td>14.94</td><td>0.00</td></tr><tr><td>10,000 addMany</td><td>39.78</td><td>25.14</td><td>3.67e-4</td></tr><tr><td>10,000 get</td><td>27.38</td><td>36.52</td><td>0.00</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add randomly</td><td>31.95</td><td>31.30</td><td>2.69e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>69.18</td><td>14.45</td><td>8.01e-4</td></tr><tr><td>10,000 addMany</td><td>41.62</td><td>24.03</td><td>2.25e-4</td></tr><tr><td>10,000 get</td><td>27.67</td><td>36.13</td><td>1.96e-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>10.50</td><td>95.20</td><td>2.30e-4</td></tr><tr><td>1,000 add & delete randomly</td><td>16.18</td><td>61.81</td><td>2.48e-4</td></tr><tr><td>1,000 addMany</td><td>10.80</td><td>92.62</td><td>1.83e-4</td></tr><tr><td>1,000 get</td><td>18.03</td><td>55.45</td><td>1.41e-4</td></tr><tr><td>1,000 dfs</td><td>157.86</td><td>6.33</td><td>0.00</td></tr><tr><td>1,000 bfs</td><td>56.68</td><td>17.64</td><td>0.00</td></tr><tr><td>1,000 morris</td><td>37.21</td><td>26.88</td><td>2.79e-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>12.29</td><td>81.38</td><td>9.60e-5</td></tr><tr><td>1,000 add & delete randomly</td><td>15.60</td><td>64.11</td><td>1.04e-4</td></tr><tr><td>1,000 addMany</td><td>10.30</td><td>97.04</td><td>9.16e-5</td></tr><tr><td>1,000 get</td><td>18.02</td><td>55.50</td><td>2.21e-4</td></tr><tr><td>1,000 dfs</td><td>175.42</td><td>5.70</td><td>0.00</td></tr><tr><td>1,000 bfs</td><td>55.71</td><td>17.95</td><td>2.56e-4</td></tr><tr><td>1,000 morris</td><td>38.29</td><td>26.11</td><td>2.10e-4</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>27.61</td><td>36.21</td><td>4.73e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>62.93</td><td>15.89</td><td>5.86e-4</td></tr><tr><td>10,000 addMany</td><td>28.70</td><td>34.84</td><td>0.00</td></tr><tr><td>10,000 get</td><td>27.67</td><td>36.14</td><td>2.92e-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>30.55</td><td>32.73</td><td>2.83e-4</td></tr><tr><td>10,000 add & delete randomly</td><td>69.22</td><td>14.45</td><td>7.57e-4</td></tr><tr><td>10,000 addMany</td><td>29.52</td><td>33.88</td><td>3.69e-4</td></tr><tr><td>10,000 get</td><td>28.71</td><td>34.83</td><td>2.69e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>rb-tree</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>100,000 add randomly</td><td>87.51</td><td>11.43</td><td>0.01</td></tr><tr><td>100,000 add & delete randomly</td><td>189.06</td><td>5.29</td><td>0.01</td></tr><tr><td>100,000 getNode</td><td>35.33</td><td>28.31</td><td>8.93e-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 randomly</td><td>85.63</td><td>11.68</td><td>0.00</td></tr><tr><td>100,000 add & delete randomly</td><td>181.31</td><td>5.52</td><td>0.01</td></tr><tr><td>100,000 getNode</td><td>91.77</td><td>10.90</td><td>5.02e-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>9899.91</td><td>8.58e-7</td></tr><tr><td>1,000 addEdge</td><td>6.06</td><td>165.02</td><td>1.68e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.17e+4</td><td>4.22e-7</td></tr><tr><td>1,000 getEdge</td><td>23.05</td><td>43.38</td><td>0.00</td></tr><tr><td>tarjan</td><td>222.59</td><td>4.49</td><td>0.01</td></tr><tr><td>tarjan all</td><td>226.89</td><td>4.41</td><td>0.01</td></tr><tr><td>topologicalSort</td><td>187.34</td><td>5.34</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>9889.32</td><td>1.21e-6</td></tr><tr><td>1,000 addEdge</td><td>5.97</td><td>167.63</td><td>1.09e-4</td></tr><tr><td>1,000 getVertex</td><td>0.05</td><td>2.17e+4</td><td>4.36e-7</td></tr><tr><td>1,000 getEdge</td><td>23.73</td><td>42.14</td><td>0.00</td></tr><tr><td>tarjan</td><td>225.10</td><td>4.44</td><td>0.01</td></tr><tr><td>tarjan all</td><td>233.47</td><td>4.28</td><td>0.02</td></tr><tr><td>topologicalSort</td><td>183.96</td><td>5.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'>heap</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 add & pop</td><td>4.66</td><td>214.54</td><td>9.38e-5</td></tr><tr><td>10,000 fib add & pop</td><td>364.30</td><td>2.74</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 add & pop</td><td>4.61</td><td>216.99</td><td>4.19e-5</td></tr><tr><td>10,000 fib add & pop</td><td>354.79</td><td>2.82</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'>doubly-linked-list</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 unshift</td><td>243.61</td><td>4.10</td><td>0.07</td></tr><tr><td>1,000,000 unshift & shift</td><td>173.32</td><td>5.77</td><td>0.03</td></tr><tr><td>1,000,000 insertBefore</td><td>315.86</td><td>3.17</td><td>0.04</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 unshift</td><td>210.07</td><td>4.76</td><td>0.03</td></tr><tr><td>1,000,000 unshift & shift</td><td>174.44</td><td>5.73</td><td>0.04</td></tr><tr><td>1,000,000 insertBefore</td><td>355.36</td><td>2.81</td><td>0.10</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>228.06</td><td>4.38</td><td>0.03</td></tr><tr><td>10,000 insertBefore</td><td>252.07</td><td>3.97</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>220.47</td><td>4.54</td><td>0.01</td></tr><tr><td>10,000 insertBefore</td><td>252.59</td><td>3.96</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'>max-priority-queue</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>11.53</td><td>86.71</td><td>2.27e-4</td></tr></table></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>10,000 refill & poll</td><td>11.72</td><td>85.32</td><td>2.97e-4</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>deque</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>227.24</td><td>4.40</td><td>0.07</td></tr><tr><td>1,000,000 shift</td><td>25.60</td><td>39.07</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>233.90</td><td>4.28</td><td>0.07</td></tr><tr><td>1,000,000 shift</td><td>25.40</td><td>39.37</td><td>0.00</td></tr></table></div>
|
||||
</div><div class="json-to-html-collapse clearfix 0">
|
||||
<div class='collapsible level0' ><span class='json-to-html-label'>queue</span></div>
|
||||
<div class="content"><table style="display: table; width:100%; table-layout: fixed;"><tr><th>test name</th><th>time taken (ms)</th><th>executions per sec</th><th>sample deviation</th></tr><tr><td>1,000,000 push</td><td>45.98</td><td>21.75</td><td>0.01</td></tr><tr><td>1,000,000 push & shift</td><td>81.12</td><td>12.33</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>43.54</td><td>22.97</td><td>0.00</td></tr><tr><td>1,000,000 push & shift</td><td>83.99</td><td>11.91</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>59.40</td><td>16.83</td><td>0.01</td></tr><tr><td>100,000 getWords</td><td>90.07</td><td>11.10</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>49.17</td><td>20.34</td><td>0.01</td></tr><tr><td>100,000 getWords</td><td>88.84</td><td>11.26</td><td>0.01</td></tr></table></div>
|
||||
</div>
|
||||
|
||||
[//]: # (No deletion!!! End of Replace Section)
|
|
@ -6,7 +6,7 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
import {BST, BSTNode} from './bst';
|
||||
import type {AVLTreeNodeNested, AVLTreeOptions, BinaryTreeDeletedResult, BTNKey} from '../../types';
|
||||
import type {AVLTreeNodeNested, AVLTreeOptions, BiTreeDeleteResult, BTNKey} from '../../types';
|
||||
import {BTNCallback} from '../../types';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
|
||||
|
@ -72,12 +72,12 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
* value. This value is compared with the `identifier` parameter to determine if the node should be
|
||||
* included in the result. The `callback` parameter has a default value of
|
||||
* `this.defaultOneParamCallback`
|
||||
* @returns The method is returning an array of `BinaryTreeDeletedResult<N>` objects.
|
||||
* @returns The method is returning an array of `BiTreeDeleteResult<N>` objects.
|
||||
*/
|
||||
override delete<C extends BTNCallback<N>>(
|
||||
identifier: ReturnType<C>,
|
||||
callback: C = this.defaultOneParamCallback as C
|
||||
): BinaryTreeDeletedResult<N>[] {
|
||||
): BiTreeDeleteResult<N>[] {
|
||||
if ((identifier as any) instanceof AVLTreeNode) callback = (node => node) as C;
|
||||
const deletedResults = super.delete(identifier, callback);
|
||||
for (const {needBalanced} of deletedResults) {
|
||||
|
@ -96,23 +96,29 @@ export class AVLTree<V = any, N extends AVLTreeNode<V, N> = AVLTreeNode<V, AVLTr
|
|||
* from the source node (`srcNode`) will be swapped to.
|
||||
* @returns The method is returning the `destNode` after swapping its properties with the `srcNode`.
|
||||
*/
|
||||
protected override _swap(srcNode: N, destNode: N): N {
|
||||
const {key, value, height} = destNode;
|
||||
const tempNode = this.createNode(key, value);
|
||||
protected override _swap(srcNode: BTNKey | N | undefined, destNode: BTNKey | N | undefined): N | undefined {
|
||||
if (this.isNodeKey(srcNode)) srcNode = this._getNodeByKey(srcNode);
|
||||
if (this.isNodeKey(destNode)) destNode = this._getNodeByKey(destNode);
|
||||
|
||||
if (tempNode) {
|
||||
tempNode.height = height;
|
||||
if (srcNode && destNode) {
|
||||
const {key, value, height} = destNode;
|
||||
const tempNode = this.createNode(key, value);
|
||||
|
||||
destNode.key = srcNode.key;
|
||||
destNode.value = srcNode.value;
|
||||
destNode.height = srcNode.height;
|
||||
if (tempNode) {
|
||||
tempNode.height = height;
|
||||
|
||||
srcNode.key = tempNode.key;
|
||||
srcNode.value = tempNode.value;
|
||||
srcNode.height = tempNode.height;
|
||||
destNode.key = srcNode.key;
|
||||
destNode.value = srcNode.value;
|
||||
destNode.height = srcNode.height;
|
||||
|
||||
srcNode.key = tempNode.key;
|
||||
srcNode.value = tempNode.value;
|
||||
srcNode.height = tempNode.height;
|
||||
}
|
||||
|
||||
return destNode;
|
||||
}
|
||||
|
||||
return destNode;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import type {BinaryTreeNodeNested, BinaryTreeOptions, BTNCallback, BTNKey} from '../../types';
|
||||
import {BinaryTreeDeletedResult, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
|
||||
import {BiTreeDeleteResult, CP, DFSOrderPattern, FamilyPosition, IterationType} from '../../types';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {trampoline} from '../../utils';
|
||||
import {Queue} from '../queue';
|
||||
|
@ -117,7 +117,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @param {BinaryTreeOptions} [options] - The options for the binary tree.
|
||||
*/
|
||||
constructor(options?: BinaryTreeOptions) {
|
||||
if (options !== undefined) {
|
||||
if (options) {
|
||||
const {iterationType = IterationType.ITERATIVE} = options;
|
||||
this.iterationType = iterationType;
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return;
|
||||
};
|
||||
|
||||
let inserted: N | null | undefined, needInsert: N | null;
|
||||
let inserted: N | null | undefined, needInsert: N | null | undefined;
|
||||
|
||||
if (keyOrNode === null) {
|
||||
needInsert = null;
|
||||
|
@ -204,19 +204,11 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return;
|
||||
}
|
||||
|
||||
// const key = typeof keyOrNode === 'number' ? keyOrNode : keyOrNode ? keyOrNode.key : undefined;
|
||||
// const existNode = key !== undefined ? this.getNode(key, (node: N) => node.key) : undefined;
|
||||
|
||||
if (this.root) {
|
||||
// if (existNode) {
|
||||
// existNode.value = value;
|
||||
// inserted = existNode;
|
||||
// } else {
|
||||
inserted = _bfs(this.root, needInsert);
|
||||
// }
|
||||
} else {
|
||||
this._setRoot(needInsert);
|
||||
if (needInsert !== null) {
|
||||
if (needInsert) {
|
||||
this._size = 1;
|
||||
} else {
|
||||
this._size = 0;
|
||||
|
@ -236,7 +228,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* the value of the nodes will be `undefined`.
|
||||
* @returns The function `addMany` returns an array of `N`, `null`, or `undefined` values.
|
||||
*/
|
||||
addMany(keysOrNodes: (BTNKey | null | undefined)[] | (N | null | undefined)[], values?: V[]): (N | null | undefined)[] {
|
||||
addMany(keysOrNodes: (BTNKey | N |null | undefined)[], values?: (V | undefined)[]): (N | null | undefined)[] {
|
||||
// TODO not sure addMany not be run multi times
|
||||
return keysOrNodes.map((keyOrNode, i) => {
|
||||
if (keyOrNode instanceof BinaryTreeNode) {
|
||||
|
@ -256,28 +248,28 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* The `refill` function clears the binary tree and adds multiple nodes with the given IDs or nodes and optional data.
|
||||
* @param {(BTNKey | N)[]} keysOrNodes - The `keysOrNodes` parameter is an array that can contain either
|
||||
* `BTNKey` or `N` values.
|
||||
* @param {N[] | Array<V>} [data] - The `data` parameter is an optional array of values that will be assigned to
|
||||
* @param {N[] | Array<V>} [values] - The `data` parameter is an optional array of values that will be assigned to
|
||||
* the nodes being added. If provided, the length of the `data` array should be equal to the length of the `keysOrNodes`
|
||||
* array. Each value in the `data` array will be assigned to the
|
||||
* @returns The method is returning a boolean value.
|
||||
*/
|
||||
refill(keysOrNodes: (BTNKey | null | undefined)[] | (N | null | undefined)[], data?: Array<V>): boolean {
|
||||
refill(keysOrNodes: (BTNKey | null | undefined)[] | (N | null | undefined)[], values?: Array<V | undefined>): boolean {
|
||||
this.clear();
|
||||
return keysOrNodes.length === this.addMany(keysOrNodes, data).length;
|
||||
return keysOrNodes.length === this.addMany(keysOrNodes, values).length;
|
||||
}
|
||||
|
||||
delete<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C): BinaryTreeDeletedResult<N>[];
|
||||
delete<C extends BTNCallback<N, BTNKey>>(identifier: BTNKey, callback?: C): BiTreeDeleteResult<N>[];
|
||||
|
||||
delete<C extends BTNCallback<N, N>>(identifier: N | null | undefined, callback?: C): BinaryTreeDeletedResult<N>[];
|
||||
delete<C extends BTNCallback<N, N>>(identifier: N | null | undefined, callback?: C): BiTreeDeleteResult<N>[];
|
||||
|
||||
delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BinaryTreeDeletedResult<N>[];
|
||||
delete<C extends BTNCallback<N>>(identifier: ReturnType<C>, callback: C): BiTreeDeleteResult<N>[];
|
||||
|
||||
/**
|
||||
* The `delete` function removes a node from a binary search tree and returns the deleted node along
|
||||
* with the parent node that needs to be balanced.
|
||||
* a key (`BTNKey`). If it is a key, the function will find the corresponding node in the
|
||||
* binary tree.
|
||||
* @returns an array of `BinaryTreeDeletedResult<N>` objects.
|
||||
* @returns an array of `BiTreeDeleteResult<N>` objects.
|
||||
* @param {ReturnType<C>} identifier - The `identifier` parameter is either a
|
||||
* `BTNKey` or a generic type `N`. It represents the property of the node that we are
|
||||
* searching for. It can be a specific key value or any other property of the node.
|
||||
|
@ -289,17 +281,17 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
delete<C extends BTNCallback<N>>(
|
||||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C = this.defaultOneParamCallback as C
|
||||
): BinaryTreeDeletedResult<N>[] {
|
||||
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
||||
if (!this.root) return bstDeletedResult;
|
||||
): BiTreeDeleteResult<N>[] {
|
||||
const deleteResult: BiTreeDeleteResult<N>[] = [];
|
||||
if (!this.root) return deleteResult;
|
||||
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
|
||||
const curr = this.getNode(identifier, callback);
|
||||
if (!curr) return bstDeletedResult;
|
||||
if (!curr) return deleteResult;
|
||||
|
||||
const parent: N | null | undefined = curr?.parent ? curr.parent : null;
|
||||
let needBalanced: N | null | undefined = null,
|
||||
orgCurrent = curr;
|
||||
let needBalanced: N | null | undefined = undefined;
|
||||
let orgCurrent: N | undefined = curr;
|
||||
|
||||
if (!curr.left) {
|
||||
if (!parent) {
|
||||
|
@ -329,8 +321,8 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
}
|
||||
this._size = this.size - 1;
|
||||
|
||||
bstDeletedResult.push({deleted: orgCurrent, needBalanced});
|
||||
return bstDeletedResult;
|
||||
deleteResult.push({deleted: orgCurrent, needBalanced});
|
||||
return deleteResult;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -347,7 +339,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
*/
|
||||
getDepth(distNode: BTNKey | N | null | undefined, beginRoot: BTNKey | N | null | undefined = this.root): number {
|
||||
if (typeof distNode === 'number') distNode = this.getNode(distNode);
|
||||
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
let depth = 0;
|
||||
while (distNode?.parent) {
|
||||
if (distNode === beginRoot) {
|
||||
|
@ -372,7 +364,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @returns the height of the binary tree.
|
||||
*/
|
||||
getHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
|
||||
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return -1;
|
||||
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
|
@ -420,9 +412,11 @@ 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: N | null | undefined = this.root, iterationType = this.iterationType): number {
|
||||
getMinHeight(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): number {
|
||||
if (!beginRoot) return -1;
|
||||
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return -1;
|
||||
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
const _getMinHeight = (cur: N | null | undefined): number => {
|
||||
if (!cur) return 0;
|
||||
|
@ -469,7 +463,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* either be of type `N` (representing a node in a tree) or `null` (representing an empty tree).
|
||||
* @returns The method is returning a boolean value.
|
||||
*/
|
||||
isPerfectlyBalanced(beginRoot: N | null | undefined = this.root): boolean {
|
||||
isPerfectlyBalanced(beginRoot: BTNKey | N | null | undefined = this.root): boolean {
|
||||
return this.getMinHeight(beginRoot) + 1 >= this.getHeight(beginRoot);
|
||||
}
|
||||
|
||||
|
@ -477,7 +471,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
identifier: BTNKey,
|
||||
callback?: C,
|
||||
onlyOne?: boolean,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): N[];
|
||||
|
||||
|
@ -485,7 +479,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
identifier: N | null | undefined,
|
||||
callback?: C,
|
||||
onlyOne?: boolean,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): N[];
|
||||
|
||||
|
@ -493,7 +487,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
identifier: ReturnType<C>,
|
||||
callback: C,
|
||||
onlyOne?: boolean,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): N[];
|
||||
|
||||
|
@ -522,11 +516,14 @@ 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: N | null | undefined = this.root,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): N[] {
|
||||
if (!beginRoot) return [];
|
||||
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
|
||||
const ans: N[] = [];
|
||||
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
|
@ -562,21 +559,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
has<C extends BTNCallback<N, BTNKey>>(
|
||||
identifier: BTNKey,
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): boolean;
|
||||
|
||||
has<C extends BTNCallback<N, N>>(
|
||||
identifier: N | null | undefined,
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): boolean;
|
||||
|
||||
has<C extends BTNCallback<N>>(
|
||||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): boolean;
|
||||
|
||||
|
@ -600,7 +597,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 = this.root,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): boolean {
|
||||
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
|
@ -611,21 +608,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
getNode<C extends BTNCallback<N, BTNKey>>(
|
||||
identifier: BTNKey,
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): N | null | undefined;
|
||||
|
||||
getNode<C extends BTNCallback<N, N>>(
|
||||
identifier: N | null | undefined,
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): N | null | undefined;
|
||||
|
||||
getNode<C extends BTNCallback<N>>(
|
||||
identifier: ReturnType<C>,
|
||||
callback: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): N | null | undefined;
|
||||
|
||||
|
@ -647,7 +644,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 = this.root,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): N | null | undefined {
|
||||
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
|
@ -655,24 +652,49 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return this.getNodes(identifier, callback, true, beginRoot, iterationType)[0] ?? null;
|
||||
}
|
||||
|
||||
protected _getNodeByKey(key: BTNKey, iterationType = IterationType.ITERATIVE): N | undefined {
|
||||
if (!this.root) return undefined;
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
const _dfs = (cur: N): N | undefined => {
|
||||
if (cur.key === key) return cur;
|
||||
|
||||
if (!cur.left && !cur.right) return;
|
||||
if (cur.left) return _dfs(cur.left);
|
||||
if (cur.right) return _dfs(cur.right);
|
||||
};
|
||||
|
||||
return _dfs(this.root);
|
||||
} else {
|
||||
const queue = new Queue<N>([this.root]);
|
||||
while (queue.size > 0) {
|
||||
const cur = queue.shift();
|
||||
if (cur) {
|
||||
if (cur.key === key) return cur;
|
||||
cur.left && queue.push(cur.left);
|
||||
cur.right && queue.push(cur.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get<C extends BTNCallback<N, BTNKey>>(
|
||||
identifier: BTNKey,
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): V | undefined;
|
||||
|
||||
get<C extends BTNCallback<N, N>>(
|
||||
identifier: N | null | undefined,
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): V | undefined;
|
||||
|
||||
get<C extends BTNCallback<N>>(
|
||||
identifier: ReturnType<C>,
|
||||
callback: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType
|
||||
): V | undefined;
|
||||
|
||||
|
@ -694,14 +716,14 @@ 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 = this.root,
|
||||
beginRoot:BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): V | undefined {
|
||||
if ((identifier as any) instanceof BinaryTreeNode) callback = (node => node) as C;
|
||||
|
||||
return this.getNode(identifier, callback, beginRoot, iterationType)?.value ?? undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The function `getPathToRoot` returns an array of nodes starting from a given node and traversing
|
||||
* up to the root node, with the option to reverse the order of the nodes.
|
||||
|
@ -712,9 +734,13 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* reversed before returning it. If `isReverse` is set to `false` or not provided, the path will
|
||||
* @returns The function `getPathToRoot` returns an array of type `N[]`.
|
||||
*/
|
||||
getPathToRoot(beginRoot: N, isReverse = true): N[] {
|
||||
getPathToRoot(beginRoot: BTNKey | N | null | undefined, isReverse = true): N[] {
|
||||
// TODO to support get path through passing key
|
||||
const result: N[] = [];
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
|
||||
if (!beginRoot) return result;
|
||||
|
||||
while (beginRoot.parent) {
|
||||
// Array.push + Array.reverse is more efficient than Array.unshift
|
||||
// TODO may consider using Deque, so far this is not the performance bottleneck
|
||||
|
@ -737,7 +763,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* no leftmost node, it returns `null`.
|
||||
*/
|
||||
getLeftMost(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
|
||||
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
|
||||
if (!beginRoot) return beginRoot;
|
||||
|
||||
|
@ -770,8 +796,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @returns The function `getRightMost` returns the rightmost node (`N`) in a binary tree. If the
|
||||
* `beginRoot` parameter is `null`, it returns `null`.
|
||||
*/
|
||||
getRightMost(beginRoot: N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
|
||||
getRightMost(beginRoot: BTNKey | N | null | undefined = this.root, iterationType = this.iterationType): N | null | undefined {
|
||||
// TODO support get right most by passing key in
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return beginRoot;
|
||||
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
|
@ -801,8 +828,9 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* possible values:
|
||||
* @returns The function `isSubtreeBST` returns a boolean value.
|
||||
*/
|
||||
isSubtreeBST(beginRoot: N | null | undefined, iterationType = this.iterationType): boolean {
|
||||
isSubtreeBST(beginRoot: BTNKey | N | null | undefined, iterationType = this.iterationType): boolean {
|
||||
// TODO there is a bug
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return true;
|
||||
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
|
@ -886,7 +914,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
iterationType = this.iterationType,
|
||||
includeNull = false
|
||||
): ReturnType<C>[] {
|
||||
if (typeof beginRoot === 'number') beginRoot = this.getNode(beginRoot);
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
|
||||
const ans: (ReturnType<BTNCallback<N>> | null | undefined)[] = [];
|
||||
if (!beginRoot) return ans;
|
||||
|
@ -938,10 +966,14 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return this.isNode(node) || node === null;
|
||||
}
|
||||
|
||||
isNodeKey(potentialKey: any) : potentialKey is number {
|
||||
return typeof potentialKey === 'number';
|
||||
}
|
||||
|
||||
dfs<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
pattern?: DFSOrderPattern,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: false
|
||||
): ReturnType<C>[];
|
||||
|
@ -949,7 +981,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
dfs<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
pattern?: DFSOrderPattern,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: undefined
|
||||
): ReturnType<C>[];
|
||||
|
@ -957,7 +989,7 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
dfs<C extends BTNCallback<N | null | undefined>>(
|
||||
callback?: C,
|
||||
pattern?: DFSOrderPattern,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: true
|
||||
): ReturnType<C>[];
|
||||
|
@ -981,10 +1013,12 @@ 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: N | null | undefined = this.root,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType: IterationType = IterationType.ITERATIVE,
|
||||
includeNull = false
|
||||
): ReturnType<C>[] {
|
||||
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
const ans: ReturnType<C>[] = [];
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
|
@ -1074,21 +1108,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
|
||||
bfs<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: false
|
||||
): ReturnType<C>[];
|
||||
|
||||
bfs<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: undefined
|
||||
): ReturnType<C>[];
|
||||
|
||||
bfs<C extends BTNCallback<N | null | undefined>>(
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: true
|
||||
): ReturnType<C>[];
|
||||
|
@ -1109,10 +1143,11 @@ 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: N | null | undefined = this.root,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType,
|
||||
includeNull = false
|
||||
): ReturnType<C>[] {
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
|
||||
const ans: ReturnType<BTNCallback<N>>[] = [];
|
||||
|
@ -1162,21 +1197,21 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
|
||||
listLevels<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: false
|
||||
): ReturnType<C>[][];
|
||||
|
||||
listLevels<C extends BTNCallback<N>>(
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: undefined
|
||||
): ReturnType<C>[][];
|
||||
|
||||
listLevels<C extends BTNCallback<N | null | undefined>>(
|
||||
callback?: C,
|
||||
beginRoot?: N | null | undefined,
|
||||
beginRoot?: BTNKey | N | null | undefined,
|
||||
iterationType?: IterationType,
|
||||
includeNull?: true
|
||||
): ReturnType<C>[][];
|
||||
|
@ -1199,10 +1234,11 @@ 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: N | null | undefined = this.root,
|
||||
beginRoot: BTNKey | N | null | undefined = this.root,
|
||||
iterationType = this.iterationType,
|
||||
includeNull = false
|
||||
): ReturnType<C>[][] {
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
const levelsNodes: ReturnType<C>[][] = [];
|
||||
|
||||
|
@ -1243,12 +1279,17 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
return levelsNodes;
|
||||
}
|
||||
|
||||
getPredecessor(node: N ): N
|
||||
|
||||
/**
|
||||
* The function returns the predecessor node of a given node in a binary tree.
|
||||
* @param {N} node - The parameter "node" represents a node in a binary tree.
|
||||
* @returns The function `getPredecessor` returns the predecessor node of the given node `node`.
|
||||
*/
|
||||
getPredecessor(node: N): N {
|
||||
getPredecessor(node: BTNKey | N | null | undefined): N | undefined{
|
||||
if (this.isNodeKey(node)) node = this.getNode(node);
|
||||
if (!node) return undefined;
|
||||
|
||||
if (node.left) {
|
||||
let predecessor: N | null | undefined = node.left;
|
||||
while (!predecessor || (predecessor.right && predecessor.right !== node)) {
|
||||
|
@ -1269,7 +1310,10 @@ export class BinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNode
|
|||
* @returns The function `getSuccessor` returns a value of type `N` (the successor node), or `null`
|
||||
* if there is no successor, or `undefined` if the input `x` is `undefined`.
|
||||
*/
|
||||
getSuccessor(x: N): N | null | undefined {
|
||||
getSuccessor(x: BTNKey | N | null | undefined): N | null | undefined {
|
||||
if (this.isNodeKey(x)) x = this.getNode(x);
|
||||
if (!x) return undefined;
|
||||
|
||||
if (x.right) {
|
||||
return this.getLeftMost(x.right);
|
||||
}
|
||||
|
@ -1299,8 +1343,9 @@ 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: N | null | undefined = this.root
|
||||
beginRoot: BTNKey | N | null | undefined = this.root
|
||||
): ReturnType<C>[] {
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (beginRoot === null) return [];
|
||||
const ans: ReturnType<BTNCallback<N>>[] = [];
|
||||
|
||||
|
@ -1433,19 +1478,26 @@ 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: N, destNode: N): N {
|
||||
const {key, value} = destNode;
|
||||
const tempNode = this.createNode(key, value);
|
||||
protected _swap(srcNode: BTNKey | N | null | undefined, destNode:BTNKey | N | null | undefined): N | undefined{
|
||||
if (this.isNodeKey(srcNode)) srcNode = this._getNodeByKey(srcNode);
|
||||
if (this.isNodeKey(destNode)) destNode = this._getNodeByKey(destNode);
|
||||
|
||||
if (tempNode) {
|
||||
destNode.key = srcNode.key;
|
||||
destNode.value = srcNode.value;
|
||||
if (srcNode && destNode) {
|
||||
const {key, value} = destNode;
|
||||
const tempNode = this.createNode(key, value);
|
||||
|
||||
srcNode.key = tempNode.key;
|
||||
srcNode.value = tempNode.value;
|
||||
if (tempNode) {
|
||||
destNode.key = srcNode.key;
|
||||
destNode.value = srcNode.value;
|
||||
|
||||
srcNode.key = tempNode.key;
|
||||
srcNode.value = tempNode.value;
|
||||
}
|
||||
|
||||
return destNode;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
return destNode;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1459,7 +1511,9 @@ 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: N): N | null | undefined {
|
||||
protected _addTo(newNode: N | null | undefined, parent: BTNKey | N | null | undefined): N | null | undefined {
|
||||
if (this.isNodeKey(parent)) parent = this.getNode(parent);
|
||||
|
||||
if (parent) {
|
||||
// When all leaf nodes are null, it will no longer be possible to add new entity nodes to this binary tree.
|
||||
// In this scenario, null nodes serve as "sentinel nodes," "virtual nodes," or "placeholder nodes."
|
||||
|
|
|
@ -13,6 +13,7 @@ import {Queue} from '../queue';
|
|||
|
||||
export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extends BinaryTreeNode<V, N> {
|
||||
override parent: N | undefined;
|
||||
|
||||
constructor(key: BTNKey, value?: V) {
|
||||
super(key, value);
|
||||
this.parent = undefined;
|
||||
|
@ -64,8 +65,7 @@ export class BSTNode<V = any, N extends BSTNode<V, N> = BSTNodeNested<V>> extend
|
|||
|
||||
export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>>
|
||||
extends BinaryTree<V, N>
|
||||
implements IBinaryTree<V, N>
|
||||
{
|
||||
implements IBinaryTree<V, N> {
|
||||
/**
|
||||
* The constructor function initializes a binary search tree object with an optional comparator
|
||||
* function.
|
||||
|
@ -82,6 +82,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override _root: N | undefined = undefined;
|
||||
|
||||
/**
|
||||
|
@ -119,8 +120,8 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
}
|
||||
if (keyOrNode === null) return undefined;
|
||||
// TODO support node as a parameter
|
||||
let inserted:N | undefined;
|
||||
let newNode:N | undefined;
|
||||
let inserted: N | undefined;
|
||||
let newNode: N | undefined;
|
||||
if (keyOrNode instanceof BSTNode) {
|
||||
newNode = keyOrNode;
|
||||
} else if (typeof keyOrNode === 'number') {
|
||||
|
@ -198,13 +199,13 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
*/
|
||||
|
||||
override addMany(
|
||||
keysOrNodes: (BTNKey | undefined)[] | (N | undefined)[],
|
||||
data?: V[],
|
||||
keysOrNodes: (BTNKey | N | undefined)[],
|
||||
data?: (V | undefined)[],
|
||||
isBalanceAdd = true,
|
||||
iterationType = this.iterationType
|
||||
): (N | undefined)[] {
|
||||
// TODO this addMany function is inefficient, it should be optimized
|
||||
function hasNoNull(arr: (BTNKey | undefined)[] | (N | undefined)[]): arr is BTNKey[] | N[] {
|
||||
function hasNoNull(arr: (BTNKey | N | undefined)[]): arr is (BTNKey | N)[] {
|
||||
return arr.indexOf(undefined) === -1;
|
||||
}
|
||||
|
||||
|
@ -289,12 +290,37 @@ 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: N | undefined = this.root, iterationType = this.iterationType): BTNKey {
|
||||
lastKey(beginRoot: BTNKey | N | undefined = 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;
|
||||
}
|
||||
|
||||
protected override _getNodeByKey(key: BTNKey, iterationType = IterationType.ITERATIVE): N | undefined {
|
||||
if (!this.root) return undefined;
|
||||
if (iterationType === IterationType.RECURSIVE) {
|
||||
const _dfs = (cur: N): N | undefined => {
|
||||
if (cur.key === key) return cur;
|
||||
|
||||
if (!cur.left && !cur.right) return;
|
||||
if (this._compare(cur.key, key) === CP.gt && cur.left) return _dfs(cur.left);
|
||||
if (this._compare(cur.key, key) === CP.lt && cur.right) return _dfs(cur.right);
|
||||
};
|
||||
|
||||
return _dfs(this.root);
|
||||
} else {
|
||||
const queue = new Queue<N>([this.root]);
|
||||
while (queue.size > 0) {
|
||||
const cur = queue.shift();
|
||||
if (cur) {
|
||||
if (this._compare(cur.key, key) === CP.eq) return cur;
|
||||
if (this._compare(cur.key, key) === CP.gt) cur.left && queue.push(cur.left);
|
||||
if (this._compare(cur.key, key) === CP.lt) cur.right && queue.push(cur.right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function `getNodes` retrieves nodes from a binary tree based on a given node property or key,
|
||||
* using either recursive or iterative traversal.
|
||||
|
@ -320,9 +346,10 @@ 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: N | undefined = this.root,
|
||||
beginRoot: BTNKey | N | undefined = this.root,
|
||||
iterationType = this.iterationType
|
||||
): N[] {
|
||||
if (this.isNodeKey(beginRoot)) beginRoot = this._getNodeByKey(beginRoot);
|
||||
if (!beginRoot) return [];
|
||||
const ans: N[] = [];
|
||||
|
||||
|
@ -509,7 +536,7 @@ export class BST<V = any, N extends BSTNode<V, N> = BSTNode<V, BSTNodeNested<V>>
|
|||
} else {
|
||||
const stack: N[] = [];
|
||||
let node: N | undefined = this.root,
|
||||
last:N | undefined = undefined;
|
||||
last: N | undefined = undefined;
|
||||
const depths: Map<N, number> = new Map();
|
||||
|
||||
while (stack.length > 0 || node) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
BinaryTreeDeletedResult,
|
||||
BiTreeDeleteResult,
|
||||
BTNCallback,
|
||||
BTNKey,
|
||||
IterationType,
|
||||
|
@ -119,8 +119,8 @@ export class RedBlackTree<V = any, N extends RBTreeNode<V, N> = RBTreeNode<V, RB
|
|||
delete<C extends BTNCallback<N>>(
|
||||
identifier: ReturnType<C> | null | undefined,
|
||||
callback: C = this.defaultOneParamCallback as C
|
||||
): BinaryTreeDeletedResult<N>[] {
|
||||
const ans: BinaryTreeDeletedResult<N>[] = [];
|
||||
): BiTreeDeleteResult<N>[] {
|
||||
const ans: BiTreeDeleteResult<N>[] = [];
|
||||
if (identifier === null) return ans;
|
||||
const helper = (node: N | undefined): void => {
|
||||
let z: N = this.NIL;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @license MIT License
|
||||
*/
|
||||
import type {BTNKey, TreeMultimapNodeNested, TreeMultimapOptions} from '../../types';
|
||||
import {BinaryTreeDeletedResult, BTNCallback, CP, FamilyPosition, IterationType} from '../../types';
|
||||
import {BiTreeDeleteResult, BTNCallback, CP, FamilyPosition, IterationType} from '../../types';
|
||||
import {IBinaryTree} from '../../interfaces';
|
||||
import {AVLTree, AVLTreeNode} from './avl-tree';
|
||||
|
||||
|
@ -274,14 +274,14 @@ export class TreeMultimap<V = any, N extends TreeMultimapNode<V, N> = TreeMultim
|
|||
* being deleted. If set to true, the count of the node will not be considered and the node will be
|
||||
* deleted regardless of its count. If set to false (default), the count of the node will be
|
||||
* decremented by 1 and
|
||||
* @returns The method `delete` returns an array of `BinaryTreeDeletedResult<N>` objects.
|
||||
* @returns The method `delete` returns an array of `BiTreeDeleteResult<N>` objects.
|
||||
*/
|
||||
override delete<C extends BTNCallback<N>>(
|
||||
identifier: ReturnType<C>,
|
||||
callback: C = this.defaultOneParamCallback as C,
|
||||
ignoreCount = false
|
||||
): BinaryTreeDeletedResult<N>[] {
|
||||
const bstDeletedResult: BinaryTreeDeletedResult<N>[] = [];
|
||||
): BiTreeDeleteResult<N>[] {
|
||||
const bstDeletedResult: BiTreeDeleteResult<N>[] = [];
|
||||
if (!this.root) return bstDeletedResult;
|
||||
|
||||
const curr: N | undefined = this.getNode(identifier, callback) ?? undefined;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import {BinaryTreeNode} from '../data-structures';
|
||||
import {BinaryTreeDeletedResult, BinaryTreeNodeNested, BTNCallback, BTNKey} from '../types';
|
||||
import {BiTreeDeleteResult, BinaryTreeNodeNested, BTNCallback, BTNKey} from '../types';
|
||||
|
||||
export interface IBinaryTree<V = any, N extends BinaryTreeNode<V, N> = BinaryTreeNodeNested<V>> {
|
||||
createNode(key: BTNKey, value?: N['value']): N;
|
||||
|
||||
add(keyOrNode: BTNKey | N | null, value?: N['value']): N | null | undefined;
|
||||
|
||||
delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null, callback: C): BinaryTreeDeletedResult<N>[];
|
||||
delete<C extends BTNCallback<N>>(identifier: ReturnType<C> | null, callback: C): BiTreeDeleteResult<N>[];
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export enum FamilyPosition {
|
|||
|
||||
export type BTNKey = number;
|
||||
|
||||
export type BinaryTreeDeletedResult<N> = { deleted: N | null | undefined; needBalanced: N | null | undefined };
|
||||
export type BiTreeDeleteResult<N> = { deleted: N | null | undefined; needBalanced: N | null | undefined };
|
||||
|
||||
export type BinaryTreeNodeNested<T> = BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, BinaryTreeNode<T, any>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
|
||||
|
|
Loading…
Reference in a new issue