JavaScript:二叉树(前序遍历,中序遍历,后序遍历,递归法,统一迭代法)

文章目录

  • 二叉树
    • 递归法
    • 迭代法
  • 144. 二叉树的前序遍历 - 力扣(LeetCode)
    • 二叉树的递归遍历
      • 递归法作图分析
      • 代码和思路分析
    • 二叉树的迭代遍历
      • 前序遍历迭代分析
      • 代码及思路分析
  • 94. 二叉树的中序遍历
    • 递归法
      • 作图举例递归流程
    • 迭代法
      • 代码
  • 145. 二叉树的后序遍历 - 力扣(LeetCode)
    • 递归法
    • 迭代法
  • 二叉树的统一迭代法
    • 前序遍历统一的迭代法
    • 中序遍历统一的迭代法
    • 后序遍历统一的迭代法

二叉树

在这里插入图片描述

递归法

在这里插入图片描述

迭代法

144. 二叉树的前序遍历 - 力扣(LeetCode)

二叉树的递归遍历

递归法作图分析

在这里插入图片描述

代码和思路分析

/**
* @param {TreeNode} root
* @return {number[]}
*/
var preorderTraversal = function(root) {
   /* 
       前序遍历:根左右
       我们用一个栈存入结果
       递归:顺序就是根左右,然后左右又分别是根,再根左右,循环,操作都一致了,可以使用递归
    */
   let res = []
   const dfs = function(root) {
       // 遇到空值,终止执行
       if(root === null) return;
       // 前序遍历从父节点开始
       res.push(root.val)
       // 之后会再压入左节点,右节点,然后每个节点的子节点,循环,使用递归
       // 左子树递归
       dfs(root.left)
       // 右子树递归
       dfs(root.right)
   }
   dfs(root)
   return res
};

二叉树的遍历除了递归还有迭代

二叉树的迭代遍历

非递归,遍历
用栈也可以实现前中后

前序遍历迭代分析

在这里插入图片描述
前序遍历是根左右
我们先让根节点入栈,然后让右节点入栈,再左节点
为什么先右后左?这样出栈的时候就可以达到根左右的效果
入栈:右–>左
出栈:根–>左–>右

代码及思路分析

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    let res = []
    if(!root) return res
    // 把根节点存入栈中
    const stack = [root]
    let cur = null
    // 遍历栈里面的元素
    while(stack.length) {
        // 最开始出栈的是根节点root
        cur = stack.pop()
        // 把出栈的节点的值压入res存起来
        res.push(cur.val)
        // 然后分别把存在的右节点 左节点压入栈,之后循环,弹出左节点,右节点
        cur.right && stack.push(cur.right)
        cur.left && stack.push(cur.left)
    }
    return res
};

前序遍历解决了,中序遍历和后序遍历就好解决了

94. 二叉树的中序遍历

递归法

作图举例递归流程

在这里插入图片描述
代码

/*
 * @lc app=leetcode.cn id=94 lang=javascript
 *
 * [94] 二叉树的中序遍历
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
    /**
     * 中序遍历  递归左子树,压入根,递归右子树
     */
    let res = []
    const dfs = function(root) {
        if(root === null) return
        dfs(root.left)
        res.push(root.val)
        dfs(root.right)
    }
    dfs(root)
    return res
};
// @lc code=end

迭代法

迭代法分析
在这里插入图片描述

中序遍历:左根右
入栈:左 --> 右
出栈:左 --> 中 --> 右

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
    let res = []
    const stack = []
    let cur = root
    while(stack.length || cur) { 
        /* 
            开始根节点存在,if语句执行,先让根节点入栈,然后让所有的左节点入栈
            当没有左节点的时候,执行else,弹出当前的末尾的左节点并且存入res中,再看右节点
         */
        if(cur) {
            // 根节点入栈
            stack.push(cur)
            // 左
            cur = cur.left
        } else {
            // 弹出
            cur = stack.pop()
            res.push(cur.val)
            // 右
            cur = cur.right
        }
    }
    return res
    
};

145. 二叉树的后序遍历 - 力扣(LeetCode)

递归法

/*
 * @lc app=leetcode.cn id=145 lang=javascript
 *
 * [145] 二叉树的后序遍历
 */

// @lc code=start
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
    /**
     * 后序遍历:左右根  左递归 右递归 压入根
     */
    let res = []
    const dfs = function(root) {
        if(root === null) return
        dfs(root.left)
        dfs(root.right)
        res.push(root.val)
    }
    dfs(root)
    return res
};
// @lc code=end

