• 二叉树的 前、中、后 序遍历(JS版)


    首先,来了解下3中遍历方式的区别:

    【前序遍历】按照 根、左、右 的次序进行遍历

    【中序遍历】按照 左、根、右 的次序进行遍历

    【后序遍历】按照 左、右、根 的次序进行遍历

    树节点的结构

    /**
     * 单个树节点的结构
     * @param {number} val
     * @param {TreeNode} left
     * @param {TreeNode} right
     */
    function TreeNode(val = 0, left = null, right = null) {
      this.val = val;
      this.left = left;
      this.right = right;
    }

    然后,我们再来熟悉一下二叉树这3种遍历的递归实现

    1. 前序遍历

    /**
     * @param {TreeNode} root
     * @return {number[]}
     */
    var preorderTraversal = function(root) {
      if (root === null) return [];
      // 按前序的次序来存储节点的值
      const ans = [];
      /**
       * 递归遍历树节点
       */
      const traversal = (node) => {
        // 如果该子节点不存在,则终止递归
        if (node === null) return;
        // 处理当前节点
        ans.push(node.val);
        // 处理当前节点的左子树
        traversal(node.left);
        // 处理当前节点的右子树
        traversal(node.right);
      };
      traversal(root);
    
      return ans;
    };

    2. 中序遍历

    // 思路同上,只需将部分代码调整如下
    
    // ...
        // 处理当前节点的左子树
        traversal(node.left);
        // 处理当前节点
        ans.push(node.val);
        // 处理当前节点的右子树
        traversal(node.right);
    // ...

    3. 后序遍历

    // 思路同上,只需将部分代码调整如下
    
    // ...
        // 处理当前节点的左子树
        traversal(node.left);
        // 处理当前节点的右子树
        traversal(node.right);
        // 处理当前节点
        ans.push(node.val);
    // ...

    遍历版本


    前序

    // 二叉树的前序遍历
    var preorderTraversal = function(root) {
        if (root === null) return [];
        // 使用栈保存尚未读取值的树节点
        const stk = [root];
        // 保存遍历过后的节点值
        const ans = [];
    
        while (stk.length > 0) {
            // 推出栈顶节点,访问其值并处理其左右子节点
            const node = stk.pop();
            ans.push(node.val);
            if (node.right !== null) stk.push(node.right);
            if (node.left !== null) stk.push(node.left);
        }
        
        return ans;
    };

    中序

    // 二叉树的中序遍历
    var inorderTraversal = function(root) {
        if (root === null) return [];
        // 存放节点值
        const ans = [];
        // 存放未访问过的节点
        const stk = [];
        // 节点指针
        let cur = root;
    
        // 按照左 中 右遍历节点
        while (cur !== null || stk.length > 0) {
            // 先将当前轮次可以遍历到的左子节点推入栈
            while (cur !== null) {
                stk.push(cur);
                cur = cur.left;
            }
            // 取出栈顶节点
            const node = stk.pop();
            ans.push(node.val);
            // 如果存在右子节点,则相应地对其进行遍历
            if (node.right !== null) cur = node.right;
        }
    
        return ans;
    };

    后序

    // 后序遍历
    var postorderTraversal = function(root) {
        if (root === null) return [];
        // 后序遍历次序是左右根
        // 前序遍历次序是根左右(尝试将其变化为 根右左 后进行反转)
    
        const stk = [root];
        const ans = [];
        while (stk.length > 0) {
            const node = stk.pop();
            ans.push(node.val)
            if (node.left !== null) stk.push(node.left);
            if (node.right !== null) stk.push(node.right);
        }
    
        return ans.reverse();
    };

    End

  • 相关阅读:
    http 请求code状态码
    uni-app实现弹窗遮罩
    小程序分享报错 Cannot read property 'apply' of null;at page XXX onShareAppMessage function
    mac下出现xcrun: error导致git、svn无法使用的解决办法
    uniapp 小程序实现自定义底部导航栏(tarbar)
    Python2.X和Python3.X中Tkinter模块的文件对话框、下拉列表的不同
    Mac 设置git的template
    每天一点点之vue框架开发
    uni-app开发小程序-使用uni.switchTab跳转后页面不刷新的问题
    小程序实现微信朋友圈时间显示效果
  • 原文地址:https://www.cnblogs.com/fanqshun/p/15996535.html
Copyright © 2020-2023  润新知