题目
迭代思路
- 同理创建一个 Stack,然后按 左 中 右的顺序输出节点。
- 尽可能的将这个节点的左子树压入 Stack,此时栈顶的元素是最左侧的元素,其目的是找到一个最小单位的子树(也就是最左侧的一个节点),并且在寻找的过程中记录了来源,才能返回上层,同时在返回上层的时候已经处理完毕左子树了。
- 当处理完最小单位的子树时,返回到上层处理了中间节点。(如果把整个左中右的遍历都理解成子树的话,就是处理完 左子树->中间(就是一个节点)->右子树)
- 如果有右节点,其也要进行中序遍历。
代码(首刷自解)
递归
class Solution {
public:
vector<int> res;
vector<int> inorderTraversal(TreeNode* root) {
inorder(root);
return res;
}
void inorder(TreeNode* root) {
if(!root)
return;
inorder(root->left);
res.push_back(root->val);
inorder(root->right);
}
};
迭代
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> ans;
while(!st.empty() || root) {
if(root) {
st.push(root);
root = root->left;
} else {
root = st.top();
ans.push_back(root->val);
root = root->right;
st.pop();
}
}
return ans;
}
};
迭代,统一风格写法
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> st;
if(root)
st.push(root);
while(!st.empty()) {
root = st.top();
if(root) {
st.pop();
if(root->right) st.push(root->right);
st.push(root);
st.push(nullptr);
if(root->left) st.push(root->left);
} else {
st.pop();
root = st.top();
res.push_back(root->val);
st.pop();
}
}
return res;
}
};
代码(8.5 二刷自解 GO)
func inorderTraversal(root *TreeNode) []int {
stk := []*TreeNode{}
res := []int{}
if root == nil {
return res
}
stk = append(stk, root)
for len(stk) > 0 {
root = stk[len(stk) - 1]
if root != nil {
stk = stk[:len(stk) - 1]
if root.Right != nil {
stk = append(stk, root.Right)
}
stk = append(stk, root)
stk = append(stk, nil)
if root.Left != nil {
stk = append(stk, root.Left)
}
} else {
stk = stk[:len(stk) - 1]
root = stk[len(stk) - 1]
res = append(res, root.Val)
stk = stk[:len(stk) - 1]
}
}
return res
}
代码(9.12 三刷自解)
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
function<void(TreeNode*)> trversal = [&](TreeNode* root) {
if(!root)
return;
trversal(root->left);
res.push_back(root->val);
trversal(root->right);
return;
};
trversal(root);
return res;
}
};