题目链接:Binary Tree Inorder Traversal

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

For example:

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

   1 
    \ 
     2 
    / 
   3 

return [1,3,2].

Note: Recursive solution is trivial, could you do it iteratively?

confused what "{1,#,2,3}" means?

read more on how binary tree is serialized on OJ.

OJ's Binary Tree Serialization:

The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

Here's an example:

   1 
  / \ 
 2   3 
    / 
   4 
    \ 
     5 

The above binary tree is serialized as "{1,2,3,#,#,4,#,#,5}".

这道题的要求是中序遍历二叉树。

二叉树,即每个节点下面最多有2个子节点的树。

1. 递归遍历

递归遍历二叉树,比较简单。

时间复杂度:O(n)

空间复杂度:O(n)

 1 class Solution
 2 {
 3 public:
 4     vector<int> inorderTraversal(TreeNode *root)
 5     {
 6         vector<int> vi;
 7         inorderTraversal(root, vi);
 8         return vi;
 9     }
10 private:
11     void inorderTraversal(TreeNode *root, vector<int> &vi)
12     {
13         if(root != NULL)
14         {
15             inorderTraversal(root -> left, vi);
16             vi.push_back(root -> val);
17             inorderTraversal(root -> right, vi);
18         }
19     }
20 };

2. 迭代遍历1

用栈进行存储,根节点先入栈。然后不断读取栈顶元素,读取某一节点的时候,如果存在左子树,说明需要先遍历左子树,因此该节点不出栈,左子树入栈,并标记左子树为NULL。如果不存在左子树,出栈,并记录该节点。如果该节点存在右子树,右子数入栈。

该方法缺点,破坏了原二叉树的结构。

时间复杂度:O(n)

空间复杂度:O(n)

 1 class Solution
 2 {
 3 public:
 4     vector<int> inorderTraversal(TreeNode *root)
 5     {
 6         vector<int> vi;
 7         
 8         if(root == NULL)
 9             return vi;
10         
11         stack<TreeNode *> stp;
12         stp.push(root);
13         while(!stp.empty())
14         {
15             TreeNode *p = stp.top();
16             if(p -> left != NULL)
17             {
18                 stp.push(p -> left);
19                 p -> left = NULL;
20             }
21             else
22             {
23                 stp.pop();
24                 vi.push_back(p -> val);
25                 
26                 if(p -> right != NULL)
27                     stp.push(p -> right);
28             }
29         }
30         
31         
32         return vi;
33     }
34 };

3. 迭代遍历2

由于上面思路破坏了原二叉树的结构,因此不常被采用。下面这段代码用栈实现遍历二叉树,并不破坏原有二叉树结构。

时间复杂度:O(n)

空间复杂度:O(n)

 1 class Solution
 2 {
 3 public:
 4     vector<int> inorderTraversal(TreeNode *root)
 5     {
 6         vector<int> vi;
 7         
 8         stack<TreeNode *> stp;
 9         TreeNode *cur = root;
10         
11         while(cur != NULL || !stp.empty())
12         {
13             while(cur != NULL)
14             {
15                 stp.push(cur);
16                 cur = cur -> left;
17             }
18             
19             cur = stp.top();
20             stp.pop();
21             vi.push_back(cur -> val);
22             cur = cur -> right;
23         }
24         
25         return vi;
26     }
27 };

4. Morris Traversal方法

该方法只需要O(1)空间,而且同样可以在O(n)时间内完成遍历二叉树。

详见这里