二叉搜索树之后序遍历(迭代版)
Node类
class Node { int val; Node left; Node right; public Node(int val) { this.val = val; } }
构建二叉树
// 构建二叉树 public static Node createBinaryTree(int[] values) { // 判空,为空直接返回null if (values == null) { return null; } int n = values.length; Node root = null; for (int i = 0; i < n; i++) { if (root == null) { // 如果此时没有根节点,则创建根节点 root = new Node(values[i]); } else { create(root, values[i]); } } return root; } public static void create(Node root, int val) { // 判空,为空直接返回 if (root == null) { return; } if (val == root.val) { return; } else if (val < root.val) { if (root.left == null) { // 如果左节点为空,直接就将当前待插入节点作为当前根节点的左孩子 root.left = new Node(val); } else { create(root.left, val); } } else { if (root.right == null) { // 如果右节点为空,直接就将当前待插入节点作为当前根节点的右孩子 root.right = new Node(val); } else { create(root.right, val); } } }
后序遍历
// 非递归实现 public static void inOrderTransvalWithIterate(Node root) { if (root == null) { return; } // 这里需要维护上一个访问的节点(这也是后序遍历的关键点) Node pre = null; List<Integer> res = new ArrayList<>(); // TODO: Deque<Node> q = new LinkedList<>(); while (!q.isEmpty() || root != null) { // 一直找到最左边界 while (root != null) { q.push(root); root = root.left; } // 弹出栈顶节点(即当前最左节点) Node pop = q.pop(); if (pop.right == null || pop.right == pre) { // 什么时候当前节点可以访问? // 1、当前节点的右节点为空 // 2、当前节点的右节点为上一个访问节点 res.add(pop.val); pre = pop; } else { // 如果发现右节点不为空,则当前节点还需要继续入栈(因为右节点始终比当前节点要先访问) q.push(pop); root = pop.right; } } // 打印 for (int i = 0; i < res.size(); i++) { System.out.print(res.get(i) + " "); } }
测试类
public static void main(String[] args) { final int[] values = { 5, 3, 8, 1, 2, 4, 6, 7, 9, 0 }; System.out.println("Create BST: "); Node root = createBinaryTree(values); System.out.println("Traversing the BST with iterative algorithm: "); inOrderTransvalWithIterate(root); // 此处填写上遍历的结果,形如:a, b , c, d, e, ... // 0, 2, 1, 4, 3, 7, 6, 9, 8, 5, /** */ }