题目描述
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例 1:
输入: root = [1,null,2,3]
输出: [1,3,2]
示例 2:
输入: root = []
输出: []
示例 3:
输入: root = [1]
输出: [1]
示例 4:
输入: root = [1,2]
输出: [2,1]
示例 5:
输入: root = [1,null,2]
输出: [1,2]
提示:
- 树中节点数目在范围
[0, 100]内 -100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
题目解释
以示例 1为例,
- 前序遍历 先输出该节点,然后输出他的左孩子,最后输出他的右孩子
- [1,2,3]
- 中序遍历 先输出它的左孩子,然后输出该结点,最后输出它的右孩子
- [1,3,2]
- 后序遍历 先输出它的左孩子,然后输出它的右孩子,最后输出该结点
- [3,2,1]
解法1 递归
由中序遍历知,我们可以一层一层追踪到最左的节点,递归是最好的写的,但是效率不高。
/**
* 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 = (root) => {
if(!root){
return ;
}
//前序遍历
// res.push(root.val);
// dfs(root.left);
// dfs(root.right);
//中序遍历
dfs(root.left);
res.push(root.val);
dfs(root.right);
//后序遍历
// dfs(root.left);
// dfs(root.right);
// res.push(root.val);
}
//第一次 进入程序
dfs(root);
return res;
};
解法2 进阶 迭代
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。
但是在这个算法里,效率好像比递归还差,难道我写错了吗
/**
* 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) {
//res 记录节点 tmp 记录还没进入res的节点
let res = [],tmp = [];
//注意: root为null 但是tmp存在的情况,不然
while(root || tmp.length > 0){
//左 一直循环到最后一个左节点
while(root){
//每次 root.left 存起来
tmp.push(root);
root = root.left;
}
//获取最后一个root.left
root = tmp.pop();
//最后一个root.left 必然没有左节点,可以把val的值存进res
res.push(root.val);
//遍历右节点
root = root.right;
}
//返回结果
return res;
};