二叉树的递归和迭代遍历方式

遍历二叉树的方法合集

递归法

递归法的重点是明确递归的结果,考虑本次递归会产生什么

前序遍历

public static void preOrderRecur(TreeNode head) {
    if (head == null) {
        return;
    }
    System.out.print(head.value + " ");
    preOrderRecur(head.left);
    preOrderRecur(head.right);
}

中序遍历

public static void preOrderRecur(TreeNode head) {
    if (head == null) {
        return;
    }
    preOrderRecur(head.left);
    System.out.print(head.value + " ");
    preOrderRecur(head.right);
}

后序遍历

public static void postOrderRecur(TreeNode head) {
    if (head == null) {
        return;
    }
    postOrderRecur(head.left);
    postOrderRecur(head.right);
    System.out.print(head.value + " ");
}

非递归法

非递归法就是模拟栈的运行,让你对栈的执行过程更加清楚

前序遍历

前序遍历是根左右,这是出栈顺序

public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<Integer>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        TreeNode cur=root;
        
        while (cur!=null||!stack.isEmpty()) {
            while(cur!=null){
                list.add(cur.val);
                stack.push(cur.right);
                cur=cur.left;
            }
            cur=stack.pop();
        }
        return list;
    }

中序遍历

前序遍历是左根右,这是出栈顺序

先将所有的左节点压入栈中,直到没有左节点,弹出栈顶,然后把弹出栈顶的右节点加入栈中

public List<Integer> inorderTraversal(TreeNode root) {
            List<Integer> list = new ArrayList<>();
            Stack<TreeNode> stack = new Stack<>();
            TreeNode cur = root;
            while (cur != null || !stack.isEmpty()) {
                while(cur!=null){
                    stack.push(cur);
                    cur=cur.left;
                }
                cur=stack.pop();
                list.add(cur.val);
                cur=cur.right;
            }
            return list;
        }

后序遍历

法1:

后序遍历左右根是 根右左的倒序,所以将根右左的遍历顺序倒序即可

根节点入栈,加入左节点,加入右节点



法2:

  1. 用一个指针cur标记当前退出的节点是什么。
  2. 后序遍历的过程中在遍历完左子树跟右子树cur都会回到根结点。所以当前不管是从左子树是右子树回到根结点
  3. 都不应该再操作了,应该退回上层。
  4. 如果是从右边再返回根结点,应该回到上层。

总结

前序遍历思路

栈S;
p= root;
while(p || S不空){
    while(p){
        访问p节点;
        p的右子树入S;
        p = p的左子树;
    }
    p = S栈顶弹出;
}

中序遍历思路

栈S;
p= root;
while(p || S不空){
    while(p){
        p入S;
        p = p的左子树;
    }
    p = S.top 出栈;
    访问p;
    p = p的右子树;
}

后序遍历思路

法1:

栈S;
p= root;
while(p || S不空){
    while(p){
        访问p节点;
        p的左子树入S;
        p = p的右子树;
    }
    p = S栈顶弹出;
}
结果序列逆序;

法2:

栈S;
p= root;
T<节点,True/False> : 节点标记;
while(p || S不空){
    while(p){
        p入S;
        p = p的左子树;
    }
    while(S不空 且 T[S.top] = True){
        访问S.top;
        S.top出S;
    }
    if(S不空){
        p = S.top 的右子树;
        T[S.top] = True;
    }
}

原文地址:https://www.cnblogs.com/treasury/p/12826020.html