Problem: 94. 二叉树的中序遍历
方法一:递归
思路
二叉树的遍历方式主要有前序遍历,中序遍历,后序遍历以及层序遍历。其中前序、中序、后序是深度优先算法,层序是广度优先算法。
中序遍历按照 左子树 → 根节点 → 右子树 左子树 \rightarrow 根节点 \rightarrow 右子树 左子树→根节点→右子树的顺序进行遍历,在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。
我们将原问题拆分成了更小规模的问题:递归遍历左子树,输出值,递归遍历右子树。
递归边界条件:节点为空
Code
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
function<void(TreeNode*)> dfs = [&](TreeNode* node){
if(node == nullptr) return;
dfs(node->left);
res.push_back(node->val);
dfs(node->right);
};
dfs(root);
return res;
}
};
复杂度
-
时间复杂度:
O ( n ) O(n) O(n),其中 n n n是二叉树的节点数 -
空间复杂度:
O ( n ) O(n) O(n),当二叉树为链状时
方法二:迭代
思路
在递归过程中,我们隐式地维护了一个栈,在迭代过程中,我们可以将栈显式地模拟出来。注意:栈是后进先出的,我们的顺序是 左子树 → 根 → 右子树 左子树 \rightarrow 根 \rightarrow 右子树 左子树→根→右子树,所以我们应将左子树先入栈。
Code
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
while(root != nullptr || !stk.empty()){
while(root != nullptr){ // 当左子树存在时需要先入栈
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
res.push_back(root->val);
root = root->right;
}
return res;
}
};
复杂度
-
时间复杂度:
O ( n ) O(n) O(n),其中 n n n是二叉树的节点数 -
空间复杂度:
O ( n ) O(n) O(n),当二叉树为链状时