https://leetcode.cn/problems/binary-tree-inorder-traversal/description/
迭代遍历
由于二叉树结构本身就是递归的(每一个节点都是一个子树),所以递归写法好理解,写法也简洁
void traversal(TreeNode* node, vector<int>& vec) {
if (!node) {
return;
}
// 左
traversal(node->left, vec);
// 中
vec.push_back(node->val);
// 右
traversal(node->right, vec);
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
traversal(root, ans);
return ans;
}
迭代遍历
由于中序遍历时,对节点的访问与操作不是在同一步中进行的,所以迭代遍历的写法与前序后序有所不同。
<aside> 💡
不断访问左孩子,直到没有左孩子时取出栈顶节点进行操作
</aside>
// 迭代遍历
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
stack<TreeNode*> st;
TreeNode* cur = root;
while (cur || !st.empty()) {
// 节点非空时访问节点,但不对节点进行操作,
// 而是不断将其压入栈并继续访问其左孩子
while (cur) {
st.push(cur);
cur = cur->left; // 左
}
// 直到左孩子为空节点时,才从栈中弹出节点进行操作
cur = st.top(); // 中
st.pop();
ans.push_back(cur->val);
cur = cur->right; // 右
}
return ans;
}
迭代遍历——统一写法
<aside> 💡
boolen标记法思路:
// 迭代——统一写法
vector<int> inorderTraversal(TreeNode* root) {
vector<int> ans;
stack<TreeNode*> st;
TreeNode* cur;
if (root)
st.push(root);
while (!st.empty()) {
cur = st.top();
if (cur) {
// 先将栈顶弹出
st.pop();
// 将栈顶节点扩展成一个子树,按右-中-左的顺序压入栈
// 右
if (cur->right)
st.push(cur->right);
// 中,中节点访问但还没操作,后面加入一个空指针作为标识
st.push(cur);
st.push(nullptr);
// 左
if (cur->left)
st.push(cur->left);
}
// 碰到了标示符(空指针),说明此时该对节点进行操作了
else {
// 先将空指针弹出,再对栈顶元素进行操作
st.pop();
cur = st.top();
ans.push_back(cur->val);
// 最后将操作完成的栈顶元素弹出
st.pop();
}
}
return ans;
}