迭代法

入栈:左 --> 右
出栈: 中 --> 右 --> 左 结果翻转

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
    let res = []
    if(!root) return res
    const stack = [root]

    let cur = null

    do {
        cur = stack.pop()
        res.push(cur.val)
        cur.left && stack.push(cur.left)
        cur.right && stack.push(cur.right)
    } while(stack.length)
    return res.reverse()
};

好多问题画图就可以迎刃而解
算法一遍不熟,大不了就多刷一遍,我都第三遍了

二叉树的统一迭代法

二叉树:一入递归深似海,从此offer是路人
递归至今我还不会?!!

前序遍历统一的迭代法

// 前序遍历:中左右
// 压栈顺序:右左中

var preorderTraversal = function(root, res = []) {
   const stack = [];
   if (root) stack.push(root);
   while(stack.length) {
       const node = stack.pop();
       if(!node) {
           res.push(stack.pop().val);
           continue;
       }
       if (node.right) stack.push(node.right); // 右
       if (node.left) stack.push(node.left); // 左
       stack.push(node); // 中
       stack.push(null);
   };
   return res;
};

中序遍历统一的迭代法

//  中序遍历:左中右
//  压栈顺序:右中左
 
var inorderTraversal = function(root, res = []) {
    const stack = [];
    if (root) stack.push(root);
    while(stack.length) {
        const node = stack.pop();
        if(!node) {
            res.push(stack.pop().val);
            continue;
        }
        if (node.right) stack.push(node.right); // 右
        stack.push(node); // 中
        stack.push(null);
        if (node.left) stack.push(node.left); // 左
    };
    return res;
};

后序遍历统一的迭代法

// 后续遍历:左右中
// 压栈顺序:中右左
 
