Problem: 144. 二叉树的前序遍历
方法一:递归
思路
二叉树的遍历方式主要有前序遍历,中序遍历,后序遍历以及层序遍历。其中前序、中序、后序是深度优先算法,层序是广度优先算法。
前序遍历按照 根节点 → 左子树 → 右子树 根节点 \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> preorderTraversal(TreeNode* root) {
vector<int> res;
function<void(TreeNode*)> dfs = [&](TreeNode* node){
if(node == nullptr){
return;
}
res.push_back(node->val);
dfs(node->left);
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> preorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
while(root || !stk.empty()){
while(root){
res.push_back(root->val);
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
root = root->right;
}
return res;
}
};
复杂度
-
时间复杂度:
O ( n ) O(n) O(n),其中 n n n是二叉树的节点数 -
空间复杂度:
O ( n ) O(n) O(n),当二叉树为链状时