前序遍历:
Code1:
vector<int> preorderTraversal(TreeNode* root) { // 前序遍历.
vector<int> retvec;
stack<TreeNode*> stk;
while (root != NULL || !stk.empty()) {
while (root != NULL) {
retvec.push_back(root->val); // 首次碰到 root, 就将其"输出"
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
root = root->right;
}
}
Code2
使用栈实现 DFS 应用到二叉树就是前序遍历的结果.
class Solution { // DFS的非递归版本
public:
vector<int> DFSTraversal(TreeNode* root) {
vector<int> vec;
stack<TreeNode*> stk;
stk.push(root);
while (!stk.empty()) {
root = stk.top();
stk.pop();
vec.push_back(root->val);
// 非二叉树, 将当前结点的孩子结点, 从右至左依次入栈.
if(root->right) stk.push(root->right);
if(root->left) stk.push(root->left);
}
return vec;
}
};
中序遍历:
Code:
vector<int> inorderTraversal(TreeNode* root) { // 中序遍历.
vector<int> retvec;
stack<TreeNode*> stk;
while (root != NULL || !stk.empty()) {
// 注意循环进行的条件.
while (root != NULL) {
stk.push(root);
root = root->left;
}
root = stk.top(); // 取一个非空元素.
stk.pop();
retvec.push_back(root->val);
root = root->right;
// 同样的方法处理右子节点, 可能为空
}
return retvec;
}
注意前序遍历和中序遍历中 retvec.push_back() 出现的地方。
补充: 后序遍历
网上看到思路:
- 前序遍历 => 根, 左, 右.
- 后序遍历 => 左, 右, 根.
- 仿照前序遍历方法求解出 => 根, 右, 左.
- reverse => 得到后序遍历.
Code1:
/**
* 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> postorderTraversal(TreeNode* root) {
stack<TreeNode*> stk;
vector<int> vec;
while (root != NULL || !stk.empty()) {
while (root != NULL) {
vec.push_back(root->val);
stk.push(root);
root = root->right;
}
root = stk.top();
stk.pop();
root = root->left;
}
reverse(vec.begin(), vec.end());
return vec;
}
};
Code2:
使用其他辅助结构,记录当前结点是从 左子节点返回还是右子节点返回。
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
enum status { st_left, st_right };
struct hlpNode {
TreeNode *pa; // 添加对应的 TreeNode 引用
status st; // 标记用于区别父节点是第几次进栈,从而知道是从左子节点还是右子节点返回
hlpNode(TreeNode *p) : pa(p), st(st_left) {} // 默认, 即第一次为 left
};
class solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> vec;
stack<hlpNode *> stk;
hlpNode *node;
while (root != NULL || !stk.empty()) {
while(root != NULL) {
node = new hlpNode(root);
stk.push(node);
root = root->left;
}
node = stk.top();
stk.pop();
if(node->st == st_left) {
// 继续处理右子节点, 并更新 st_left 为 st_right
node->st = st_right;
stk.push(node);
root = node->pa->right;
} else {
// 左右子节点均处理完成, "输出"根结点
vec.push_back(node->pa->val);
}
}
}
};