📜  在Java中使用堆栈实现中序、前序、后序(1)

📅  最后修改于: 2023-12-03 15:23:23.987000             🧑  作者: Mango

在Java中使用堆栈实现中序、前序、后序

在数据结构和算法的学习中,树是其中最常见和有用的数据结构之一。在树遍历过程中,有三种主要的遍历方式:中序遍历、前序遍历和后序遍历。在本文中,我们将学习如何使用Java中的堆栈实现这三种树遍历方式。

前置知识

在学习堆栈实现树遍历前,请确保你已经掌握以下概念:

  • 树的遍历方式(中序、前序、后序)
  • 堆栈
使用堆栈实现中序遍历

在中序遍历中,我们先遍历树的左子树,然后访问根节点,最后遍历右子树。

我们可以使用一个堆栈来模拟这个过程。首先我们将根节点入栈,然后将根节点的左子树入栈,直到左子树为空。此时我们将堆栈顶部的元素(即左子树的最后一个节点)弹出并访问,然后将右子树入栈。这个过程一直持续到堆栈为空。

下面是Java代码片段实现中序遍历:

public void inorderTraversal(TreeNode root) {
    if (root == null) return;

    Stack<TreeNode> stack = new Stack<>();
    TreeNode node = root;

    while (!stack.isEmpty() || node != null) {
        while (node != null) {
            stack.push(node);
            node = node.left;
        }

        node = stack.pop();
        System.out.println(node.val);

        node = node.right;
    }
}

该代码中,我们使用了一个堆栈stack来存储节点。while循环持续到堆栈为空且没有左子树可遍历。在while循环中,我们首先将根节点和它的左子树入栈,然后循环将左子树中的所有节点都入栈。同时,我们还将遍历到的节点打印出来。最后,我们访问右子树并且将右子树入栈,然后不断重复这个过程。

使用堆栈实现前序遍历

在前序遍历中,我们先访问根节点,然后遍历根节点的左子树,最后遍历右子树。

与中序遍历类似,我们可以使用堆栈来模拟这个遍历过程。首先我们将根节点入栈,然后访问根节点。然后,我们将右子树节点入栈,并将左子树节点入栈。我们不断重复这个过程,直到堆栈为空。

下面是Java代码片段实现前序遍历:

public void preorderTraversal(TreeNode root) {
    if (root == null) return;

    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);

    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        System.out.println(node.val);

        if (node.right != null) stack.push(node.right);
        if (node.left != null) stack.push(node.left);
    }
}

该代码首先将根节点入栈,然后在while循环中重复以下过程:弹出堆栈顶部的节点并访问,将右子树入栈,将左子树入栈。由于堆栈的特性,这会使左子树节点在右子树节点之前被访问。

使用堆栈实现后序遍历

在后序遍历中,我们先遍历根节点的左子树,然后遍历右子树,最后访问根节点。

与前序遍历类似,我们可以使用堆栈来模拟后序遍历过程。我们需要使用两个堆栈,其中一个堆栈用于存储节点,另一个堆栈用于遍历。具体来说,我们首先将根节点入堆栈1。然后在while循环中,我们从堆栈1中弹出节点并将它推入堆栈2。然后,我们将该节点的左子树和右子树分别推入堆栈1。我们重复这个过程,直到堆栈1中所有节点都被处理完毕。最后,我们从堆栈2中弹出节点并访问。

下面是Java代码片段实现后序遍历:

public void postorderTraversal(TreeNode root) {
    if (root == null) return;

    Stack<TreeNode> stack1 = new Stack<>();
    Stack<TreeNode> stack2 = new Stack<>();
    stack1.push(root);

    while (!stack1.isEmpty()) {
        TreeNode node = stack1.pop();
        stack2.push(node);

        if (node.left != null) stack1.push(node.left);
        if (node.right != null) stack1.push(node.right);
    }

    while (!stack2.isEmpty()) {
        TreeNode node = stack2.pop();
        System.out.println(node.val);
    }
}

该代码使用了两个堆栈stack1和stack2。在第一个while循环中,我们首先将根节点入堆栈1。然后,我们重复弹出堆栈1中的节点并将其推入堆栈2,同时将其左右子树推入堆栈1。这样,我们可以在堆栈2中得到一个逆序的树遍历。在第二个while循环中,我们从堆栈2中弹出树节点并访问。由于这是一个逆序遍历,因此我们得到了正确顺序的后序遍历。

总结

在本文中,我们学习了如何使用Java中的堆栈实现树的三种遍历方式:中序、前序和后序。中序遍历和前序遍历都只需要使用一个堆栈。对于后序遍历,我们需要使用两个堆栈。通过仔细阅读并理解以上代码,相信你已经完全掌握了使用堆栈实现树遍历的方法。