1、二叉树先序,中序,后序遍历的递归和非递归方法(JS实现)。

查找某个节点的路径的方法通常有两种,一种是递归算法,另一种是非递归算法

以中序遍历为例

1、定义树节点

class TreeNode{
    constructor(value){
        this.value = value;
        this.left = null;
        this.right = null;
    }
}

2、构建树

// 构建树
let root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
console.log(root);//如下图

在这里插入图片描述

递归算法

// 递归中序遍历二叉树
function midOrder(root) { 
    if(!root || !(root instanceof TreeNode)){
        return;
    }
    //instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
    // 递归访问左子树
    midOrder(root.left);
    console.log(root.value);
    // 递归访问右子树
    midOrder(root.right);
}
midOrder(root);

非递归算法

// 非递归中序遍历二叉树
function midOrderN(root) { 
    let p = root; // p为当前遍历的节点, 初始为根
    let arr = []; // arr作为栈
    while(p || arr.length !== 0){
        if(p){
            // 遍历左子树
            arr.push(p);
            // 每遇到非空二叉树先向左走
            p = p.left;
        }else{
            // p为空,出栈
            let node = arr.pop();
            // 访问该节点
            console.log(node.value);
            // 向右走一次
            p = node.right;
        }
    }
 }
 midOrderN(root)

前序、中序、后序

以下为牛客网的试题

递归写法

function TreeNode(x){
    this.val=val;
    this.left=null;
    this.right=null;
}
// 递归方法
function threeOrders(root){
    let preArray=[],middleArray=[],lastArray=[];
    //先序遍历:根、左、右
    function preOrder(root){
        if(root){
            preArray.push(root.val);
            preOrder(root.left);
            preOrder(root.right);
        }
    }
    //中序遍历 : 左 根 右   
    function inOrder(root){
            if(root){
                inOrder(root.left)
                middleArray.push(root.val);
                inOrder(root.right);
            }
    }
    //后序遍历:左右根
    function lastOrder(root){
        if(root){
            lastOrder(root.left);
            lastOrder(root.right);
            lastArray.push(root.val);
        }
    }
    preOrder(root);
    inOrder(root);
    lastOrder(root);
    return [preArray,middleArray,lastArray]
}

非递归写法

function threeOrders(root){
    //非递归算法实现先序遍历二叉树,根左右,所以向数组中push一个元素
    function preOrder(root){
        let res=[],
        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.right);
            }

        }
        return res;
    }
    //非递归算法 实现中序遍历二叉树   首先遍历找到最深层的左子树,
    function inOrder(root){
        let res=[],
            stack=[];
            while(root||stack.length>0){
                while(root){
                    stack.push(root);
                    root=root.left;
                }
                root=stack.pop();
                res.push(root.val);
                root=root.right;
            }
            return res;
    }
    // 非递归算法实现后序遍历二叉树, 和先序遍历二叉树类似,唯一区别是向数组中unshift元素,先push左再push右
    function lastOrder(root){
        let res=[],
        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;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值