二叉树基础 -后序遍历二叉树

本文详细讲解了如何进行二叉树的后序遍历,包括递归和非递归两种方法。递归法按照左子树、右子树、根节点的顺序进行。非递归法通过栈来实现,重点在于正确处理根节点的出栈时机,确保遍历完整个右子树。示例展示了具体操作过程,并提供了力扣(LeetCode)的题目链接。

1. 题目描述

给定一个二叉树,返回它的 后序 遍历。

示例:
输入: [1,null,2,3]
1
\
2
/
3

输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 题解

1. 递归

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
//左右根
var postorderTraversal = function(root) {
    const res = [];
    function dfs(root){
        if(root === null){
            return;
        }
        dfs(root.left);
        dfs(root.right);
        res.push(root.val);
    }
    dfs(root);
    return res;
};

2. 非递归

思路:后序遍历是 左右根,和中序不同的是,在没遍历到右子节点时该根节点不能真正出栈,否则接下来遍历不到右子节点。

  • 遍历直至遇到最左节点停下;
  • 开始出栈,出栈节点记为root;
  • 若该root没有右子节点 或 右子节点已经存入结果数组,可以出栈,并用变量preNode记录下root,root置为null;
  • 否则该root再入栈,并令root = root.right,循环继续;
//左右根
var postorderTraversal = function(root) {
    const res = [];
    const stack = [];
    let preNode; //记录上一次存入结果数组的右子节点
    while(root || stack.length > 0){
        //找到最左节点
        while(root){
            stack.push(root);
            root = root.left;
        }
        if(stack.length > 0){
            //出栈
            root = stack.pop();
            //如果右子节点已经存入结果数组,则该root可以真正出栈
            if(root.right == null || root.right == preNode){
                //没有右子节点,可以真正出栈并存入结果数组
                res.push(root.val);
                preNode = root;
                root = null;
            }else{
                //有右子节点,再次入栈
                stack.push(root);
                root = root.right;
            }
        }
    }
    return res;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值