145. 二叉树的后序遍历【力扣】

it2022-05-09  63

题意理解

如题

问题分析

递归解法

非递归解法

用栈,再用一个指示上一个访问节点,用于根节点判断是否已经回退还是访问右子树。

大思路是,向左走到底 -- 如果右子树存在,向右一步走 -- 先左走到底。

其中,如果右子树不存在,或者右子树存在但是被访问过了,访问当前节点,再回退上一个结点(弹栈即可)。

为了标记右子树是否被访问,可以看上一次访问的是否是自己的右孩子,如果是右孩子,表明访问过了,如果不是右孩子,表明没有被访问过。

其他

链接

vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> st; if (root == nullptr) { //空树 return res; //直接返回空序列 } TreeNode* p = root; while (p) { //初始化,向左走到最左节点 st.push(p); p = p -> left; } TreeNode* last_visited; //记录上一个别访问节点 while (!st.empty()) { //栈不空 p = st.top(); //弹出最左节点 st.pop(); if (p -> right == nullptr || last_visited == p -> right) { //左子树必为空,当右子树为空,或者右节点是上一个被访问节点(右子树访问完) res.push_back(p -> val); //输出当前节点 last_visited = p; //重置上一次访问节点 } else { //右子树存在 st.push(p); //再把当前节点入栈 p = p -> right; //向右一步 while (p) { //向左走到底(为下一循环做准备) st.push(p); p = p -> left; } } } return res; } vector<int> postorderTraversal(TreeNode* root) { if (!root) { return vector<int>{}; } vector<int> res{}; vector<int> l_vector = postorderTraversal (root -> left); //左子树的后序遍历 vector<int> r_vector = postorderTraversal (root -> right); //右子树的后序遍历 res.insert (res.end(), l_vector.begin(), l_vector.end()); //插入左子树遍历结果 res.insert (res.end(), r_vector.begin(), r_vector.end()); //插入右子树遍历结果 res.push_back (root -> val); //插入根 return res; }

 

vector<int> postorderTraversal(TreeNode* root) { vector<int> res; if (root == nullptr) { return res; } stack<TreeNode*> st1; //存节点 stack<int> st2; //存倒过来的后序序列 st1.push(root); //入根节点 while (!st1.empty()) { //栈不空 TreeNode* p = st1.top(); //出栈, st2.push(p -> val); //拨开节点内的值 st1.pop(); //入后序序列栈 if (p -> left) st1.push(p -> left); //根处理完了,先入栈左节点 if (p -> right) st1.push(p -> right); //再入栈右节点,因为后序是先左后右再根,入第一个栈是先左后右,入第二个栈变成了先右后左,最后输出的时候就又变回先左后右了 } while (!st2.empty()) { res.push_back(st2.top()); st2.pop(); } return res; }

 


最新回复(0)