参考资料:
递归法:
1. 确定递归函数的参数和返回值。(可以在写的过程补充)
2. 确定终止条件
3. 确定单层递归的逻辑
/**
* 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> result;
traversal(root,result);
return result;
}
void traversal(TreeNode* node,vector<int> &vec){
if(node==nullptr) return;
vec.push_back(node->val);
traversal(node->left,vec);
traversal(node->right,vec);
}
};
中序遍历(94. 二叉树的中序遍历)、后序遍历(145. 二叉树的后序遍历)
思路同上,只需更改递归函数的单层递归逻辑顺序即可。
迭代法:
一)前序遍历
节点访问顺序和处理顺序相同(先访问根节点,先处理根节点)
对节点的处理:将值存入result数组,将右结点、左节点入栈
//迭代法
vector<int> preorderTraversal(TreeNode* root){
vector<int> result;
if(root==nullptr) return result;
stack<TreeNode*> stk;
stk.push(root);//中
while(!stk.empty()){
TreeNode* temp=stk.top();
stk.pop();
if(temp->right!=nullptr) stk.push(temp->right);//右
if(temp->left!=nullptr) stk.push(temp->left);//左
result.push_back(temp->val);
}
return result;
}
一)后序遍历
1. 将左右节点入栈顺序调转,此时变为“中右左”
2. 将result数组整个反转reverse
//迭代法(在前序基础上改)
vector<int> result;
if(root==nullptr) return result;
stack<TreeNode*> stk;
stk.push(root);//中
while(!stk.empty()){
TreeNode* temp=stk.top();
stk.pop();
//左右顺序调换
if(temp->left!=nullptr) stk.push(temp->left);//左
if(temp->right!=nullptr) stk.push(temp->right);//右
result.push_back(temp->val);
}//此时数组里面 中右左
//翻转数组
reverse(result.begin(),result.end());
return result;
三)中序遍历
注意:由于中序遍历里,节点访问顺序与节点处理顺序不同。在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。
//迭代法
vector<int> vec;
stack<TreeNode*> stk;
TreeNode *cur=root;
while(cur!=nullptr || !stk.empty()){
if(cur!=nullptr){
stk.push(cur);//左
cur=cur->left;
}
else{
cur=stk.top();
stk.pop();
vec.push_back(cur->val);//中
cur=cur->right;//右
}
}
return vec;
统一迭代法:
上面的迭代法中前中后序遍历的写法不统一,这里进行统一改造使其写法统一。
方法:待处理结点入栈后统一加入null节点,则在出栈时遇到Null节点就知道下一个节点待处理了。
//中序遍历
//空节点标记待处理的节点
stack<TreeNode*> stk;
vector<int> result;
if(root!=nullptr) stk.push(root);
while(!stk.empty()){
TreeNode* temp=stk.top();
if(temp!=nullptr){
stk.pop();
//入栈:右中左
if(temp->right) stk.push(temp->right);
stk.push(temp);
stk.push(nullptr);
if(temp->left) stk.push(temp->left);
}
else{//空节点,下一节点待处理
stk.pop();
temp=stk.top(); //取出待处理的节点
stk.pop();
result.push_back(temp->val);
}
}
return result;
前序、后序操作仅需要更改元素入栈顺序即可
//前序遍历
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
if (root != NULL) st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
if (node != NULL) {
st.pop();
if (node->right) st.push(node->right); // 右
if (node->left) st.push(node->left); // 左
st.push(node); // 中
st.push(NULL);
} else {
st.pop();
node = st.top();
st.pop();
result.push_back(node->val);
}
}
return result;
}
};