Class AbstractRootToLeafPathVisitor<T,R>
- Type Parameters:
T
- The type of the value/data stored in each node of the binary tree being path-traversedR
- The type of value/object that is to be returned as the result of the path-traversal
- Direct Known Subclasses:
DepthCalculator
,RootToLeafPathsMaker
A path-traversal is defined as traversing the tree by following root-to-leaf path order from left to right while maintaining each single path. For example, a path-traversal of the following tree
1 / \ 2 3 / \ \ 4 5 6is
1 -> 2 -> 4 -> 5 -> 3 -> 6
. The fundamental difference between path-traversal and pre-order traversal
is that path-traversal works for algorithm in which root-to-leaf path needs to be calculated while pre-order
traversal does not. For example, all root-to-leaf paths of a binary tree
or
depth of a binary tree
can be found using path-traversal algorithm. These are, however, not
doable using pre-order traversal algorithm
This algorithm
is not designed for implementing algorithm that could possibly
terminate in the middle of the traversal(such as search), because
this algorithm
does not terminate when the terminating condition is satisfied
(such as the search target is found); instead it will keep traversing until all nodes in the tree have been visited.
-
Constructor Summary
Constructors -
Method Summary
-
Constructor Details
-
AbstractRootToLeafPathVisitor
public AbstractRootToLeafPathVisitor()
-
-
Method Details
-
getVisitResult
Retrieves the result of the path-traversal.visit(TreeNode)
must be called before calling this method; otherwise the behavior of this method is not defined.- Returns:
- identity to be calculated by path-traversal
-
visit
Executes the path-traversal algorithm on a specified binary tree.Algorithm: a straight forward recursion approach is
RootToLeafPathsMaker.constructTreePaths(TreeNode, Path)
. This is a tail recursion which can be changed to an iterative algorithm (1st draft) as follows:final Deque<TreeNode<T>> path = new ArrayDeque<>(); final Deque<TreeNode<T>> stack = new ArrayDeque<>(Collections.singleton(root)); while (!stack.isEmpty()) { final TreeNode<T> current = stack.pop(); path.addLast(current); if (isLeaf(current)) { getPaths().add(new LinkedList<>(path)); path.removeLast(); } if (current.getRight() != null) { stack.push(current.getRight()); } if (current.getLeft() != null) { stack.push(current.getLeft()); } }
1 / \ 2 3
but not1 / \ 2 3 / \ \ 4 5 6
because we will get "1-2-3-6" as the last path. Thepath
is not able to be updated to remove 2. To address that, we record parent of each node in a map as we traverse. For each node popping out of stack, we use this map to keep removing elements frompath
until we see the parent the current node. At this moment,path
won't have 2 and 3 will get append to 1 correctly.- Parameters:
root
- The root of the binary tree (cannot benull
)- See Also:
-
visitLeaf
Performs action while path-traversal is visiting aleaf node
.For example, while path-traversing the following tree
1 / \ 2 3 / \ \ 4 5 6
visitLeaf(Path)
is called at node 4, 5, and 6.- Parameters:
path
- A complete root-to-leaf path ending on the leaf being visited; for example, when callingvisitLeaf(Path)
at node 4,path
is1 -> 2 -> 4
; at node 5,path
is1 -> 2 -> 5
; at node 6,path
is1 -> 3 -> 6
-