递归解法比较简单,此处不再赘述。仅讨论迭代解法。
private List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) return res;
res.add(root.val);
res.addAll(preorderTraversal(root.left));
res.addAll(preorderTraversal(root.right));
return res;
}
- 如图所示,红色箭头P表示当前树节点;stack表示操作栈;result表示要返回的结果集
- 遍历开始:
-
指针P指向1节点,由于1非空,1入结果集,1入栈([1]),指针指向1的左子节点2
-
指针P指向2节点,由于2非空,2入结果集,2入栈([1,2]),指针指向2的左子节点4
-
指针P指向4节点,由于4非空,4入结果集,4入栈([1,2,4]),指针指向4的左子节点4l(null)
-
指针P指向4l节点,由于4l为空,4出栈([1,2]),指针指向4的右子节点4r(null)
-
指针P指向4r节点,由于4r为空,2出栈([1]),指针指向2的右子节点5
-
指针P指向5节点,由于5非空,5入结果集,5入栈([1,5]),指针指向5的左子节点5l(null)
-
指针P指向5l节点,由于5l为空,5出栈([1]),指针指向5的右子节点5r(null)
-
指针P指向5r节点,由于5r为空,1出栈([]),指针指向1的右子节点3
-
指针P指向3节点,由于3非空,3入结果集,3入栈([3]),指针指向3的左子节点6
-
指针P指向6节点,由于6非空,6入结果集,6入栈([3,6]),指针指向6的左子节点6l(null)
-
指针P指向6l节点,由于6l为空,6出栈([3]),指针指向6的右子节点6r(null)
-
指针P指向6r节点,由于6r为空,3出栈(),指针指向3的右子节点7
-
指针P指向7节点,由于7非空,7入结果集,7入栈([7]),指针指向7的左子节点7l(null)
-
指针P指向7l节点,由于7l为空,7出栈([]),指针指向7的右子节点7r(null)
-
指针P指向7r节点,此时当前节点7r为空,stack也为空,循环结束,二叉树遍历完成。
-
private List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.isEmpty()) {
if (root == null) {
TreeNode pop = stack.pop();
root = pop.right;
} else {
res.add(root.val);
stack.push(root);
root = root.left;
}
}
return res;
}