一、二叉树的应用场景
1.前序遍历:可以用来实现目录结构的显示。
2.中序遍历:一颗二叉搜索树,被中序遍历之后,就是value从小到大的排列,当然也可以用来做表达式树,在编译器底层实现的时候用户可以实现基本的加减乘除,比如 a*b+c。
3.后序遍历:可以用来实现计算目录内的文件占用的数据大小。
二、后续遍历的实现
后序遍历:左子树---> 右子树 ---> 根结点
上图的后序遍历:4 5 2 6 3 1
2.1、非递归的方法
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if (root == nullptr) {
return res;
}
stack<TreeNode *> stk;
TreeNode *prev = nullptr;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.emplace(root);
root = root->left;
}
root = stk.top();
stk.pop();
if (root->right == nullptr || root->right == prev) {
res.emplace_back(root->val);
prev = root;
root = nullptr;
} else {
stk.emplace(root);
root = root->right;
}
}
return res;
}
};
或者
先序遍历是中左右,后续遍历是左右中,那么我们只需要调整一下先序遍历的代码顺序,就变成中右左的遍历顺序,然后在反转result数组,输出的结果顺序就是左右中了,如下图:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if (root == nullptr) {
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;
}
};
2.2、递归的方法
//后续遍历
class Solution {
public:
void postorder(TreeNode *root, vector<int> &res) {
if (root == nullptr) {
return;
}
postorder(root->left, res);
postorder(root->right, res);
res.push_back(root->val);
}
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
postorder(root, res);
return res;
}
};
参考:
C++实现二叉树 前、中、后序遍历(递归与非递归)非递归实现过程最简洁版本_gy1012的博客-CSDN博客_后序遍历的非递归算法