var postorderTraversal = function(root, res = []) {
    const stack = [];
    if (root) stack.push(root);
    while(stack.length) {
        const node = stack.pop();
        if(!node) {
            res.push(stack.pop().val);
            continue;
        }
        stack.push(node); // 中
        stack.push(null);
        if (node.right) stack.push(node.right); // 右
        if (node.left) stack.push(node.left); // 左
    };
    return res;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/18206.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

制作Alpine Linux镜像报错errors: 15 distinct packages available

1.执行报错 执行docker build -t 镜像:版本 -f Dockerfile . 报错: 2.查看网上的解决思路 网上文档解决思路: 这边我做了一下改变把这些写入了dockerfile 加了几个RUN RUN rm -rf /var/cache/apk RUN mkdir -p /var/cache/apk RUN apk update -v 发现还…

mongodb分片集群搭建

1.本次搭建使用三台centos7主机搭建伪集群,关闭防火墙和selinux服务 2.mongodb架构相当于9个分片节点,3个路由节点,3个配置节点,主机信息如下图所示 主机名称主机ip地址端口服务A10.1.60.11420001,21001,…

Visual Studio 2019离线安装包获取和安装教程

摘要 介绍Visual Studio 2019离线安装方法和配置及注意事项 关键词 VS2019 离线安装 Visual Studio 2019版本与以往的2015、2013、2012版本不同,采用了新的模块化安装方法。微软官方也并未提供ISO镜像,根据官方提供的离线下载方案(docs.mic…

JMeter开发web及手机APP自动化脚本练习

(一)开发web自动化脚本练习 一、打开浏览器代理服务器设置 我这里用的是360浏览器,打开浏览器代理服务器设置,端口要与jmeter中的端口设置保持一致哦。 二、JMeter设置代理 JMeter设置代理(jmeter中的端口要与360浏览…

数据发送流程

在发送模式下,UART 的串行数据发送电路主要包括一个发送移位寄存器(TSR),TSR 功能是将数据 逐个移位送出。待发数据必须先写到发送缓冲区中。 TXIFx 是发送中断标志位,可配置为发送缓冲区空或TSR 空。 数据的发送支持7bit 、8bit 或9bit 数据…

JAVA基础:Scanner类中next(), nextLine(), hasNext(), hasNextLine()

一、next() : 只读缓冲区中空格之前的数据,并且光标指向本行。二、nextLine() : 读取除回车以外的所有符号(整行内容),光标定位在下一行三、hasNext() :检查下一个标记(token),也就是以空格、制表符或换行符为分隔符的…

大数据技术之Kettle

目录 第1章 Kettle概述 1.1 ETL简介 1.2 Kettle简介1.2.1 Kettle是什么 1.2.2 Kettle的两种设计 1.2.3 Kettle的核心组件 1.2.4 Kettle特点 第2章 Kettle安装部署 2.1 Kettle下载 2.1.1 下载地址 2.1.2 Kettle目录说明 2.1.3 Kettle文件说明 2.2 Kettle安装部署 …

YonLinker连接集成平台构建新一代产业互联根基

近日,由用友公司主办的“2023用友BIP技术大会“在用友产业园(北京)盛大召开,用友介绍了更懂企业业务的用友BIP-iuap平台,并发布了全面数智化能力体系,助力企业升级数智化底座,加强加速数智化推进…

mysql数据库之索引

1.索引的相关知识 1.1 索引的简介 索引是一个排序的列表,在这个列表中存储着索引的值和包含这个值的数据所在行的物理地址(类似于c语言的链表通过指针指向数据记录的内存地址)。使用索引后可以不用扫描全表来定位某行的数据,而是…

PCL学习六:Filtering-滤波

参考引用 Point Cloud Library黑马机器人 | PCL-3D点云 1. 点云滤波概述 1.1 背景 在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,以及电磁波衍射特性、被测物体表面性质变化和数据拼接配准操作过程的影响,点云数据中将…

大型数据库期末总复习【SQL server 2008 基础教程】

一、概述 1.Microsoft SQL Server系统的体系结构 Microsoft SQL Server 2008系统由4个主要部分组成。这4个部分被称为4个服务,这些服务分别是数据库引擎、分析服务、报表服务和集成服务。这些服务之间相互存在和相互应用,它们的关系示意图如图所示&…

“世界中医药之都” 亳州市医保局领导一行莅临万民健康交流指导

为进一步推进智慧医疗、智慧服务、智慧管理“三位一体”为主旨的“智慧中医、健康社区”项目建设。2023 年 5 月 3 日,“世界中医药之都” 亳州市医保局 局长 吴旭春 、 医保中心主任秦克靖 、 办公室主任徐伟 等一行 5 人莅临 万民健康交流 指导工作 &#xff0c…

JQuery实现自定义滚动条

在页面中虽然可以通过CSS修改滚动条的样式,但是部分属性是无法自己修改和设置的,而且不同浏览器存在兼容问题,因此通过JS来实现滚动条在自定义滚动条的环境下也是有必要的。 接下来,我们来实现上图两种情况下滚动条的实现。 一、页面搭建 1.…

白宫召见科技巨头 讨论AI潜在风险 以确保人们从创新中受益

ChatGPT的问世,被认为是通用人工智能发展的“奇点”和强人工智能即将到来的“拐点”,甚至有业内人士推测所有数字化系统和各个行业都可能被其重新“洗牌”。 乐观主义者表示,人工智能的核心是对人类大脑的模拟,其目的是延伸和增强…

mysql数据库之事务

1.事务的概念 事务是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个 整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行。 事务是一个不可分割的工作逻辑单元&#xf…

ES6-Class类

ES6 提供了更接近传统语言的写法,引入了 Class (类)这个概念,作为对 象的模板。通过 class 关键字,可以定义类。基本上, ES6 的 class 可以看作只是 一个语法糖,它的绝大部分功能&…

代码随想录算法训练营第三十二天 | 利润题、覆盖范围题

122.买卖股票的最佳时机II 文档讲解:代码随想录 (programmercarl.com) 视频讲解:贪心算法也能解决股票问题!LeetCode:122.买卖股票最佳时机II_哔哩哔哩_bilibili 状态:根本做不出来,思路太巧了。 思路 想获…

DT7遥控DBUS协议解析

文章目录 运行环境:1.1 DBUS协议解析1)DT7遥控2)配置串口引脚3)配置串口接收DMA 2.1例程代码移植1)例程移动到 Inc 和 Src2)makefile添加.c文件 3.1核心代码解释4.1代码修改1)bsp_rc.c 和 remote_control.c2)调用代码 5.1调试1)硬件接线2)串口工具监视拨杆数据 运行…

【C++】哈希

一、unordered系列关联式容器 在C98中,STL提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 l o g 2 N log_2 N log2​N,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。 …

Linux学习之Shell(一)

Shell概述 1)Linux提供的Shell解析器有 [xiaominghadoop101 ~]$ cat /etc/shells /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin /bin/tcsh /bin/csh2)bash和sh的关系 [xiaominghadoop101 bin]$ ll | grep bash -rwxr…
最新文章