NC+LC:实现二叉树遍历
二叉树的前、中、后序遍历
前序遍历
LC 144.二叉树的前序遍历:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/
解法一:递归
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { List<Integer> list = new ArrayList<>(); public List<Integer> preorderTraversal(TreeNode root) { //递归实现前序遍历 if(root == null) return list; list.add(root.val); list = preorderTraversal(root.left); list = preorderTraversal(root.right); return list; } }
解法二:栈
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<Integer> preorderTraversal(TreeNode root) { //使用栈实现前序遍历 List<Integer> list = new ArrayList<>(); if(root == null) return list; Stack<TreeNode> stack = new Stack<>(); TreeNode currNode = root; while(currNode != null || !stack.isEmpty()){ while(currNode != null){ //遍历入栈左节点,入栈的顺序就是前序遍历的顺序 list.add(currNode.val); stack.push(currNode); currNode = currNode.left; } if(!stack.isEmpty()){ currNode = stack.pop(); currNode = currNode.right; //出栈当前节点,遍历其右节点 } } return list; } }
中序遍历
解法一:递归
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { List<Integer> list = new ArrayList<>(); public List<Integer> inorderTraversal(TreeNode root) { //递归实现中序遍历 if(root == null) return list; list = inorderTraversal(root.left); list.add(root.val); list = inorderTraversal(root.right); return list; } }
解法二:栈
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> list = new ArrayList<>(); if(root == null) return list; Stack<TreeNode> stack = new Stack<>(); TreeNode currNode = root; while(currNode != null || !stack.isEmpty()){ while(currNode != null){ //有左节点就循环入栈左节点 stack.push(currNode); currNode = currNode.left; } if(!stack.isEmpty()){ currNode = stack.pop(); list.add(currNode.val); //出栈的顺序就是中序遍历的顺序 currNode = currNode.right; //判断当前节点的右节点 } } return list; } }
后序遍历
解法一:递归
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { List<Integer> list = new ArrayList<>(); public List<Integer> postorderTraversal(TreeNode root) { //递归实现后序遍历 if(root == null) return list; list = postorderTraversal(root.left); list = postorderTraversal(root.right); list.add(root.val); return list; } }
解法二:栈
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<Integer> postorderTraversal(TreeNode root) { //使用栈实现后序遍历 List<Integer> list = new ArrayList<>(); if(root == null) return list; Stack<TreeNode> stack = new Stack<>(); TreeNode currNode = root; while(currNode != null || !stack.isEmpty()){ while(currNode != null){ //与前序遍历类似,但是是遍历入栈右节点,出栈遍历左节点 list.add(currNode.val); stack.push(currNode); currNode = currNode.right; } if(!stack.isEmpty()){ currNode = stack.pop().left; } } Collections.reverse(list); //最后再反转List集合 return list; } }
二叉树的层序遍历
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<List<Integer>> levelOrder(TreeNode root) { //使用队列实现层序遍历 List<List<Integer>> res = new ArrayList<List<Integer>>(); if(root == null) return res; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while(!queue.isEmpty()){ int size = queue.size(); //记录当前层级的节点数 List<Integer> list = new ArrayList<>(); for(int i = 0; i < size; i++){ //遍历当前层级的所有节点 TreeNode currNode = queue.poll(); list.add(currNode.val); if(currNode.left != null) queue.offer(currNode.left); //左右节点不为空就将其入队 if(currNode.right != null) queue.offer(currNode.right); } res.add(list); } return res; } }
二叉树的之字形层序遍历
NC14 按之字形顺序打印二叉树
思路
- 第一层从左向右,下一层从右向左,一直这样交替
- 思路基本与二叉树的层序遍历一样,刚开始想过利用栈或者根据不同层级决定入队的顺序,但都无法得到正确的结果
- 既然无法通过改变出入队来实现交替遍历,那就从将它加入ArrayList时入手
- 按照正常的出队,将元素加入到当前层级的ArrayList中,在偶数层时进行头插入,这样后一个元素就在前一个的前面了,在奇数层时进行尾插入
实现代码
import java.util.*; /* * public class TreeNode { * int val = 0; * TreeNode left = null; * TreeNode right = null; * } */ public class Solution { /** * * @param root TreeNode类 * @return int整型ArrayList<ArrayList<>> */ public ArrayList<ArrayList<Integer>> zigzagLevelOrder (TreeNode root) { // write code here ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); if(root == null){ return res; } Queue<TreeNode> queue = new LinkedList<TreeNode>(); queue.offer(root); int level = 1;//层级 while(!queue.isEmpty()){ ArrayList<Integer> arrList = new ArrayList<Integer>(); int size = queue.size(); //当前层级的元素数 for(int i = 0; i<size; i++){//将该层元素遍历出队 TreeNode node = queue.poll(); if(level % 2 == 0){//偶数层进行头插入 arrList.add(0, node.val); }else{//奇数层进行尾插入 arrList.add(node.val); } if(node.left != null){ queue.offer(node.left); } if(node.right != null){ queue.offer(node.right); } } level++; res.add(arrList); } return res; } }
二叉树的自底向上层序遍历
LC 107. 二叉树的层序遍历 II:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
思路
遍历过程与正常层序遍历类似,只是将每一层的结果以头插入的方式放入结果集合中,ArrayList的add()方法正常是进行尾插入的,add(0, list)可实现头插入
实现代码
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode() {} * TreeNode(int val) { this.val = val; } * TreeNode(int val, TreeNode left, TreeNode right) { * this.val = val; * this.left = left; * this.right = right; * } * } */ class Solution { public List<List<Integer>> levelOrderBottom(TreeNode root) { List<List<Integer>> resList = new ArrayList<List<Integer>>(); if(root == null){ return resList; } Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while(!queue.isEmpty()){ int size = queue.size(); //当前层级的节点数 List<Integer> list = new ArrayList<>(); for(int i = 0; i < size; i++){ //遍历当前层级的所有节点 TreeNode node = queue.poll(); list.add(node.val); if(node.left != null){ //当前节点有左右节点就进行入队 queue.offer(node.left); } if(node.right != null){ queue.offer(node.right); } } resList.add(0, list); //头插入 } return resList; } }