二叉树的后序遍历

后序遍历的逻辑: 左节点------右节点------根节点

递归方式

/**
 * 递归的后序遍历: 左节点-右节点-跟节点
 */
public static void postTraversing(Tree root) {
    // 1.判空
    if (root == null) {
        return;
    }

    // 2.递归左节点
    preTraversing(root.left);
    // 3. 递归右节点
    preTraversing(root.right);
    // 4.输出根节点
    System.out.print(root.val + " ");
}

非递归方式

后序遍历的非递归方式有两种方式实现,分别是单栈方法和双栈方法,这里介绍的是双栈的两种实现方式;
法一:
思路: 利用两个栈来实现,一个栈保存是当前处理的节点,另外一个栈则是用来保存最后输出的结果,并且递归的过程其实转为非递归就是一个循环的过程,这里的循环结束条件为:栈1元素为空或者当前节点为空。
这里用图解方式进行讲解:
1.分别将根节点以及右子树压入栈1和栈2中,栈1是当前结果集,栈2是最终遍历的栈
图片
2.弹出栈1中的元素,记住我们栈2是用来保存结果集,最后弹出结果集来遍历的。结果为(8,9)此时弹出的元素为9,则继续找9元素是否有左子树,此时9没有左子树,则继续弹出栈11
图片
3. 栈中元素还不为空,则继续弹出栈中元素,此时弹出的栈中元素为8,栈1已经为空了。寻找元素8是否有左孩子,此时8有左孩子,则将左孩子入栈,并且遍历该左孩子的右子树也入栈,如图,则结果集为(8,9,6,7)

图片
4. 继续弹出栈1元素,此时为7,则此时7没有左孩子,即继续弹出栈

图片
5. 弹出栈中元素为6,则元素6有左孩子,则将左孩子5入栈1和栈2,此时为(8,9,6,7,5)

图片

  1. 继续遍历,弹出栈1元素5,此时栈为空,且5没有左孩子,则退出循环
  2. 弹出栈2的元素,此时为(5,7, 6, 9, 8)

图片

/**
 * 非递归的后序遍历: 左节点-右节点-跟节点
 * 双栈法的思路:
 *   1. 一个栈用来表示当前处理的节点,另外一个栈用来输出
 *   2. 在处理两个栈的时候,将根节点同时压入两个栈中,然后压入右子树的根节点,再压入右子树
 *   3. 直到压入的右子树没有元素压栈,弹出栈1的元素,把它的左子树压入栈1和栈2里面,直到它的右子树压完。
 */
public static void postTraversing1(Tree root) {
    // 1.判空
    if (root == null) {
        return;
    }

    // 2.栈1用来保存临时处理,栈2输出
    LinkedList<Tree> stack1 = new LinkedList<Tree> ();
    LinkedList<Tree> stack2 = new LinkedList<Tree> ();
    Tree currentNode = root;
    // 3.当前节点不为空或者栈1不为空
    while (currentNode!=null || !stack1.isEmpty()) {

        // 4.将右子树都压入栈1和栈2中
        while (currentNode != null) {
            stack1.push(currentNode);
            stack2.push(currentNode);
            currentNode = currentNode.right;
        }
        // 5.弹出栈1的元素,即右节点,然后赋值去找它的左节点
        currentNode = stack1.pop();
        currentNode = currentNode.left;
    }
    //  6.将存在栈2的元素进行遍历
    while (!stack2.isEmpty()) {
        System.out.print(stack2.pop().val+" ");
    }
}

法二:
思路: 第二种思路也是使用两个栈,它也是使用一个栈来保存当前的指向,用一个栈来 保存结果集,只不过这个结果集是和后序遍历是反着的,比如后序遍历最后保存根节点,它就先存储根节点,后序遍历倒数第二个元素是根节点的右子树的元素,它就第二个保存根节点的右子树的元素。如果把树做一个镜像,也就是所有的节点的左右子树都进行一次交换的话
注意:这里循环结束的条件是栈1中的元素为空,则跳出循环
步骤:
1.将根节点压入栈1中
图片
2.弹出栈1的元素8,将弹出的元素8压入栈2,然后将弹出的元素8的左孩子6压入栈1中,右孩子9压栈1中
图片
3.弹出栈1的元素9,将弹出的元素压入栈2,然后将弹出的元素9的左右孩子压入栈1,这里元素9没有左右孩子
图片
4.继续弹出栈1的元素6,将弹出的元素压入栈2,然后将弹出的元素6的左右孩子压入栈1,这里元素6的左孩子为元素5,右孩子为元素7,则如图

图片
5.弹出栈1的元素7,将弹出的元素7压入栈2中,则弹出的元素7没有左右孩子,继续弹出栈1

图片
6. 弹出栈1的元素5,将弹出的元素压入栈2中,则弹出的元素5没有左右孩子,继续弹出栈1

图片

7.此时栈1元素为空,跳出循环
8.弹出栈2的所有元素

/**
 *
 * 后序遍历双栈法:
 *          第二种思路也是使用两个栈,它也是使用一个栈来保存当前的指向,用一个栈来      保存结果集,只不过这个结果集是和后序遍历是反着的,比如后序遍历最后保存根节点,它就先存储根节点,后序遍历倒数第二个元素是根节点的右子树的元素,它就第二个保存根节点的右子树的元素。如果把树做一个镜像,也就是所有的节点的左右子树都进行一次交换的话
 * @param root
 */
public static void postTraversing2(Tree root) {
    // 1.判空
    if (root == null) {
        return;
    }

    // 2.栈1用来保存临时处理,栈2输出
    LinkedList<Tree> stack1 = new LinkedList<Tree> ();
    LinkedList<Tree> stack2 = new LinkedList<Tree> ();
    stack1.push(root);
    
    // 3.弹出栈1的元素
    while (!stack1.isEmpty()) {
        root = stack1.pop();
        if (root == null) {
            continue;
        }
        // 4.压入栈2元素
        stack2.push(root);
        stack1.push(root.left);
        stack1.push(root.right);

    }
    // 5.弹出栈2的元素作为结果
    while (!stack2.isEmpty()) {
        System.out.print(stack2.pop().val+" ");
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 后序遍历二叉树的算法代码如下:def postOrder(root): if root: postOrder(root.left) postOrder(root.right) print(root.data) ### 回答2: 二叉树后序遍历是指先访问左子树,再访问右子树,最后访问根节点的遍历方式。接下来给出二叉树后序遍历的算法代码的实现。 在二叉树后序遍历的算法代码实现中,我们可以使用递归或栈来辅助完成。这里给出使用递归的实现方式。 首先定义二叉树的节点数据结构: ``` class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right ``` 然后实现后序遍历的函数: ``` def postorderTraversal(root): if root is None: return [] result = [] result += postorderTraversal(root.left) # 访问左子树 result += postorderTraversal(root.right) # 访问右子树 result.append(root.val) # 访问根节点 return result ``` 代码中使用递归的方式来实现后序遍历。首先判断根节点是否为空,若为空,则返回空列表。然后递归地访问左子树,再递归地访问右子树。最后将根节点的值添加到结果列表中。 下面给出一个示例来展示如何使用该函数进行后序遍历: ``` # 创建一个二叉树 root = TreeNode(1) root.left = TreeNode(2) root.right = TreeNode(3) root.left.left = TreeNode(4) root.left.right = TreeNode(5) # 对二叉树进行后序遍历 result = postorderTraversal(root) # 输出遍历结果 print(result) # 输出 [4, 5, 2, 3, 1] ``` 以上就是二叉树后序遍历的算法代码的实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值