[路飞]145. 二叉树的后序遍历

166 阅读2分钟

145. 二叉树的后序遍历

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。

 

示例 1:

输入:root = [1,null,2,3] 输出:[3,2,1] 示例 2:

输入:root = [] 输出:[] 示例 3:

输入:root = [1] 输出:[1]  

提示:

树中节点的数目在范围 [0, 100] 内 -100 <= Node.val <= 100
解题思路:二叉树是树形结构的一种重要类型,二叉树每一个节点最多两个分支,即左右结构,二叉树有三种遍历顺序:前序遍历/中序遍历/后续遍历,这三种遍历的顺序分别是:

  1. 前序遍历:根节点 -> 左节点 -> 右节点
    2.中序遍历:左节点 -> 根节点 -> 右节点
    3.后序遍历:左节点 -> 右节点 -> 根节点
    如下图三种遍历结果分别是:
  2. 前序遍历:0137849256
    2.中序遍历:7381940526
    3.后序遍历:7839415620
    image.png

方法一:递归法

var postorderTraversal = function(root) {
    //接受遍历参数
    let res = [];
    //递归
    return postorderTraversalNode(root,res);
};

var postorderTraversalNode = function(node,res){
    if(node){
        //遍历最左边节点
        postorderTraversalNode(node.left,res);
        //遍历最右边节点
        postorderTraversalNode(node.right,res);
        res.push(node.val);
    }
    return res;
}

方法二:迭代法从节点最末尾开始遍历,将遍历得到的数通过unshift()方法加到数组最前面实现

var postorderTraversal = function(root) {
    if(!root) return [];
    //接受遍历结果
    let res = [];
    //定义一个数组默认第一个参数是二叉树
    let s1 = [root];
    while(s1.length){
        //获得第一个二叉树
        root = s1.pop();
        //保存到数组第一位(即先获取根节点),依次第二个节点,三四...
        res.unshift(root.val);
        //查查第一个节点的第一个左节点,
        if(root.left) s1.push(root.left);
         //查查第一个节点的第一个右节点,再次循环就是先找右节点,然后将右节点保存到res,然后再找上面左节点
        if(root.right) s1.push(root.right);
    }
    return res;
};

方法三:的迭代法方2,先通过while()找到最左边节点.然后将节点通过push()加到res数组,然后依次找上一个节点,判断是否存在右节点,如果有重新找最后一个左边节点,

var postorderTraversal = function(root) {
    let res = [];
     //接受遍历结果
    if(!root) return res;
    let s1 = [];
    let prev = null;//保存当前遍历节点,避免重复循环节点
    while(root || s1.length){
        //先找到最左边节点
        while(root){
            s1.push(root);
            root = root.left;
        }
        //此时找到最左边的节点
        root = s1.pop();
        //判断当前最左边节点是否有右节点,因为每次保存的都是一个二叉树结构,所以可能会存在重复右节点,当等于已遍历过得二叉树就直接获取当前节点
        if(root.right == null || root.right === prev) {
            //此时已经是最左边节点,且不存在右节点,保存节点值
             res.push(root.val);
             //保存当前节点
             prev = root;
             //寻找上一个节点
             root = null;
        }else {
            //当前节点存在右节点,所以需要找到最嘴边节点
            s1.push(root);
            //从右节点开始寻找最左边节点
            root = root.right;
        }
    }
    return res;
};