方法一:
利用栈的原理,其实递归不就是栈嘛,递归函数在栈中的创建和删除而已
还有一个skill,其实先序,他的本质,咋们是不是可以理解成都是遍历左子树呢,接下来再遍历右子树的左子树,是不是very good
这里把先序和中序都给实现了
void preorderTraversal(TreeNode *root, vector<int> &path)
{
stack<TreeNode *> s;
TreeNode *p = root;
while (p != NULL || !s.empty())
{
//每次遍历的本质:遍历每个节点的左子树
while (p != NULL)
{
//这样输出是先序遍历
//cout << tmp->val << " ";
s.push(p);
p = p->left;
}
//这里相当于递归里边的回退,即回退到上一个,但是要将此时的节点弹出,因为已经访问过
if (!s.empty())
{
p = s.top();
//这样输出是后序遍历
//cout << tmp->val << " ";
s.pop();
p = p->right;
}
}
}
方法二:
这里要注意的是,通过切断左节点和右节点来实现后序遍历,此时,树被改变了
技巧:巧妙的利用了栈来保存树节点,其实吧,递归中每个函数的创建和消除不也就是栈嘛
TreeNode *tmp = nullptr;
stack<TreeNode *> pathNode;
vector<vector<int>> vec;
pathNode.push(root);
//cout << root->val << " ";
while (!pathNode.empty())
{
tmp = pathNode.top();
if (tmp->left == nullptr && tmp->right == nullptr)
{
//cout << tmp->val << " ";
pathNode.pop();
}
else if (tmp->left)
{
pathNode.push(tmp->left);
cout << tmp->left->val << " ";
//tmp->left->val = INT_MIN;
tmp->left = nullptr;
}
else if (tmp->right)
{
pathNode.push(tmp->right);
cout << tmp->right->val << " ";
tmp->right = nullptr;
}
}