
二叉树递归遍历(后序遍历)
1
/ \
2 3
执行过程(后序遍历):
1. postorderTraversal(节点1)
│ 创建空vector: result = []
│
└─ traversal(节点1, result)
│
├─ traversal(节点2, result)
│ │
│ ├─ traversal(左空, result) → 直接返回
│ │
│ └─ traversal(右空, result) → 直接返回
│ │
│ └─ result.push_back(2) → result = [2]
│
├─ traversal(节点3, result)
│ │
│ ├─ traversal(左空, result) → 直接返回
│ │
│ └─ traversal(右空, result) → 直接返回
│ │
│ └─ result.push_back(3) → result = [2,3]
│
└─ result.push_back(1) → result = [2,3,1]
最终返回:result = [2,3,1]
cpp
class Solution {
public:
// 后序遍历递归函数
// 参数:
// cur - 当前遍历到的树节点指针
// vec - 存储遍历结果的vector的引用
void traversal(TreeNode *cur, vector<int> &vec) {
// 递归终止条件:当前节点为空(到达叶子节点的子节点)
if (cur == NULL) return;
// 递归遍历左子树
traversal(cur->left, vec);
// 递归遍历右子树
traversal(cur->right, vec);
// 后序遍历:最后访问根节点
// 将当前节点的值添加到结果vector中
vec.push_back(cur->val);
}
// 后序遍历的入口函数
// 参数:
// root - 二叉树的根节点指针
// 返回值:
// vector<int> - 包含后序遍历结果的整数数组
vector<int> postorderTraversal(TreeNode* root) {
// 创建一个空的vector用于存储遍历结果
vector<int> result;
// 调用递归函数,从根节点开始遍历
// result通过引用传递,递归过程中会不断添加元素
traversal(root, result);
// 返回完整的遍历结果
return result;
}
};
后序遍历(迭代法)
来看后序遍历是左右中,先序遍历是中左右,后序遍历是左右中,那么我们只需要调整一下先序遍历的迭代(先右结点入栈,再左结点入栈)的代码顺序,就变成中右左(先左结点入栈,再右结点入栈)的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了,如下图:

cpp
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
// 使用栈来辅助迭代遍历
stack<TreeNode*> st;
// 存储遍历结果的数组
vector<int> result;
// 如果根节点为空,直接返回空结果
if (root == NULL) return result;
// 将根节点入栈
st.push(root);
// 当栈不为空时,继续遍历
while (!st.empty()) {
// 取出栈顶节点
TreeNode* node = st.top();
st.pop();
// 将当前节点的值加入结果集
result.push_back(node->val);
// 先将左子节点入栈(如果存在)
// 注意:这里先左后右的入栈顺序,配合后面的反转,实现后序遍历
if (node->left) st.push(node->left); // 空节点不入栈
// 再将右子节点入栈(如果存在)
if (node->right) st.push(node->right); // 空节点不入栈
}
// 反转结果数组
// 此时的遍历顺序是:中->右->左(因为先处理中节点,然后右节点先于左节点出栈)
// 反转后得到:左->右->中,即后序遍历顺序
reverse(result.begin(), result.end());
// 返回后序遍历结果
return result;
}
};