Tree Traversal
The function is handed a log book from the parameter. Now it needs to travel down this tree and log its visits in a top-down (root to leaf) fashion.
Without using recursion or corecursion specifically, one may traverse a tree by starting at the root node, placing its child nodes in a data structure, then iterating by removing node after node from the data structure while placing each removed node's children back into that data structure.[b] If the data structure is a stack (LIFO), this yields depth-first traversal, and if the data structure is a queue (FIFO), this yields breadth-first traversal. -- Wikipedia
Preorder Traversal (LC.144)
Given a binary tree, return the preorder traversal of its nodes' values.
Analysis
Traverse - traverse the entire tree and add nodes in a certain order. preorder will add root.val in the beginning, inorder will add root.val in the middle, and postorder will add root.val in the end.
D&C - the boss breaks down his task into the same subproblems and assign his employees to do it then report to the boss when they are done. *One major difference b/w traverse and D&C is that D&C must have a return value (the report to the boss).
Iteratively - use an explicit stack and be careful with the ordering. Iterative DFS has the opposite ordering as the recursive DFS.
Traverse
public ArrayList<Integer> preorderTraversal(TreeNode root) {
ArrayList<Integer> visitLog = new ArrayList<>();
preOrderHelper(root, visitLog);
return visitLog;
}
private void preOrderHelper(TreeNode root, ArrayList<Integer> visitLog) {
// base case
if (root == null) {
return;
}
// log
visitLog.add(root.val);
// visit
preOrderHelper(root.left, visitLog);
preOrderHelper(root.right, visitLog);
}D&C
Iteratively
Dump children nodes to a data structure. This is like a regular DFS (w/ opposite ordering). Pretty easy to understand.
N-ary Tree Preorder Traversal (LI.1526)
Inorder Traversal (LC.94)
Given a binary tree, return the inorder traversal of its nodes' values.
Traverse
D&C
Trace this one. It makes sense to go down all the way to the left, print and backtrack, print then go right, then backtrack.
Iteratively
The else statement kinda works as an iterative backtracking. We want to stop the search when the current pointer is at bottom right of the binary tree and nothing to backtrack to.
It can be hard to implement the iterative version of in-order traversal after pre-order traversal. There are 2 distinctions to help clarifying the approach.
When to backtrack?
Should be coupled with stack frame being removed
Where does the last iteration stop?
Same place with each subtree (the traversal is recursive in nature)
Going through the tree will help visualize the algorithmic movement. But going through a base case will help implement the stop condition correctly.
Postorder Traversal (LC.145)
Given a binary tree, return the postorder traversal of its nodes' values.
Traverse
D&C
Iteratively
the key is to understand the use of lastVisit and peek
peek is for going right first before root
what about lastVisit? make sure you don't step down on the right path again
Time & Space Complexity
duh we need to visit all the nodes so time will be O(V). The stack space is proportional to the height of the tree. Note: the height of tree is not necessarily logn, the worst case can be n, a linear tree. So we have O(h) where a balanced tree can be O(logn) and a linear tree can be O(n).
References
Wikipedia Tree Traversal
ʕ; •`ᴥ•´ʔ
Last updated