非递归实现二叉树的前序、中序和后序遍历

一. 前序遍历 DLR
leetcode地址
使用栈,先压入根节点,每次栈顶弹出一个节点后先压入这个节点的右孩子,再压入左孩子,直到结束

public List<Integer> preorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Deque<TreeNode> stack = new ArrayDeque<>();
    TreeNode p = root;
    while(!stack.isEmpty() || p != null) {
        if(p != null) {
            stack.push(p);
            result.add(p.val);  // Add before going to children
            p = p.left;
        } else {
            TreeNode node = stack.pop();
            p = node.right;   
        }
    }
    return result;
}

二.中序遍历 LDR
leetcode地址
还是用栈,分三个步骤,root为操作节点

  1. 先压入操作节点
  2. 压入左孩子节点到底
  3. 每次弹出一个节点,这个节点相当于是D,LD已经遍历了,需要考虑R了,但是R也应该是LDR的一个顺序(递归思想),所以将弹出节点的右孩子作为操作节点,返回步骤1
public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<>();
    Deque<TreeNode> stack = new ArrayDeque<>();
    TreeNode p = root;
    while(!stack.isEmpty() || p != null) {
        if(p != null) {
            stack.push(p);
            p = p.left;
        } else {
            TreeNode node = stack.pop();
            result.add(node.val);  // Add after all left children
            p = node.right;   
        }
    }
    return result;
}

三. 后序遍历 LRD
leetcode地址
硬刚LRD也可以搞定,入栈,递归思想和每个需要弹出两次,但是有一种方法更巧妙
把遍历结果看成是DRL遍历的翻转,用LinkedList的addFrist方法,从头部开始插入即可

public List<Integer> postorderTraversal(TreeNode root) {
    LinkedList<Integer> result = new LinkedList<>();
    Deque<TreeNode> stack = new ArrayDeque<>();
    TreeNode p = root;
    while(!stack.isEmpty() || p != null) {
        if(p != null) {
            stack.push(p);
            result.addFirst(p.val);  // Reverse the process of preorder
            p = p.right;             // Reverse the process of preorder
        } else {
            TreeNode node = stack.pop();
            p = node.left;           // Reverse the process of preorder
        }
    }
    return result;
}
    原文作者:yxwithu
    原文地址: https://www.jianshu.com/p/17d073bff198
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