LeetCode145二叉树后序遍历
题目介绍
-
题目链接
https://leetcode-cn.com/problems/binary-tree-postorder-traversal/description/
-
题目考点
二叉树,后序遍历,递归,迭代,栈
-
题目难度
LeetCode Medium
-
题目大意
后序遍历1颗二叉树
-
输入
1颗二叉树
-
输出
后序遍历的结果
题解一
解题思路
-
递归法
后序遍历的顺序是“左右中”。先后通过递归遍历左子树和右子树,然后遍历当前根结点。
-
复杂度分析
假设该二叉树有n个结点,则时间复杂度为\(O(n)\)、最大空间复杂度为\(O(n)\)、平均空间复杂度为\(O(log\ n)\)。
代码
class Solution{
public:
vector<int> result;
void traversal(TreeNode* root){
if(root!=nullptr){
traversal(root->left);
traversal(root->right);
result.push_back(root->val);
}
}
vector<int> postorderTraversal(TreeNode* root){
traversal(root);
return result;
}
};
题解二
解题思路
-
栈法/迭代法
该思路是通过显式栈模拟递归函数。虽然该思路的复杂度稍高一些,但其仅需要微小改动就可以通用于二叉树的先/中/后序遍历。该思路实现3种顺序遍历的介绍:https://www.cnblogs.com/chouxianyu/p/13293284.html
该思路的核心是将
nullptr
作为可以遍历下1个结点的标志(因此也就不能将空结点压入栈中),即遇到nullptr
时就可以遍历下一个结点,如果不是nullptr
则根据遍历顺序入栈,当前根结点入栈时也要将nullptr
压入栈中(后续遇到这个nullptr
时就可以遍历到该根结点)。 -
复杂度分析
假设二叉树有n个结点,则时间复杂度为\(O(n)\)、最大空间复杂度为\(O(n)\)、平均空间复杂度为\(O(log\ n)\)。
代码
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> nodes;
vector<int> result;
if (root!=nullptr)
nodes.push(root);
while(!nodes.empty()){
root=nodes.top();
nodes.pop();
if(root==nullptr){
result.push_back(nodes.top()->val);
nodes.pop();
}else{
nodes.push(root);
nodes.push(nullptr);
if(root->right!=nullptr)
nodes.push(root->right);
if(root->left!=nullptr)
nodes.push(root->left);
}
}
return result;
}
};
题解三
解题思路
-
栈法/迭代法
后序遍历的顺序为:左子树、右子树、根结点。
用
prev
保存上1个遍历过的结点。对于1个根结点,分3步操作:-
将
root
压入栈中并不断更新为其左子树,直至root
为空可以想象下,后序遍历时就是这样并不遍历当前结点,而是一直往左下角延伸到底
-
更新
root
为栈顶结点第1步结束后,此时栈顶结点无左子树或其左子树已遍历完
-
如果无右子树或右子树已遍历,则遍历
root
并更新prev
为root
、更新root
为nullptr
;否则root
入栈并更新root
为右子树。
如果
root
非空或者栈非空则循环以上步骤。 -
-
复杂度分析
假设二叉树有n个结点,则时间复杂度为\(O(n)\)、最大空间复杂度为\(O(n)\)、平均空间复杂度为\(O(log\ n)\)。
代码
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*> nodes;
vector<int> result;
TreeNode* prev=nullptr;
while(root!=nullptr || !nodes.empty()){
while(root!=nullptr){
nodes.push(root);
root=root->left;
}
root=nodes.top();
nodes.pop();
if(root->right==nullptr || root->right==prev){
result.push_back(root->val);
prev=root;
root=nullptr;
}else{
nodes.push(root);
root=root->right;
}
}
return result;
}
};
题解四
Morris 遍历算法是另一种遍历二叉树的方法。
假设二叉树有n个结点,该算法的时间复杂度为\(O(n)\)、空间复杂度为\(O(1)\)。
作者:@臭咸鱼
转载请注明出处:https://www.cnblogs.com/chouxianyu/
欢迎讨论和交流!