Tree Tranverse: Pre/In/Post/Level Order tranverse
Preorder:
迭代写法:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res; //we need to check it is null or not
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur = stack.pop();
res.add(cur.val);
if(cur.right != null) stack.push(cur.right); //先push右边的子节点 这样以后Pop出来就是左边的先pop,但是如果之后有变形题目,说逆序的preorder 直接把push的顺序调换过来即可
if(cur.left != null) stack.push(cur.left);
}
return res;
}
}
递归写法:
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
helper(root, res);
return res;
}
public void helper(TreeNode root, List<Integer> res){
if(root == null) return;
//先add再递归
res.add(root.val);
helper(root.left, res);
helper(root.right, res);
}
}
Inorder tranverse:
迭代写法:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
LinkedList<TreeNode> stack = new LinkedList<>();
TreeNode cur = root; //cur指针
while(cur != null || !stack.isEmpty()){
while(cur != null){ //每一次都是尽可能往左边走 直到走不动
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
res.add(cur.val);
cur = cur.right;
}
return res;
}
}
递归写法:
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
helper(res, root);
return res;
}
public void helper(List<Integer> res, TreeNode root){
if(root == null){
return;
}
helper(res, root.left);
res.add(root.val);
helper(res, root.right);
}
}
postorder tranverse:跟前序遍历比较像
迭代写法:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
LinkedList<TreeNode> stack = new LinkedList<>();
stack.push(root);
while(!stack.isEmpty()){
TreeNode cur = stack.pop();
res.add(0, cur.val);
if(cur.left != null) stack.push(cur.left); //先Push left这样每次pop出来的就是右边的
if(cur.right != null) stack.push(cur.right);
}
return res;
}
}
递归写法:
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if(root == null) return res;
helper(root, res);
return res;
}
public void helper(TreeNode root, List<Integer> res){
if(root == null) return;
//先add再递归
helper(root.left, res);
helper(root.right, res);
res.add(root.val);
}
}
level order:
迭代写法:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
TreeNode cur = root; //跟中序遍历一样 需要指针
queue.offer(cur); //但是要先把root给放进queue里面
while(queue.size() != 0){
List<Integer> list = new ArrayList<>();
int size = queue.size();
for(int i = 0; i<size; i++){//这个for语句的作用只是为了好截取list 然后add到res中 实际上的层次遍历本质上和前序遍历一样
cur = queue.poll();
list.add(cur.val);
if(cur.left != null) queue.offer(cur.left);
if(cur.right != null) queue.offer(cur.right);
}
res.add(list);
}
return res;
}
}
递归写法:
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
helper(res, root, 0);
return res;
}
public void helper(List<List<Integer>> res, TreeNode root, int level) {
if(root == null) return;
if(res.size() <= level){ //如果需要开辟新的写入层 就直接开辟
res.add(new ArrayList<>());
}
//跟前序遍历有点像 先add再双递归
res.get(level).add(root.val);
helper(res, root.left, level + 1);
helper(res, root.right, level + 1);
}
}
总结:
preorder, inorder, postorder are based on DFS
level order are based on BFS.
the iterate way to tranverse:
because pre/in/post are based on DFS, so they use stack(linkedlist)
but level order uses queue(linkedlist)
for inorder and level order tranvese, we needs to use a cur pointer on root
but for pre and post order, we only needs to push the root.
Core statement: while statement:
preorder: while stack is not empty: pop() and added cur.val, stack.pop(cur.right) stack.pop(cur.left)
postorder: while stack is not empty: pop() and added cur.val to the index of 0, stack.push(cur.left) stack.push(cur.right)
inorder: cur = root, while cur not null and stack not empty, while(cur != null){ stack.push(cur); cur = cur.left;}cur = stack.pop(); res.add(cur.val); cur = cur.right; //go all the way left each time until can’t move any further, pop and add it, and move to the right.
levelorder: queue.offer(cur), while (queue.size() != 0) size = queue.size() for () {pull add cur.left, cur.right}\
the recusive way to tranverse:
千种后序遍历都是一样的 只是什么时候添加节点值不一样。
层次遍历和前序遍历比较像 但是需要在递归函数里加一个扩容的操作

浙公网安备 33010602011771号