二叉树前序,中序,后序的遍历

二叉树前序,中序,后序的遍历

生成二叉树

      var tree = {
        value: 1,
        left: {
          value: 2,
          left: {
            value: 4,
            left: {
              value: 9,
            },
            right: {
              value: 10
            }
          },
          right: {
            value: 11,
            left: {
              value: 12,
            },
            right: {
              value: 13
            }
          },
        },
        right: {
          value: 3,
          left: {
            value: 5,
            left: {
              value: 7,
            },
            right: {
              value: 8,
            },
          },
          right: {
            value: 6,
          },
        },
      };

递归法

      var DLR = function(root) {
        if (Object.keys(root).length === 0) return [];
        let res = [];
        res.push(root.value); //6 5 4
        if (root.left) res = res.concat(DLR(root.left))
        if (root.right) res = res.concat(DLR(root.right))
        return res;
      }

      var LDR = function(root) {
        if(Object.keys(root).length === 0) return [];
        let res = [];
        if(root.left) res = res.concat(LDR(root.left))
        res.push(root.value)
        if(root.right) res = res.concat(LDR(root.right))
        return res;
      }

      var LRD = function(root) {
        if(Object.keys(root).length === 0) return [];
        let res = [];
        if(root.left) res = res.concat(LRD(root.left));
        if(root.right) res = res.concat(LRD(root.right));
        res.push(root.value)
        return res;
      }

    console.log(DLR(tree),LDR(tree),LRD(tree));

非递归法


      const DLR = (root) => {
        let res = [];
        let stack = [];
        stack.push(root);
        while (stack.length) {
          let node = stack.pop();
          res.push(node.value);
          if (node.right) stack.push(node.right);
          if (node.left) stack.push(node.left);
        }
        return res;
      };

      const LDR = (node) => {
        let res = [];
        let stack = [];

        while (stack.length || node) {
          if (node) {
            stack.push(node);
            node = node.left;
          } else {
            node = stack.pop();
            res.push(node.value);
            node = node.right;
          }
        }
        return res;
      };

      const LRD = (node) => {
        let result = [];
        let stack = [];
        stack.push(node);
        while (stack.length) {
          // 不能用node.touched !== 'left' 标记‘left’做判断,
          // 因为回溯到该结点时,遍历右子树已经完成,该结点标记被更改为‘right’ 若用标记‘left’判断该if语句会一直生效导致死循环
          if (node.left && !node.touched) {
            // 不要写成if(node.left && node.touched !== 'left')
            // 遍历结点左子树时,对该结点做 ‘left’标记;为了子结点回溯到该(双亲)结点时,便不再访问左子树
            node.touched = "left";
            node = node.left;
            stack.push(node);
            continue;
          }
          if (node.right && node.touched !== "right") {
            // 右子树同上
            node.touched = "right";
            node = node.right;
            stack.push(node);
            continue;
          }
          node = stack.pop(); // 该结点无左右子树时,从栈中取出一个结点,访问(并清理标记)
          node.touched && delete node.touched; // 可以不清理不影响结果 只是第二次对同一颗树再执行该后序遍历方法时,结果就会出错啦因为你对这棵树做的标记还留在这棵树上
          result.push(node.value);
          node = stack.length ? stack[stack.length - 1] : null;
          //node = stack.pop(); 这时当前结点不再从栈中取(弹出),而是不改变栈数据直接访问栈中最后一个结点
          //如果这时当前结点去栈中取(弹出)会导致回溯时当该结点左右子树都被标记过时 当前结点又变成从栈中取会漏掉对结点的访问(存入结果数组中)
        }
        return result; // 返回值
      };

      console.log(DLR(tree), LDR(tree), LRD(tree));

参考文献

js 中二叉树的深度遍历与广度遍历(递归实现与非递归实现)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MaxLoongLvs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值