144. 二叉树的前序遍历
给定一个二叉树,返回它的 前序 遍历。
示例:
输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
借助栈模拟递归过程。设置指针ptr指向当前的根节点,当ptr不为nullptr时,访问并将其入栈,并将ptr设为其左孩子;当ptr为nullptr时,将ptr设置为栈顶右孩子并弹栈。放在栈中的元素表示已经访问过且右子树尚未访问过节点。
代码一如下:
vector<int> preorderTraversal(TreeNode* root)
{
vector<int> res;
if(root == nullptr)
return res;
stack<TreeNode*> s;
TreeNode* ptr = root;
while(ptr || !s.empty())
{
if(ptr)
{
res.push_back(ptr->val);
s.push(ptr);
ptr = ptr->left;
}
else
{
ptr = s.top();
s.pop();
ptr = ptr->right;
}
}
return res;
}
94. 二叉树的中序遍历
给定一个二叉树,返回它的中序 遍历。
示例:
输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
中序遍历的非递归版和前序遍历的很相似,只需要在将ptr指向其右孩子之前访问该节点即可。
vector<int> inorderTraversal(TreeNode* root)
{
vector<int> res;
if(root == nullptr)
return res;
stack<TreeNode*> s;
TreeNode* ptr = root;
while(ptr || !s.empty())
{
if(ptr)
{
s.push(ptr);
ptr = ptr->left;
}
else
{
ptr = s.top();
s.pop();
res.push_back(ptr->val);
ptr = ptr->right;
}
}
return res;
}
145. 二叉树的后序遍历
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
对于任意根节点,先将其入栈。分两种情况:1、根节点无孩子,或根节点的孩子均被访问过,则可以访问该根节点。2、依次将右孩子和左孩子入栈。
vector<int> postorderTraversal(TreeNode* root)
{
vector<int> res;
if(root == nullptr)
return res;
TreeNode* ptr = root, *pre = nullptr;
stack<TreeNode*> s;
s.push(ptr);
while(!s.empty())
{
ptr = s.top();
if((!ptr->left && !ptr->right) || (pre && (ptr->right == pre || ptr->left == pre)))//注意顺序
{
res.push_back(ptr->val);
s.pop();
pre = ptr;
}
else
{
if(ptr->right)
s.push(ptr->right);
if(ptr->left)
s.push(ptr->left);
}
}
return res;
}
另一种写法:
void PostOrder(TreeNode *root) {
TreeNode *p = root, *r = NULL;
stack<TreeNode*> s;
while (p || !s.empty()) {
if (p) {//走到最左边
s.push(p);
p = p->left;
}
else {
p = s.top();
if (p->right && p->right != r)
p = p->right;
else {
s.pop();
visit(p->val);
r = p;
p = NULL;
}
}
}
}