二叉树的层序遍历
- 1.层序遍历
- 2.实例
- 2.1二叉树的层序遍历
- 2.2 二叉树的层序遍历 II
- 2.3 二叉树的右视图
- 2.4 二叉树的层平均值
- 2.5 N叉树的层序遍历
- 2.6在每个树行中找最大值
- 2.7二叉树的最大深度
- 2.8二叉树的最小深度
- 2.9翻转二叉树
- 2.10完全二叉树的节点个数
- 2.11左叶子之和
- 2.11找树左下角的值
1.层序遍历
层序遍历一个二叉树。就是从左到右一层一层的区遍历二叉树。为了实现层序遍历,我们需要借助一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
2.实例
2.1二叉树的层序遍历
二叉树的层序遍历
思路:
1.创建队列用来存储节点,创建list集合用来存储结果
2.逐层记录结果即可。
/*** 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>> ans = new ArrayList<>();//用来输出结果Queue<TreeNode> queue = new LinkedList<>();//创建一个队列,用来逐层存放if(root==null) return ans;queue.offer(root);while(!queue.isEmpty()){List<Integer> list = new ArrayList<>();//用于存放值int len = queue.size();for(int i=0;i<len;i++){TreeNode temp = queue.poll();list.add(temp.val);//放进listif(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}ans.add(list);}return ans;}
}
2.2 二叉树的层序遍历 II
二叉树的层序遍历 II
思路:
和上题基本一致,只需要在输出结果之前将结果反转即可。
/*** 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>> ans = new ArrayList<>();//用来输出结果Queue<TreeNode> queue = new LinkedList<>();//创建一个队列,用来逐层存放if(root==null) return ans;queue.offer(root);while(!queue.isEmpty()){List<Integer> list = new ArrayList<>();//用于存放值int len = queue.size();for(int i=0;i<len;i++){TreeNode temp = queue.poll();list.add(temp.val);//放进listif(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}ans.add(list);}//将ans反转即可List<List<Integer>> ans1 = new ArrayList<>();for(int i=ans.size()-1;i>=0;i--){ans1.add(ans.get(i));}return ans1;}
}
2.3 二叉树的右视图
二叉树的右视图
和模板思路一致,只不过添加的是队列的最后一个元素
if(i==len-1){//保证当前的最后后子节点
ans.add(temp.val);
}
/*** 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> rightSideView(TreeNode root) {List<Integer> ans = new ArrayList<>();//用来输出结果Queue<TreeNode> queue = new LinkedList<>();//队列用来存放节点if(root==null) return ans;queue.offer(root);while(!queue.isEmpty()){int len = queue.size();for(int i=0;i<len;i++){TreeNode temp = queue.poll();if(i==len-1){//保证当前的最后后子节点ans.add(temp.val);}if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}}return ans;}
}
2.4 二叉树的层平均值
二叉树的层平均值
依旧套用模板,只是在记录每一层的值,并输出即可。
/*** 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<Double> averageOfLevels(TreeNode root) {List<Double> ans =new ArrayList<>();//用于输出答案Queue<TreeNode> queue = new LinkedList<>();//用于存放节点if(root==null) return ans;queue.offer(root);//将节点存入队列中while(!queue.isEmpty()){int len = queue.size();Double sum = 0.0;for(int i = 0;i<len;i++){TreeNode temp = queue.poll();sum+=temp.val;if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}ans.add(sum/len);}return ans;}
}
2.5 N叉树的层序遍历
N叉树的层序遍历
本题我们需要注意的是如何添加孩子节点。
/*
// Definition for a Node.
class Node {public int val;public List<Node> children;public Node() {}public Node(int _val) {val = _val;}public Node(int _val, List<Node> _children) {val = _val;children = _children;}
};
*/class Solution {public List<List<Integer>> levelOrder(Node root) {List<List<Integer>> ans = new ArrayList<>();//用于输出答案Queue<Node> queue = new LinkedList<>();//用于存储节点if(root==null) return ans;queue.offer(root);//将节点存入队列中while(!queue.isEmpty()){int len = queue.size();List<Integer> list = new ArrayList<>();//记录每层的值for(int i=0;i<len;i++){Node temp = queue.poll();list.add(temp.val);List<Node> children = temp.children;//记录temp的孩子节点if(children==null||children.size()==0) continue;for(Node child:children){if(child!=null){//如果孩子节点不为空queue.offer(child);//添加到队列}}}ans.add(list);}return ans;}
}
2.6在每个树行中找最大值
在每个树行中找最大值
注意注意Collection.max()这一方法,输出集合中的最大值
/*** 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> largestValues(TreeNode root) {List<Integer> ans = new ArrayList<>();//用于输出答案Queue<TreeNode> queue = new LinkedList<>();//用于存放节点if(root==null) return ans;queue.offer(root);//存放当前节点while(!queue.isEmpty()){int len = queue.size();List<Integer> list = new ArrayList<>();//用于记录每一层的值for(int i=0;i<len;i++){TreeNode temp = queue.poll();//暂时存放节点list.add(temp.val);//记录没层的所有值if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}ans.add(Collections.max(list));//注意Collection.max()}return ans;}
}
2.7二叉树的最大深度
二叉树的最大深度
遍历完每一层时深度加一即可。
/*** 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 int maxDepth(TreeNode root) {Queue<TreeNode> queue = new LinkedList<>();//存放节点int depth=0;if(root==null) return depth;queue.offer(root);//将节点入队while(!queue.isEmpty()){int len = queue.size();for(int i=0;i<len;i++){TreeNode temp = queue.poll();if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}depth++;//层数加一}return depth;}
}
2.8二叉树的最小深度
二叉树的最小深度
只需要找出左右节点都为null的节点,返回当前深度即可。
/*** 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 int minDepth(TreeNode root) {List<Integer> ans = new ArrayList<>();Queue<TreeNode> queue = new LinkedList<>();if(root==null) return 0;queue.offer(root);//根节点入队int depth=0; while(!queue.isEmpty()){depth++;//每进入一层,depth++int len = queue.size();for(int i=0;i<len;i++){TreeNode temp = queue.poll();//找到叶子节点if(temp.left==null&&temp.right==null) return depth;if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}}return depth;}
}
2.9翻转二叉树
反转二叉树
思路:使用层序遍历,然后将该层的左右子树翻转即可。
```java
/*** 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 TreeNode invertTree(TreeNode root) {Queue<TreeNode> queue =new LinkedList<>();if(root==null) return null;queue.offer(root);//根节点入队while(!queue.isEmpty()){int len = queue.size();for(int i=0;i<len;i++){TreeNode temp=queue.poll();//取出当前根节点swapChild(temp);//交换根节点的左右子节点//继续收集下一层的节点if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}}return root;}//交换根节点的左右子节点private void swapChild(TreeNode root){TreeNode temp = root.left;root.left=root.right;root.right=temp;}
}
2.10完全二叉树的节点个数
完全二叉树的节点个数
依旧使用层序遍历,定义一个计数器记录节点个数即可
/*** 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 int countNodes(TreeNode root) {if(root==null) return 0;Queue<TreeNode> queue = new LinkedList<>();//存储节点int num =0;//记录节点个数queue.offer(root);while(!queue.isEmpty()){int len = queue.size();for(int i=0;i<len;i++){TreeNode temp = queue.poll();//出队num++;if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}}return num;}
}
2.11左叶子之和
左叶子之和
本题依旧可以使用层序遍历,解题的关键是如何找到左叶子节点的
/*** 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 int sumOfLeftLeaves(TreeNode root) {if(root==null) return 0;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);int sum=0;while(!queue.isEmpty()){TreeNode temp=queue.poll();//注意左叶子的判断if(temp.left!=null&&temp.left.left==null&&temp.left.right==null){sum+=temp.left.val;}if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}return sum;}
}
2.11找树左下角的值
找树左下角的值
注意int的使用,只有一个值
/*** 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 {/**注意只有一个值,所有用int*/public int findBottomLeftValue(TreeNode root) {int ans=0;Queue<TreeNode> queue =new LinkedList<>();//放节点queue.offer(root);while(!queue.isEmpty()){int len =queue.size();for(int i=0;i<len;i++){TreeNode temp = queue.poll();//取出当前节点if(i==0) ans = temp.val;if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}}return ans;}
}