深度优先遍历的三种遍历方式,可看出区别在于访问根的位置不同。
以下使用非递归的实现方式,总结出前序、中序、后序遍历的模板。基本相同的代码,只作了稍微的改变。
前序遍历:根-左-右
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if(root == null){
return res;
}
while(root != null || !stack.isEmpty()){
while(root!= null){
//访问根
res.add(root.val);
stack.push(root);
//遍历左边
root = root.left;
}
root = stack.pop();
//遍历右边
root = root.right;
}
return res;
}
}
中序遍历:左-根-右
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if(root == null){
return res;
}
while(root != null || !stack.isEmpty()){
while(root != null){
stack.push(root);
//遍历左
root = root.left;
}
root = stack.pop();
//访问根节点,与前序相比,就改变了这个位置
res.add(root.val);
//遍历右
root = root.right;
}
return res;
}
}
后序遍历:左-右-根
先输出 根-右-左,然后进行反转得到 左-右-跟
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
Stack<TreeNode> stack = new Stack<>();
if(root == null){
return res;
}
while(root != null || !stack.isEmpty()){
while(root != null){
res.add(root.val);
stack.push(root);
//与前序相比,左改成右
root = root.right;
}
root = stack.pop();
//与前序相比,右改成左
root = root.left;
}
//然后对 根-右-左 结果进行反转,反转后结果为 左-右-跟
Collections.reverse(res);
return res;
}
}