Problem:
Given a binary tree, return the preorder, inorder, postorder traversal of its nodes’ values.
Preorder :
Recursive :
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> res;
helper(root, res);
return res;
}
void helper(TreeNode * root, vector<int>& res)
{
if (!root) return;
res.push_back(root -> val);
helper(root -> left, res);
helper(root -> right, res);
return;
}
Iterative:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> res;
if (!root) return res;
stack<TreeNode*> stk;
TreeNode * cur = root;
while (!stk.empty() || cur)
{
while (cur)
{
stk.push(cur);
res.push_back(cur -> val);
cur = cur -> left;
}
cur = stk.top();
stk.pop();
cur = cur ->right;
}
return res;
}
Morris Traversal:
vector<int> preorderTraversal(TreeNode* root)
{
TreeNode * cur = root, *predecessor = NULL;
vector<int> res;
while (cur)
{
if (!cur -> left)
{
res.push_back(cur -> val);
cur = cur -> right;
}
else{
predecessor = cur -> left;
while (predecessor -> right && predecessor -> right != cur)
predecessor = predecessor -> right;
if (!predecessor -> right)
{
res.push_back(cur -> val); // difference with inorder, push the value when index is build;
predecessor -> right = cur;
cur = cur -> left;
}
else{
predecessor -> right = NULL;
cur = cur -> right;
}
}
}
return res;
}
Inorder :
recursive :
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> res;
helper(root, res);
return res;
}
void helper(TreeNode * root, vector<int>& res)
{
if (!root) return;
helper(root -> left, res);
res.push_back(root -> val);
helper(root -> right, res);
return;
}
Iterative :
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> res;
if (!root) return res;
stack<TreeNode*> stk;
TreeNode * cur = root;
while (cur || !stk.empty())
{
while (cur)
{
stk.push(cur);
cur = cur -> left;
}
cur = stk.top();
res.push_back(cur -> val);
stk.pop();
cur = cur -> right;
}
return res;
}
Morris Traversal: O(1) space and O (n) time
vector<int> inorderTraversal(TreeNode* root)
{
TreeNode * cur = root, *predecessor = NULL;
vector<int> res;
while (cur)
{
if (!cur -> left)//left most node
{
res.push_back(cur -> val);
cur = cur -> right;
}
else{ //check and add index for each step;
predecessor = cur -> left;
while (predecessor -> right && predecessor -> right != cur)
predecessor = predecessor -> right;
if (!predecessor -> right) // connected the predecessor with cur.(index)
{
predecessor -> right = cur;
cur = cur -> left;
}
else{
predecessor -> right = NULL; //disable the index.
res.push_back(cur -> val);// push the value when visit the index
cur = cur -> right;
}
}
}
return res;
}
Postorder:
recursive:
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
helper(root, res);
return res;
}
void helper(TreeNode * root, vector<int> & res)
{
if (!root) return NULL;
helper(root -> left);
helper(root -> right);
res.push_back(root -> val);
return;
}
Iterative :
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
if (!root) return res;
stack<TreeNode*> stk;
TreeNode * cur = root;
TreeNode * previsited = NULL;
while (cur || !stk.empty())
{
while (cur)
{
stk.push(cur);
cur = cur -> left;
}
cur = stk.top();
//if the right child is not null or haven't been visited;
if (cur -> right && previsited != cur -> right)
cur = cur -> right;
else{
res.push_back(cur -> val);
previsited = cur;
stk.pop();
cur = NULL; // cur set to null
}
}
return res;
}