Leetcode144. 二叉树的前序遍历
题目链接:
[144. 二叉树的前序遍历 - 力扣(Leetcode)]
法一:递归
遵循根左右
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
traversal(root,res);
return res;
}
void traversal(TreeNode* root,vector<int> &res){
if(root==nullptr) return ;
res.push_back(root->val);
traversal(root->left,res);
traversal(root->right,res);
}
};
法二:迭代
利用栈完成,先将根节点放入栈中,然后将右孩子加入栈,再加入左孩子。(栈的特性先进后出)
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode *> st;
vector<int> res;
if(root == nullptr) return res;
st.push(root);
while(!st.empty())
{
TreeNode *cur=st.top();
st.pop();
res.push_back(cur->val);
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
}
return res;
}
};
法三:统一迭代法
详见中序统一迭代法
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode *> st;
vector<int> res;
if(root!=nullptr) st.push(root);
while(!st.empty())
{
TreeNode *cur =st.top();
if(cur!=nullptr)
{
st.pop();
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
st.push(cur);
st.push(nullptr);
}else{
st.pop();
cur=st.top();
res.push_back(cur->val);
st.pop();
}
}
return res;
}
};
Leetcode94. 二叉树的中序遍历
题目链接:
法一:递归
思路同上
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
traversal(root,res);
return res;
}
void traversal(TreeNode* root,vector<int> &res){
if(root==nullptr) return ;
traversal(root->left,res);
res.push_back(root->val);
traversal(root->right,res);
}
};
法二:迭代
在使用迭代法写中序遍历,就需要借用指针的遍历来帮助访问节点,栈则用来处理节点上的元素。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode *> st;
vector<int> res;
TreeNode *cur=root;
while(cur!=nullptr || !st.empty())
{
if(cur!=nullptr)
{
st.push(cur);
cur=cur->left;
}else{
cur=st.top();
st.pop();
res.push_back(cur->val);
cur=cur->right;
}
}
return res;
}
};
法三:统一迭代法
class Solution {
public:
vector<int> inorderTraversal(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); // 添加右节点(空节点不入栈)
st.push(node); // 添加中节点
st.push(NULL); // 中节点访问过,但是还没有处理,加入空节点做为标记。
if (node->left) st.push(node->left); // 添加左节点(空节点不入栈)
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
st.pop(); // 将空节点弹出
node = st.top(); // 重新取出栈中元素
st.pop();
result.push_back(node->val); // 加入到结果集
}
}
return result;
}
};
Leetcode145. 二叉树的后序遍历
题目链接:
[145. 二叉树的后序遍历 - 力扣(Leetcode)]
法一:递归
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> res;
traversal(root,res);
return res;
}
void traversal(TreeNode* root,vector<int> &res){
if(root==nullptr) return ;
traversal(root->left,res);
traversal(root->right,res);
res.push_back(root->val);
}
};
法二:迭代
先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode *> st;
vector<int> res;
if(root == nullptr) return res;
st.push(root);
while(!st.empty())
{
TreeNode *cur=st.top();
st.pop();
res.push_back(cur->val);
if(cur->left) st.push(cur->left);
if(cur->right) st.push(cur->right);
}
reverse(res.begin(),res.end());
return res;
}
};
法三:统一迭代法
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode *> st;
vector<int> res;
if(root!=nullptr) st.push(root);
while(!st.empty())
{
TreeNode *cur =st.top();
if(cur!=nullptr)
{
st.pop();
st.push(cur);
st.push(nullptr);
if(cur->right) st.push(cur->right);
if(cur->left) st.push(cur->left);
}else{
st.pop();
cur=st.top();
res.push_back(cur->val);
st.pop();
}
}
return res;
}
};