二叉树的先序遍历:
(以 leetcode 144. 二叉树的前序遍历 为例)
空树的遍历序列为空序列
二叉树先序遍历序列 = 根节点 + 左子树遍历序列 + 右子树遍历序列
二叉树先序遍历递归实现:
class Solution {
vector<int> result;
void preorder(TreeNode *root) {
if (!root) return;
result.push_back(root->val);
preorder(root->left);
preorder(root->right);
}
public:
vector<int> preorderTraversal(TreeNode *root) {
result.clear();
preorder(root);
return result;
}
};
二叉树先序遍历迭代实现1:
- 若为空树,返回空序列(空vector)
- 以下讨论非空情况:
- 建栈,根节点进栈
- 当栈非空时:
- 取栈顶元素now,弹栈。
- 往结果序列(result)尾部添加now的数据域(val)
- 若now有右孩子,将右孩子进栈
- 若now有左孩子,将左孩子进栈
- 注:以上两行顺序不可颠倒(左孩子最后进栈,保证栈顶为左孩子)
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> result;
if (!root) return result;
stack<TreeNode *> st; st.emplace(root);
while (!st.empty()) {
auto now = st.top(); st.pop();
result.push_back(now->val);
if (now->right) st.emplace(now->right);
if (now->left) st.emplace(now->left);
}
return result;
}
};
二叉树先序遍历迭代实现 2:
- 若为空树,返回空序列(空vector) (实际上,由于虚拟根节点的设置,可以取消root是否为空树的判断)
- 以下讨论非空情况:
- 建立虚拟的根节点,将虚拟根节点的右孩子设置为实际根节点
- 建栈,虚拟根节点进栈
- 当栈非空时:
- 取栈顶元素now,弹栈
- 将now的右子树(若右子树非空)的最左边的一条链全部依次进栈
class Solution {
public:
vector<int> preorderTraversal(TreeNode *root) {
vector<int> result;
TreeNode dummyRoot(0); dummyRoot.right = root;
stack<TreeNode *> st; st.emplace(&dummyRoot);
while (!st.empty()) {
auto now = st.top()->right; st.pop();
while (now) {
result.emplace_back(now->val);
st.emplace(now);
now = now->left;
}
}
return result;
}
};
二叉树的后序遍历
(以 leetcode 145. 二叉树的后序遍历 为例)
空树的遍历序列为空序列
二叉树后序遍历序列 = 左子树遍历序列 + 右子树遍历序列 + 根节点
二叉树后序遍历递归实现:
class Solution {
vector<int> result;
void postorder(TreeNode *root) {
if (!root) return;
postorder(root->left);
postorder(root->right);
result.push_back(root->val);
}
public:
vector<int> postorderTraversal(TreeNode *root) {
result.clear();
postorder(root);
return result;
}
};
二叉树后序遍历迭代实现:
注意:此方法在本质上不是后序遍历,核心:
二叉树后序遍历序列 = reverse (根节点 + 右子树遍历序列 + 左子树遍历序列)
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
if (!root) return vector<int>();
deque<int> result;
stack<TreeNode *> st; st.emplace(root);
while (!st.empty()) {
auto now = st.top(); st.pop();
result.push_front(now->val);
if (now->left) st.emplace(now->left);
if (now->right) st.emplace(now->right);
}
return vector<int>(begin(result),end(result));
}
};