二叉树的前序,中序,后序遍历【详细】【JS实现】

1.常用的二叉树的遍历方式:

(1)前序遍历:根、左、右;
(2)中序遍历:左、根、右;
(3)后续遍历:左、右、根;

因为前序遍历和后序遍历比较像,所以我们先上考察比较多的中序遍历

2.中序遍历

2.1栈方法
  • 当前节点存在,就存入栈中,并访问左子树

  • 直到当前节点不存在,就出栈放入结果数组,并通过栈顶节点访问右子树

  • 不断重复前面两步,直到当前节点不存在且栈为空

  • 图画演示:

    • 从1到4都存在,于是依次存入栈中,访问4的左子树,左子树不存在,将4出栈放入数组,访问4的右子树,右子树不存在,继续从栈顶取出3,访问3的右子树,3的右节点存在,所以将5入栈
      在这里插入图片描述

在这里插入图片描述

  • 5入栈,访问其左子树,左子树不存在,即将5取出栈顶,并访问其右子树,右子树为空,即将2取出栈顶,并访问其右子树,其右子树为空,即将栈顶1取出,访问1的右子树,右子树为6,将6入栈,反复…
    在这里插入图片描述
    在这里插入图片描述

  • 通过上面图表可知,每次查找的节点不存在时,即出栈;最后栈为空,没有下一节点的时候结束

  • 代码为:

let inOrderTraversal = function(root) {
    if(!root) return [];
    const stack = []; //先定义一个栈
    const res = []; //定义存放最后顺序结果的数组
    let cur = root ; //指向树的首结点
    while(cur || stack.length!=0){
        //左节点依次压入栈中
        while(cur){
            stack.push(cur);
            cur = cur.left;
        }
        //跳出上面的循环说明左节点为空了,那此时应该从栈顶取出元素
        let node = stack.pop();
        res.push(node.val);
        //查找其右节点,若存在,cur指向该节点
        if(node.right != null){
            cur = node.right
        }
    }
    return res
} 
2.2递归方法
  • 左子树——根节点——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候我们按照同样的方式遍历,直到遍历完整棵树
let inOrderTraversal = function(root,arr=[]){
    if(root){
        inOrderTraversal(root.left,arr);
        arr.push(root.val);
        inOrderTraversal(root.right,arr);
    }
    return arr;
}

3.前序遍历

3.1栈方法
  • 将父节点压入栈中

  • 执行出栈操作,放入结果数组

  • 每次将出栈的节点的右孩子先压入栈中,其次压入左孩子节点

  • 重复执行第2,3步…

  • 图画演示

    • 一开始先将父节点1压入栈中,将1出栈,放入结果数组,将其右节点6压入栈中,将其左节点2压入栈中;将2出栈,2没有右节点,所以将其左节点3压入栈中;
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    • 然后将3出栈,放入结果数组,将其右节点5,左节点4压入栈中;将4出栈放入结果数组,无左右节点;将5出栈放入结果数组,无左右节点;将6出栈放入结果数组,将其右节点8,右节点7放入栈中;将7出栈放入结果数组,无左右节点,将8出栈放入结果数组,无左右节点
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

  • 代码为:

let preOrderTraversal = function(root){
    if(!root) return []; 
    const res = []; //结果数组
    const stack = [root]; //栈中先放入根节点
    while(stack.length!=0){
        let node = stack.pop(); //出栈
        res.push(node.val); //放入结果数组
        if(node.right) stack.push(node.right); //先将右节点压入栈
        if(node.left) stack.push(node.left); //再将左节点压入栈
    }
    return res
}
3.2递归方法
  • 根节点——左子树——右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树
let preOrderTraversal = function(root,arr=[]) {
    if(root){
        arr.push(root.val);
        preOrderTraversal(root.left,arr);
        preOrderTraversal(root.right,arr);
    }
    return arr
};

4、后序遍历

4.1栈方法
  • 将父节点压入栈中

  • 执行出栈操作,放入结果数组(与前序的区别就是这里是在头部插入!!)

  • 每次将出栈的节点的左孩子先压入栈中,其次压入右孩子节点

  • 重复执行第2,3步…

  • 图画演示

    • 首先还是根节点1入栈出栈,放入结果数组,将其左节点2,右节点6压入栈中;取出栈顶节点6,插入结果数组头部,将6的左节点7,右节点8压入栈中;取出栈顶节点8,插入结果数组头部;取出栈顶节点7,插入结果数组头部
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    • 取出栈顶节点2,插入结果数组头部,将2的左节点3压入栈中;取出栈顶节点3,插入结果数组头部,将其左节点4,右节点5压入栈中;取出栈顶节点5,插入结果数组头部;取出栈顶节点4,插入结果数组头部
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

  • 代码为:

let postOrderTraversal = function(root) {
    if(!root) return []; 
    const res = [];
    const stack = [root]; 
    while(stack.length!=0){
        let node = stack.pop();
        res.unshift(node.val); //记住这里是头部插入
        if(node.left) stack.push(node.left); //先压入左节点
        if(node.right) stack.push(node.right); //再压入右节点
    }
    return res
};
4.2递归方法
let postOrderTraversal = function(root,arr=[]) {
    if(root){
        postOrderTraversal(root.left,arr);
        postOrderTraversal(root.right,arr);
        arr.push(root.val);
    }
    return arr
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值