返回介绍

Binary Tree Inorder Traversal

发布于 2025-02-22 13:01:28 字数 5617 浏览 0 评论 0 收藏 0

Source

Problem

Given a binary tree, return the inorder traversal of its nodes' values.

Example

Given binary tree {1,#,2,3} ,

   1
  \
   2
  /
   3

return [1,3,2] .

Challenge

Can you do it without recursion?

题解 1 - 递归版

中序遍历的访问顺序为『先左再根后右』,递归版最好理解,递归调用时注意返回值和递归左右子树的顺序即可。

Python

"""
Definition of TreeNode:
class TreeNode:
  def __init__(self, val):
    this.val = val
    this.left, this.right = None, None
"""


class Solution:
  """
  @param root: The root of binary tree.
  @return: Inorder in ArrayList which contains node values.
  """
  def inorderTraversal(self, root):
    if root is None:
      return []
    else:
      return [root.val] + self.inorderTraversal(root.left) \
                + self.inorderTraversal(root.right)

Python - with helper

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, x):
#     self.val = x
#     self.left = None
#     self.right = None

class Solution:
  # @param {TreeNode} root
  # @return {integer[]}
  def inorderTraversal(self, root):
    result = []
    self.helper(root, result)
    return result

  def helper(self, root, ret):
    if root is not None:
      self.helper(root.left, ret)
      ret.append(root.val)
      self.helper(root.right, ret)

C++

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *   int val;
 *   TreeNode *left;
 *   TreeNode *right;
 *   TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
  vector<int> inorderTraversal(TreeNode* root) {
    vector<int> result;
    helper(root, result);
    return result;
  }

private:
  void helper(TreeNode *root, vector<int> &ret) {
    if (root != NULL) {
      helper(root->left, ret);
      ret.push_back(root->val);
      helper(root->right, ret);
    }
  }
};

Java

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *   int val;
 *   TreeNode left;
 *   TreeNode right;
 *   TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
  public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<Integer>();
    helper(root, result);
    return result;
  }

  private void helper(TreeNode root, List<Integer> ret) {
    if (root != null) {
      helper(root.left, ret);
      ret.add(root.val);
      helper(root.right, ret);
    }
  }
}

源码分析

Python 这种动态语言在写递归时返回结果好处理点,无需声明类型。通用的方法为在递归函数入口参数中传入返回结果, 也可使用分治的方法替代辅助函数。

复杂度分析

树中每个节点都需要被访问常数次,时间复杂度近似为 O(n)O(n)O(n). 未使用额外辅助空间。

题解 2 - 迭代版

使用辅助栈改写递归程序,中序遍历没有前序遍历好写,其中之一就在于入栈出栈的顺序和限制规则。我们采用「左根右」的访问顺序可知主要由如下四步构成。

  1. 首先需要一直对左子树迭代并将非空节点入栈
  2. 节点指针为空后不再入栈
  3. 当前节点为空时进行出栈操作,并访问栈顶节点
  4. 将当前指针 p 用其右子节点替代

步骤 2,3,4 对应「左根右」的遍历结构,只是此时的步骤 2 取的左值为空。

Python

# Definition for a binary tree node.
# class TreeNode:
#   def __init__(self, x):
#     self.val = x
#     self.left = None
#     self.right = None

class Solution:
  # @param {TreeNode} root
  # @return {integer[]}
  def inorderTraversal(self, root):
    result = []
    s = []
    while root is not None or s:
      if root is not None:
        s.append(root)
        root = root.left
      else:
        root = s.pop()
        result.append(root.val)
        root = root.right

    return result

C++

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *   int val;
 *   TreeNode *left, *right;
 *   TreeNode(int val) {
 *     this->val = val;
 *     this->left = this->right = NULL;
 *   }
 * }
 */
class Solution {
  /**
   * @param root: The root of binary tree.
   * @return: Inorder in vector which contains node values.
   */
public:
  vector<int> inorderTraversal(TreeNode *root) {
    vector<int> result;
    stack<TreeNode *> s;

    while (!s.empty() || NULL != root) {
      if (root != NULL) {
        s.push(root);
        root = root->left;
      } else {
        root = s.top();
        s.pop();
        result.push_back(root->val);
        root = root->right;
      }
    }

    return result;
  }
};

Java

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *   int val;
 *   TreeNode left;
 *   TreeNode right;
 *   TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
  public List<Integer> inorderTraversal(TreeNode root) {
    List<Integer> result = new ArrayList<Integer>();
    if (root == null) return result;

    Deque<TreeNode> stack = new ArrayDeque<TreeNode>();
    while (root != null || (!stack.isEmpty())) {
      if (root != null) {
        stack.push(root);
        root = root.left;
      } else {
        root = stack.pop();
        result.add(root.val);
        root = root.right;
      }
    }

    return result;
  }
}

源码分析

使用栈的思想模拟递归,注意迭代的演进和边界条件即可。

复杂度分析

最坏情况下栈保存所有节点,空间复杂度 O(n)O(n)O(n), 时间复杂度 O(n)O(n)O(n).

Reference

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文