树的遍历

LeetCode上的三道关于树的遍历题目:

  1. 144二叉树的前序遍历
  2. 94二叉树的中序遍历
  3. 145二叉树的后序遍历

递归解法

递归是最容易的。递归是函数自身调用自身,涉及到保护现场(变量入栈,记录地址等),时间和空间开销较大,而这操作都是在栈上,调用层级太多很容易溢出。 其与迭代最大的区别就是是否会栈溢出。

前序遍历

public void dfs(TreeNode root) {
    if(root == null) {
        return;
    }
    visit(root);
    dfs(root.left);
    dfs(root.right);
}

中序遍历

public void dfs(TreeNode root) {
    if(root == null) {
        return;
    }
    dfs(root.left);
    visit(root);
    dfs(root.right);
}

后序遍历

public void dfs(TreeNode root) {
    if(root == null) {
        return;
    }
    dfs(root.left);
    dfs(root.right);
    visit(root);
}

非递归解法

非递归的方法是用存储代替计算,就是在建立树时,实现了存储展开,相当于存储了未来需要遍历的路径,速度更快。

前序遍历

public void dfs(TreeNode root) {
    if(root == null) return;
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while(!stack.isEmpty()) {
        TreeNode node = stack.pop();
        visit(node);
        if(node.right != null) stack.push(node.right);
        if(node.left != null) stack.push(node.left);
    }
}

中序遍历

public void dfs(TreeNode root) {
    if(root == null) return;
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = root;
    while(cur != null || !stack.isEmpty()) {
        while(cur != null) {
            stack.push(cur);
            cur = cur.left;
        }
        TreeNode node = stack.pop();
        visit(node);
        cur = node.right;
    }
}

后序遍历

用两个栈

public void dfs(TreeNode root) {
    if(root == null) return;
    Stack<TreeNode> s1 = new Stack<>();
    Stack<TreeNode> s2 = new Stack<>();
    s1.push(root);
    while(!s1.isEmpty()) {
        TreeNode node = s1.pop();
        s2.push(node);
        if(peek.left != null) s1.push(peek.left);
        if(peek.right != null)
        s1.push(peek.right);
    }
    while(!s2.isEmpty()) {
        TreeNode node = s2.pop();
        visit(node);
    }
}

用一个栈

public void dfs(TreeNode root) {
    if(root == null) return;
    Stack<TreeNode> stack = new Stack<>();
    TreeNode cur = null;
    stack.push(root);
    while(!stack.isEmpty()) {
        TreeNode peek = stack.peek();
        if(peek.left != null && peek.left != cur && (peek.right != cur || cur == null)) {
            stack.push(peek.left);
        } else if(peek.right != null && peek.right != cur) {
            stack.push(peek.right);
        } else {
            visit(stack.pop());
            cur = peek;
        }
    }
}
原文地址:https://www.cnblogs.com/chenshaowei/p/13468421.html