- 定义二叉树结构
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
- 前序遍历:访问某个节点时,并且访问其左子树节点并将已访问节点入栈。在节点出栈时,判断节点是否存在右子树。如果存在,则按上述方法重复执行。
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> ret;
if (root == nullptr) {
return ret;
}
stack<TreeNode *> stk;
TreeNode *p = root;
while (p) {
ret.push_back(p->val);
stk.push(p);
p = p->left;
}
while (!stk.empty()) {
p = stk.top();
stk.pop();
p = p->right;
while (p) {
ret.push_back(p->val);
stk.push(p);
p = p->left;
}
}
return ret;
}
};
- 中序遍历:先将节点以及节点的左子树节点推送入栈;之后出栈时访问节点,并判断是否存在右子树。如果存在,则按上述方法将其左子树节点推送入栈。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ret;
if (root == nullptr) {
return ret;
}
stack<TreeNode *> stk;
TreeNode *p = root;
while (p) {
stk.push(p);
p = p->left;
}
while (!stk.empty()) {
p = stk.top();
stk.pop();
ret.push_back(p->val);
p = p->right;
while (p) {
stk.push(p);
p = p->left;
}
}
return ret;
}
};
- 后序遍历:与中序遍历类似,先将节点以及节点的左子树节点推送入栈;之后出栈时访问节点,并判断是否存在右子树,并且右子树没有被访问过。如果存在,则按上述方法将其左子树节点推送入栈;否则节点出栈即可。
如何判断右子树没有被访问过,我们使用一个last指针,即上次访问的节点。根据后序遍历的规律,如果当前节点有右子树,则上次访问的节点必定是其右子树节点,所以使用p->right != last
判断右子树是否被访问过。
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ret;
if (root == nullptr) {
return ret;
}
TreeNode *p = root;
stack<TreeNode *> stk;
while (p) {
stk.push(p);
p = p->left;
}
TreeNode *q = nullptr;
while (!stk.empty()) {
p = stk.top();
if (p->right == nullptr || p->right == q) {
ret.push_back(p->val);
q = p;
stk.pop();
continue;
} else {
p = p->right;
while (p) {
stk.push(p);
p = p->left;
}
}
}
return ret;
}
};