二叉树的前序、中序、后序遍历的非递归实现
-
写在前面
public class TreeNode { public int val; public TreeNode left; public TreeNode right; }
前序遍历
-
实现一:使用单个栈完成
public class Preorder { public List<Integer> preorder(TreeNode root) { if(root==null) return new ArrayList<>(); Deque<TreeNode> stk = new ArrayDeque<>(); List<Integer> result = new ArrayList<>(); stk.push(root); while(!stk.isEmpty()) { TreeNode p = stk.pop(); result.add(p.val); if(p.right!=null) stk.push(p.right); if(p.left!=null) stk.push(p.left); } return result; } }
-
实现二:使用一个栈、一个指针完成
public class Preorder { public List<Integer> preorder(TreeNode root) { List<Integer> result = new ArrayList<>(); Deque<TreeNode> stk = new ArrayDeque<>(); TreeNode p = root; while(p!=null || !stk.isEmpty()) { if(p==null) p=stk.pop(); result.add(p.val); if(p.right!=null) stk.push(p.right); p=p.left; } return result; } }
-
实现三:只使用一个指针完成 - Morris
public class Preorder { public List<Integer> preorder(TreeNode root) { List<Integer> result = new ArrayList<>(); TreeNode p = root; while(p!=null) { if(p.left==null) { result.add(p.val); p=p.right; } else { TreeNode q = p.left; while(q.right!=null && q.right!=p) q=q.right; if(q.right==null) { result.add(p.val); q.right=p; p=p.left; } else { q.right=null; p=p.right; } } } return result; } }
中序遍历
-
实现一:使用两个栈完成
public class Inorder { public List<Integer> inorder(TreeNode root) { if(root==null) return new ArrayList<>(); List<Integer> result = new ArrayList<>(); Deque<TreeNode> stk = new ArrayDeque<>(); Deque<Boolean> stk2 = new ArrayDeque<>(); stk.push(root); stk2.push(false); while(!stk.isEmpty()) { TreeNode p=stk.pop(); boolean visited = stk2.pop(); if(!visited) { stk.push(p); stk2.push(true); if(p.left!=null) { stk.push(p.left); stk2.push(false); } } else { result.add(p.val); if(p.right!=null) { stk.push(p.right); stk2.push(false); } } } return result; } }
-
实现二:使用一个栈、一个指针完成
public class Inorder { public List<Integer> inorder(TreeNode root) { List<Integer> result = new ArrayList<>(); Deque<TreeNode> stk = new ArrayDeque<>(); TreeNode p = root; while(p!=null || !stk.isEmpty()) { if(p==null) { p=stk.pop(); result.add(p.val); p=p.right; } else { stk.push(p); p=p.left; } } return result; } }
-
实现三:只使用一个指针完成 - Morris
public class Inorder { public List<Integer> inorder(TreeNode root) { List<Integer> result = new ArrayList<>(); TreeNode p = root; while(p!=null) { if(p.left==null) { result.add(p.val); p=p.right; } else { TreeNode q=p.left; while(q.right!=p && q.right!=null) q=q.right; if(q.right==null) { q.right=p; p=p.left; } else { q.right=null; result.add(p.val); p=p.right; } } } return result; } }
后序遍历
-
实现一:使用两个栈实现
public class Postorder { public List<Integer> postorder(TreeNode root) { if(root==null) return new ArrayList<>(); List<Integer> result = new ArrayList<>(); Deque<TreeNode> stk = new ArrayDeque<>(); Deque<Integer> stk2 = new ArrayDeque<>(); stk.push(root); stk2.push(0); while(!stk.isEmpty()) { TreeNode p=stk.pop(); int visited = stk2.pop(); if(visited==2) { result.add(p.val); } else if(visited==1) { stk.push(p); stk2.push(2); if(p.right!=null) { stk.push(p.right); stk2.push(0); } } else { // visited==0 stk.push(p); stk2.push(1); if(p.left!=null) { stk.push(p.left); stk2.push(0); } } } return result; } }
-
实现二:使用一个栈、两个指针实现
public class Postorder { public List<Integer> postorder(TreeNode root) { List<Integer> result = new ArrayList<>(); Deque<TreeNode> stk = new ArrayDeque<>(); TreeNode p=root, q=null; while(p!=null || !stk.isEmpty()) { if(p==null) { p=stk.pop(); if(p.right==null || q==p.right) { result.add(p.val); q=p; p=null; } else { stk.push(p); p=p.right; } } else { stk.push(p); p=p.left; } } return result; } }
-
实现三:使用一个指针实现(先得到逆序,再逆序),借助Morris的思想
二叉树的后序遍历为LRN,与NRL得到的遍历顺序是完全相反的,因此我们先按NRL来遍历,将得到的结果逆序即可,而NRL的遍历顺序又与前序遍历类似,因此可以借助Morris的思想来实现
public class Postorder { public List<Integer> postorder(TreeNode root) { List<Integer> result = new ArrayList<>(); TreeNode p=root; while(p!=null) { if(p.right==null) { result.add(p.val); p=p.left; } else { TreeNode q=p.right; while(q.left!=null && q.left!=p) q=q.left; if(q.left==null) { result.add(p.val); q.left=p; p=p.right; } else { q.left=null; p=p.left; } } } Collections.reverse(result); return result; } }