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

news/2024/11/16 20:47:59/

文章目录

  • 二叉树
    • 递归法
    • 迭代法
  • 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) {// 最开始出栈的是根节点rootcur = 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) returndfs(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 = rootwhile(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) returndfs(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 resconst stack = [root]let cur = nulldo {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.ppmy.cn/news/60077.html

相关文章

Python---正则表达式与递归

1. 正则表达式: 是一种字符串验证的规则,通过特殊的字符串组合来确立规则 用规则去匹配字符串是否满足 如(^[\w-](\.[\w-])*[\w-](\.[\w-])$)可以表示为一个标准邮箱的格式 re模块的三个主要方法: re.match: re.match(匹配规…

最新VUE面试题

前言 本文以前端面试官的角度出发,对 Vue 框架中一些重要的特性、框架的原理以问题的形式进行整理汇总,意在帮助作者及读者自测下 Vue 掌握的程度。 本文章节结构以从易到难进行组织,建议读者按章节顺序进行阅读,当然大佬级别的…

用 C# 实现独占音频设备降低其它程序的音量

C#调用 Windows 辅助功能 API "AccSetRunningUtilityState" 函数实现音频避闪功能 音频闪避是指当自身应用程序,例如辅助功能程序,正在播放音频的时候,降低其他应用程序的音量。这样可以让用户更清楚地听到自身应用程序的音频&…

自动控制原理笔记-根轨迹法

目录 一,根轨迹的基本概念 1.根轨迹的基本概念 2.根轨迹方程 3.根轨迹方程的应用 二,根轨迹的绘制规则 【规则一】根轨迹有n条分支: 【规则二】根轨迹对称于实轴: 【规则三】根轨迹的起点和终点: 【规则四】…

Shell脚本3

环境变量 1、系统全局环境变量文件: /etc/profile 2、设置环境变量:export var_namevalue 注意环境变量建议变量名全部大写 3、修改 /etc/profile文件后, 立刻加载修改的数据配置 source /etc/profile shell环境分类 交互式:…

全栈成长-python各数据类型之间的转换

python数据类型的转换 字符串与数字之间的转换 原始类型目标类型函数举例整型字符串strstr(123)>“123”浮点型字符串strstr(3.14)>“3.14”字符串整型intint(“123”)>123 int(3.14)>报错字符串浮点型floatfloat(“3.14”)>3.14 float(“314”)>314.0 其他…

与chatGPT谈TyptScript接口问题

与chatGPT谈TyptScript接口问题 问1:能给我说说c#中的inteface 与typescript 中的inteface的不同与相同吗? 答1: C# 中的 Interface 和 TypeScript 中的 Interface 有一些相似之处,但也有一些不同之处。 相同点: …

SpringBoot+Shiro+Jwt+Vue+elementUI实现前后端分离单体系统Demo

记录一下使用SpringBoot集成Shiro框架和Jwt框架实现前后端分离Web项目的过程,后端使用SpringBoot整合ShiroJwt(auth0),前端使用vueelementUI框架,前后端的交互使用的是jwt的token,shiro的会话关闭,后端只需要使用Shiro…