JAVA二刷-Day14 | 144.二叉树的前序遍历, 145.二叉树的后序遍历, 94.二叉树的中序遍历

JAVA二刷-Day14 | 144.二叉树的前序遍历, 145.二叉树的后序遍历, 94.二叉树的中序遍历

迭代方法由于要满足弹出时候的左中右或者中左右或者左右中顺序。

二叉树的前序遍历

LeetCode题目链接:https://leetcode.cn/problems/binary-tree-preorder-traversal/

解题思路

  递归方法代码,迭代的方法都比较相同:

class Solution {

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

  迭代方法代码:

class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Stack<TreeNode> stkNode = new Stack<TreeNode>();
        stkNode.push(root);
        while (!stkNode.isEmpty()) {
            TreeNode node = stkNode.peek();
            stkNode.pop();
            if (node != null) {
                result.add(node.val);
                if (node.right != null) stkNode.push(node.right);
                if (node.left != null) stkNode.push(node.left);
            }
        }
        return result;
    }
}

二叉树的后序遍历

LeetCode题目链接:https://leetcode.cn/problems/top-k-frequent-elements/

解题思路

  递归方法与前序类似,迭代方法也可以简单修改顺序和翻转后完成。

  具体代码如下:

class Solution {
    public void postOrder(TreeNode root, List<Integer> result) {
        if (root == null) return;
        
        postOrder(root.left, result);
        postOrder(root.right, result);
        result.add(root.val);
        return;
    }
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        postOrder(root, result);
        return result;
    }
}

二叉树的中序遍历

LeetCode题目链接:https://leetcode.cn/problems/binary-tree-inorder-traversal/

解题思路

  递归方法与前序相同,迭代方法需要注意中序的特殊性质,即元素入栈顺序和实际加载顺序不相关,因此需要特殊处理。

  具体代码如下:

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Stack<TreeNode> stkNode = new Stack<TreeNode>();
        TreeNode current = root;
        while (current != null || !stkNode.isEmpty()) {
            if (current != null) {
                stkNode.add(current);
                current = current.left;
            }else {
                current = stkNode.peek();
                stkNode.pop();
                result.add(current.val);
                current = current.right;
            }
        }
        return result;
    }
}

统一迭代法

统一迭代法主要的思想是对要取出的元素后加入NULL标记来进行迭代。如果迭代到某个根元素的时候没有NULL标记,可以理解为该点元素还没有被拿出来查询分支过,以此来进行不断的迭代循环,经过查询后的节点才可以放入返回数组中。

以下是前序遍历的标记迭代法,进行中序后序遍历,只需要改变cur和NULL 的位置即可,因为cur被理解为被查询分支的那个节点,所以对他进行标记而不是对该节点的两个分支进行标记:

class Solution {

    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        Stack<TreeNode> stkNode = new Stack<TreeNode>();
        if (root != null) stkNode.push(root);
        while (!stkNode.isEmpty()) {
            TreeNode cur = stkNode.peek();
            if (cur != null) {
                stkNode.pop();
                if (cur.right != null) stkNode.add(cur.right);
                if (cur.left != null) stkNode.add(cur.left);
                stkNode.add(cur);
                stkNode.add(null);
            }else {
                stkNode.pop();
                cur = stkNode.peek();
                stkNode.pop();
                result.add(cur.val);
            }
        }
        return result;
    }
}

你可能感兴趣的:(数据结构,java,开发语言)