1 难点
中序遍历,访问到某个节点时,不能直接输出他,要维护结点顺序。且目标是像递归实现一样有个统一模板,不同遍历顺序只需要调整几行代码的顺序。
2 思路
每个节点都访问两次,第一次压栈,第二次再输出。主需要注意压栈时候,自身、左、右的顺序。且每个中结点后面添加一个null结点作为标识待输出结点
3 先序
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if(root==null){
return ans;
}
Deque<TreeNode> q = new LinkedList<>();
q.addLast(root);
while(!q.isEmpty()){
root=q.removeLast();
if(root!=null){
if(root.right!=null){
q.addLast(root.right);
}
if(root.left!=null){
q.addLast(root.left);
}
q.addLast(root);
q.addLast(null);
}else{//null前面一个就是要进答案数组的
root=q.removeLast();
ans.add(root.val);
}
}
return ans;
}
}
先序遍历是自身、左、右。压栈的时候就反过来,右、左、自身
4 中序
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if(root==null){
return ans;
}
Deque<TreeNode> q = new LinkedList<>();
q.addLast(root);
while(!q.isEmpty()){
root=q.removeLast();
if(root!=null){
if(root.right!=null){
q.addLast(root.right);
}
q.addLast(root);
q.addLast(null);
if(root.left!=null){
q.addLast(root.left);
}
}else{//null前面一个就是要进答案数组的
root=q.removeLast();
ans.add(root.val);
}
}
return ans;
}
}
左、中、右–>右、中、左
5 后序
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> ans = new ArrayList<>();
if(root==null){
return ans;
}
Deque<TreeNode> q = new LinkedList<>();
q.addLast(root);
while(!q.isEmpty()){
root=q.removeLast();
if(root!=null){
q.addLast(root);
q.addLast(null);
if(root.right!=null){
q.addLast(root.right);
}
if(root.left!=null){
q.addLast(root.left);
}
}else{//null前面一个就是要进答案数组的
root=q.removeLast();
ans.add(root.val);
}
}
return ans;
}
}
左、右、中–>中、右、左