zoukankan      html  css  js  c++  java
  • 聊聊二叉树的各种遍历

    聊聊二叉树的各种遍历

    聊聊二叉树的各种遍历

    二叉树的遍历有前序、中序和后序遍历,还有层次遍历等。遍历可以用递归法,也可以使用非递归法,即迭代法。
    各种算法里,递归法通常是最简单,最能反应数学本质的。但由于递归算法,需要保存所有递归的栈信息,因此会占有较多的栈内存,运行效率也要低一些。一般程序的内存空间,分为方法区和静态变量区、栈区和堆区。堆区的空间是最大的,方法区和静态变量区和栈区的空间相对要小很多。所以,递归的层次太深之后,就会导致栈区的内存被占满,导致栈内存泄漏而出现异常。
    所以,需要使用迭代的方法来替代递归法。当然,如果是尾递归的话,现代的编译器可以自动转换为非递归的,也就可以放心的使用递归了。

    1 前序遍历

    1.1 递归法

    public ArrayList<Integer> preorderTravesal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList();
        helper(root, result);
    
        return result;
    }
    private void helper(TreeNode root, ArrayList<Integer> result) {
        if (root == null) {
            return;
        }
        result.add(root.val);
        helper(root.left, result);
        helper(root.right, result);
    }
    

    1.2 迭代法

    迭代法需要使用一个栈表来保存所有遍历过的左节点,当到达左树的叶子节点时,从栈中往回退,获得每个节点的右节点,继续遍历所有的左节点,然后,循环。

    public ArrayList<Integer> preorderTravesal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList();
        Stack<TreeNode> st = new Stack();
    
        TreeNode cur = root;
    
        while (cur != null || !st.empty()) {
            while (cur != null) {
                result.add(cur.val);
                st.push(cur);
                cur = cur.left;
            }
            if (!st.empty()) {
                cur = st.pop();
                cur = cur.right;
            }
        }
    
        return result;
    }
    

    2 中序遍历

    2.1 递归法

    public ArrayList<Integer> preorderTravesal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList();
        helper(root, result);
    
        return result;
    }
    private void helper(TreeNode root, ArrayList<Integer> result) {
        if (root == null) {
            return;
        }
        helper(root.left, result);
        result.add(root.val);
        helper(root.right, result);
    }
    

    2.2 迭代法

    迭代法需要使用一个栈表来保存所有遍历过的左节点,当到达左树的叶子节点时,从栈中往回退,获得每个节点的右节点这时添加到结果列表中,继续遍历所有的左节点,然后,循环。

    public ArrayList<Integer> preorderTravesal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList();
        Stack<TreeNode> st = new Stack();
    
        TreeNode cur = root;
    
        while (cur != null || !st.empty()) {
            while (cur != null) {
                st.push(cur);
                cur = cur.left;
            }
            if (!st.empty()) {
                cur = st.pop();
                result.add(cur.val);
                cur = cur.right;
            }
        }
    
        return result;
    }
    

    3 后序遍历

    3.1 递归法

    public ArrayList<Integer> preorderTravesal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList();
        helper(root, result);
    
        return result;
    }
    private void helper(TreeNode root, ArrayList<Integer> result) {
        if (root == null) {
            return;
        }
        helper(root.left, result);
        helper(root.right, result);
        result.add(root.val);
    }
    

    3.2 迭代法

    后序遍历需要先遍历左节点,再右节点,再父节点。所以,入栈的顺序是父-右-左,出栈的顺序就是左-右-父。
    每个节点取栈顶节点,如果是叶子节点或者已经是回退中的父节点,则添加到结果列表中,并出栈。

    public ArrayList<Integer> preorderTravesal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList();
        Stack<TreeNode> st = new Stack();
    
        TreeNode prev = null;
        TreeNode cur = root;
    
        st.push(cur);
        while (!st.empty()) {
            cur = st.peek();
            if ((cur.left == null && cur.right == null)
                || (prev != null && (prev == cur.left || prev == cur.right))) {
                result.add(cur.val);
                prev = cur;
                cur = st.pop();
            } else {
                if (cur.right != null) {
                    st.push(cur.right);
                }
                if (cur.left ! = null) {
                    st.push(cur.left);
                }
            }
        }
    
        return result;
    }
    

    Date: 2017-07-01 21:44

    Author: WEN YANG

    Created: 2017-07-01 Sat 23:05

    Emacs 25.2.1 (Org mode 8.2.10)

    Validate

  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/yangwen0228/p/7103767.html
Copyright © 2011-2022 走看看