Java树的中序遍历非递归实现

介绍

在计算机科学中,树是一种非常常见的数据结构。树的中序遍历是一种遍历树的方式,它首先遍历树的左子树,然后访问根节点,最后遍历树的右子树。

在本文中,我将介绍如何使用非递归的方式实现Java树的中序遍历。我将按照以下步骤进行介绍,并附带相应的代码示例。

实现步骤

  1. 创建一个辅助栈,用于存储遍历过程中的节点。
  2. 初始化当前节点为根节点。
  3. 循环执行以下步骤,直到当前节点为空且辅助栈为空:
    1. 将当前节点的所有左子树节点入栈,并将当前节点更新为其左子树节点。
    2. 如果当前节点为空,出栈一个节点,并将当前节点更新为该节点的右子树节点。
    3. 访问当前节点。

下面是具体的代码实现:

public void inorderTraversal(TreeNode root) {
    Stack<TreeNode> stack = new Stack<>();
    TreeNode current = root;
    
    while (current != null || !stack.isEmpty()) {
        // 将当前节点的所有左子树节点入栈,并将当前节点更新为其左子树节点
        while (current != null) {
            stack.push(current);
            current = current.left;
        }
        
        // 如果当前节点为空,出栈一个节点,并将当前节点更新为该节点的右子树节点
        current = stack.pop();
        
        // 访问当前节点
        System.out.print(current.val + " ");
        
        // 更新当前节点为其右子树节点
        current = current.right;
    }
}

在上述代码中,我们使用了一个辅助栈来存储遍历过程中的节点。我们首先将根节点入栈,并将当前节点更新为其左子树节点。然后,我们在循环中不断将当前节点的左子树节点入栈,并将当前节点更新为其左子树节点,直到当前节点为空。此时,我们出栈一个节点,并将当前节点更新为该节点的右子树节点。最后,我们访问当前节点,并将当前节点更新为其右子树节点。循环直到当前节点为空且辅助栈为空。

示例

考虑以下二叉树:

       1
      / \
     2   3
    / \
   4   5

我们可以按照以下步骤进行中序遍历:

  1. 将根节点1入栈,并将当前节点更新为其左子树节点2。
  2. 将节点2入栈,并将当前节点更新为其左子树节点4。
  3. 当前节点为空,出栈节点4,并将当前节点更新为节点4的右子树节点null。
  4. 访问节点4。
  5. 当前节点为空,出栈节点2,并将当前节点更新为节点2的右子树节点5。
  6. 访问节点2。
  7. 将节点5入栈,并将当前节点更新为其左子树节点null。
  8. 当前节点为空,出栈节点5,并将当前节点更新为节点5的右子树节点null。
  9. 访问节点5。
  10. 当前节点为空,出栈节点1,并将当前节点更新为节点1的右子树节点3。
  11. 访问节点1。
  12. 将节点3入栈,并将当前节点更新为其左子树节点null。
  13. 当前节点为空,出栈节点3,并将当前节点更新为节点3的右子树节点null。
  14. 访问节点3。

按照上述步骤,我们得到中序遍历结果:4 2 5 1 3

下面是中序遍历的流程图:

journey
    title 中序遍历流程

    section 初始化
        初始化辅助栈stack
        初始化当前节点current为根节点root
    end

    section 循环
        while (current != null || !stack.isEmpty())
    end

    section 遍历左子树
        while (current != null)
            stack.push(current)
            current