学透二叉树遍历-后序遍历
后序遍历思想:左 - 右 - 打印
递归版:
class Solution {
public List<Integer> postorderTraversal(TreeNode root){
List<Integer> res = new ArrayList<Integer>();
dfs(res, root);
return res;
}
void dfs(List<Integer> res, TreeNode root){
if(root == null){
return;
}
//按照 左-右-打印 的方式遍历
dfs(res, root.left);
dfs(res, root.right);
res.add(root.val);
}
}
其中,时间复杂度:O(n),其中 n 是二叉搜索树的节点数。每一个节点恰好被遍历一次。
空间复杂度:O(n),为递归过程中栈的开销,平均情况下为O(logn),最坏情况下树呈现链状,为 O(n)。
非递归版:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
// 与先序遍历基本一致 不同:"root="后,left和right互换
while(stack.size() > 0 || root != null){
if(root != null){
res.add(root.val);
stack.add(root);
root = root.right;
}else{
TreeNode t = stack.pop();
root = t.left;
}
}
//此时,res的遍历结果为 根、右、左
// 将res反转即为:左、右、根 顺序
Collections.reverse(res);
return res;
}
}
其中,时间复杂度:O(n),其中 n 是二叉搜索树的节点数。每一个节点恰好被遍历一次。
空间复杂度:O(n),为迭代过程中显式栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)。
【注】先序遍历和后序遍历的非递归版基本一致,只不过将结果反转一下即可。
截至目前,将前,中,后序三种遍历代码均已给出递归版和非递归版,并且两个版本对应的三种遍历方法均有章法可循,每种遍历方式的代码仅仅有小的改动,即掌握其中一种方法,另外两种照葫芦画瓢即可。前序遍历 中序遍历