今天碰到了这道题,写一下怎么实现树的前序遍历而不使用递归。
基本思路:
- 在我之前的博客中曾经写过,虽然递归和非递归有着紧密的联系(比如思想上),但是两者在编写上依然有很大差别。——主要体现在递归可以使用所谓整体法,而如果使用非递归的话用整体法很难想。
- 如果使用非递归的话怎么搞呢?我们只能先通过模拟,摸清大概是怎么做的,然后再来谈具体的实现。
- 谈到递归,不得不谈到栈这个数据结构——我们递归要从递归函数中返回,等价于出栈这个操作——同样的,在非递归的写法中我们完全可以引入栈,当搜索完毕时出栈,直到栈顶元素是我们待处理的下一个元素。
- 有以上的理论基础,我们的思路就比较清晰了:
- 不断地往左子树搜索,并输出左子树的节点的值。
- 如果搜到底了,不断回溯,看看有没有有右子树的节点,如果有,进入右子树搜索。
代码:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
// 树的左子树和右子树都是链表的形式
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
TreeNode *p = root;
if (!p) return res;
stack<TreeNode *> s;
// 控制整个搜索的过程(什么时候结束)
while (!s.empty() || p) {
// 不断往左子树搜索
while (p) {
s.push(p);
res.push_back(p->val);
p = p->left;
}
// 进入右子树
if (!s.empty()) {
p = s.top();
s.pop();
p = p->right;
}
}
return res;
}
};