leetcode 94二叉树的中序遍历

157 阅读2分钟

94.二叉树的中序遍历

给定一个二叉树的根节点 root ,返回它的 中序 遍历。

示例 1:

输入:root = [1,null,2,3]
输出:[1,3,2]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [1]
输出:[1]

提示:

  • 树中节点数目在范围 [0, 100] 内
  • -100 <= Node.val <= 100 解题思路:

方法1:递归

按照左子树——根节点——右子树的顺序访问这棵树,
在访问左子树或者右子树的时候按照同样的方式遍历,
直到遍历完整棵树。
var inorderTraversal = function(root) {
    let res=[];
    inorder(res,root);
    return res;
};
function inorder(res,root){
    if(root){
        inorder(res,root.left);
        res.push(root.val);
        inorder(res,root.right);
    }  
}

方法2:迭代,使用栈维护左子树

1.根节点入栈->2.左子树入栈->3.弾栈,访问节点->
- 4.1 有右子树,将右子节点视为根节点,重复步骤1234
- 4.2 无右子树,重复步骤34
var inorderTraversal = function(root) {
  let stack=[],result=[];
  while(root || stack.length){
      while(root){
        stack.push(root);
        root=root.left;  
      }
      root=stack.pop();
      result.push(root.val);
      root=root.right;
  }
  return result;
};

方法3:使用指针指示根节点的中序遍历前驱节点

假设当前遍历到的节点为 root,
- 如果 root 无左孩子,先将root.val的值加入result数组,再访问root的右子树
- 如果 root 有左孩子,则找到root左子树上最右的节点(即root 在中序遍历中的前驱节点)pre,
    - 如果pre的右孩子为空,则将其右孩子指向root,即pre.right=root,然后访问root的左子树
    - 如果pre的右孩子不为空,则此时有pre.right==root,说明已经访问完root的左子树,
    此时将pre的右孩子置空,然后将root.val的值加入result数组,再访问root的右孩子,
重复上述操作,直至访问完整棵树。
var inorderTraversal = function(root) {
    let res=[],pre=null;
    while(root){
        if(root.left){
            pre=root.left;
            while(pre.right && pre.right!==root){
                pre=pre.right;
            }
            if(!pre.right){
                pre.right=root;
                root=root.left;
            }else{
                pre.right=null;
                res.push(root.val);
                root=root.right;
            }
        }else{
            res.push(root.val);
            root=root.right;
        }
    }
    return res;
};