Very efficient recursion
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> ls = new LinkedList<Integer>(); per(root, ls); return ls; } public static void per(TreeNode T, List ls) { if (T != null) { ls.add(T.val); if (T.left != null) per(T.left, ls); if (T.right != null) per(T.right, ls); } } }
It's recursive, but it's not efficient.
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> ls = new LinkedList<Integer>(); Stack<TreeNode> queue = new Stack<TreeNode>(); queue.add(root); while (!queue.isEmpty()) { TreeNode node = queue.pop(); if (node != null) { ls.add(node.val); if (node.right != null) queue.add(node.right); if (node.left != null) queue.add(node.left); } } return ls; } }
Morris doesn't know how to traverse
Method 2: Morris traversal
The method is based on Morris's article and can optimize the spatial complexity. The algorithm does not use extra space, only the final output needs to be saved. If the results are output in real time, the spatial complexity is O(1)O(1).
algorithm
The idea of the algorithm is to visit the predecessor nodes from the current node down, and each predecessor node is visited twice.
First, we start from the current node, take a step to the left child, and then follow the right child all the way down until we reach a leaf node (the middle order of the current node traverses the precursor node), so we update the output and create a pseudo edge predictor.right = root updates the next point of the precursor. If we visit the precursor node for the second time, we remove the pseudo edge and move to the next vertex because it already points to the current node.
If the first move to the left does not exist, update the output directly and move to the right.
class Solution { public List<Integer> preorderTraversal(TreeNode root) { LinkedList<Integer> output = new LinkedList<>(); TreeNode node = root; while (node != null) { if (node.left == null) { output.add(node.val); node = node.right; } else { TreeNode predecessor = node.left; while ((predecessor.right != null) && (predecessor.right != node)) { predecessor = predecessor.right; } if (predecessor.right == null) { output.add(node.val); predecessor.right = node; node = node.left; } else{ predecessor.right = null; node = node.right; } } } return output; } }