思路

前序遍历是中左右,每次先处理的是中间节点,那么先将跟节点放入栈中,然后将右孩子加入栈,再加入左孩子。
为什么要先加入右孩子,再加入左孩子呢?
因为这样出栈的时候才是中左右的顺序

解法一

leetcode-144:二叉树的前序遍历 - 图1

  1. class Solution {
  2. public List<Integer> preorderTraversal(TreeNode root) {
  3. List<Integer> res = new ArrayList<>();
  4. if (root == null) {
  5. return res;
  6. }
  7. Deque<TreeNode> stack = new LinkedList<>();
  8. stack.push(root);
  9. while (!stack.isEmpty()) {
  10. TreeNode temp = stack.pop();
  11. res.add(temp.val);
  12. if (temp.right != null) {
  13. stack.push(temp.right);
  14. }
  15. if (temp.left != null) {
  16. stack.push(temp.left);
  17. }
  18. }
  19. return res;
  20. }
  21. }

时间复杂度:leetcode-144:二叉树的前序遍历 - 图2,其中 n 是二叉树的节点数。每一个节点恰好被遍历一次
空间复杂度:leetcode-144:二叉树的前序遍历 - 图3,为迭代过程中显式栈的开销,平均情况下为 leetcode-144:二叉树的前序遍历 - 图4,最坏情况下树呈现链状,为 leetcode-144:二叉树的前序遍历 - 图5

解法二

  1. class Solution {
  2. public List<Integer> preorderTraversal(TreeNode root) {
  3. List<Integer> res = new ArrayList<Integer>();
  4. if (root == null) {
  5. return res;
  6. }
  7. Deque<TreeNode> stack = new LinkedList<TreeNode>();
  8. while (!stack.isEmpty() || root != null) {
  9. while (root != null) {
  10. res.add(root.val);
  11. stack.push(root);
  12. root = root.left;
  13. }
  14. root = stack.pop();
  15. root = root.right;
  16. }
  17. return res;
  18. }
  19. }