二叉树的层序遍历
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
而这种层序遍历方式就是图论中的广度优先遍历,只不过我们应用在二叉树上。
使用队列实现二叉树广度优先遍历,动画如下:
代码:
力扣题目:102.二叉树的层序遍历
class Solution {
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
//checkFun01(root,0);
checkFun02(root);
return resList;
}
//DFS--递归方式
public void checkFun01(TreeNode node, Integer deep) {
if (node == null) return;
deep++;
if (resList.size() < deep) {
//当层级增加时,list的Item也增加,利用list的索引值进行层级界定
List<Integer> item = new ArrayList<Integer>();
resList.add(item);
}
resList.get(deep - 1).add(node.val);
checkFun01(node.left, deep);
checkFun01(node.right, deep);
}
//BFS--迭代方式--借助队列
public void checkFun02(TreeNode node) {
if (node == null) return;
Queue<TreeNode> que = new LinkedList<TreeNode>();
que.offer(node);
while (!que.isEmpty()) {
List<Integer> itemList = new ArrayList<Integer>();
int len = que.size();
while (len > 0) {
TreeNode tmpNode = que.poll();
itemList.add(tmpNode.val);
if (tmpNode.left != null) que.offer(tmpNode.left);
if (tmpNode.right != null) que.offer(tmpNode.right);
len--;
}
resList.add(itemList);
}
}
}
力扣题目:二叉树的层次遍历 II
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if(root == null){
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
List<Integer> levelList = new ArrayList<>();
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode peek = que.peekFirst();
levelList.add(que.pollFirst().val);
if (peek.left != null) {
que.offerLast(peek.left);
}
if (peek.right != null) {
que.offerLast(peek.right);
}
}
list.add(levelList);
}
List<List<Integer>> result = new ArrayList<>();
for (int i = list.size() - 1; i >= 0; i-- ) {
result.add(list.get(i));
}
return result;
}
}
力扣题目:199. 二叉树的右视图
//解法一:递归
/**
* 解法:队列,迭代。
* 每次返回每层的最后一个字段即可。
*/
public List<Integer> rightSideView(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while (!que.isEmpty()) {
int levelSize = que.size();
for (int i = 0; i < levelSize; i++) {
TreeNode poll = que.pollFirst();
if (poll.left != null) {
que.addLast(poll.left);
}
if (poll.right != null) {
que.addLast(poll.right);
}
if (i == levelSize - 1) {
list.add(poll.val);
}
}
}
return list;
}
}
//小优化:每层右孩子先入队。
public List<Integer> rightSideView(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while(!que.isEmpty()){
int len = que.size();
for (int i = 0; i < len; i++) {
TreeNode poll = que.pollFirst();
if (poll.right != null) {
que.addLast(poll.right);
}
if (poll.left != null) {
que.addLast(poll.left);
}
if (i == 0) {
list.add(poll.val);
}
}
}
return list;
}
力扣题目:637. 二叉树的层平均值
class Solution {
public List<Double> averageOfLevels(TreeNode root) {
List<Double> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if (root == null) {
return list;
}
que.offerLast(root);
while(!que.isEmpty()){
int len = que.size();
double sum = 0.0;
for(int i = 0; i < len; i++){
TreeNode poll = que.pollFirst();
sum += poll.val;
if (poll.left != null) {
que.addLast(poll.left);
}
if (poll.right != null) {
que.addLast(poll.right);
}
}
list.add(sum / len);
}
return list;
}
}
力扣题目:429. N 叉树的层序遍历
class Solution {
public List<List<Integer>> levelOrder(Node root) {
List<List<Integer>> list = new ArrayList<>();
Deque<Node> que = new LinkedList<>();
if(root == null){
return list;
}
que.offerLast(root);
while(!que.isEmpty()){
int len = que.size();
List<Integer> item = new ArrayList<>();
for(int i = 0; i < len; i++){
Node poll = que.pollFirst();
item.add(poll.val);
List<Node> children = poll.children;
if (children == null || children.size() == 0) {
continue;
}
for (Node child : children) {
if (child != null) {
que.offerLast(child);
}
}
}
list.add(item);
}
return list;
}
}
力扣题目:515.在每个树行中找最大值
class Solution {
public List<Integer> largestValues(TreeNode root) {
List<Integer> list = new ArrayList<>();
Deque<TreeNode> que = new LinkedList<>();
if(root == null){
return list;
}
que.offerLast(root);
while(!que.isEmpty()){
int len = que.size();
int max = Integer.MIN_VALUE;
for(int i = 0; i < len; i++){
TreeNode poll = que.pollFirst();
max = Math.max(max, poll.val);
if(poll.left != null){
que.addLast(poll.left);
}
if(poll.right != null){
que.addLast(poll.right);
}
}
list.add(max);
}
return list;
}
}
力扣题目:116. 填充每个节点的下一个右侧节点指针
class Solution {
public Node connect(Node root) {
Deque<Node> que = new LinkedList<>();
if(root == null){
return root;
}
que.offerLast(root);
while(!que.isEmpty()){
int len = que.size();
Node cur = que.poll();
if (cur.left != null) que.add(cur.left);
if (cur.right != null) que.add(cur.right);
for(int i = 1; i < len; i++){
Node next = que.poll();
if (next.left != null) que.add(next.left);
if (next.right != null) que.add(next.right);
cur.next = next;
cur = next;
}
}
return root;
}
}
力扣题目:填充每个节点的下一个右侧节点指针 II
本题只是换了一种树,但思路代码都是一样的
力扣题目:104. 二叉树的最大深度
class Solution {
public int maxDepth(TreeNode root) {
int deep = 0;
Deque<TreeNode> que = new LinkedList<>();
if(root == null){
return deep;
}
que.offerLast(root);
while(!que.isEmpty()){
deep++;
int len = que.size();
for(int i = 0; i < len; i++){
TreeNode node = que.poll();
if(node.left != null){
que.offer(node.left);
}
if(node.right != null){
que.offer(node.right);
}
}
}
return deep;
}
}
力扣题目:111. 二叉树的最小深度
class Solution {
public int minDepth(TreeNode root) {
int deep = 0;
Deque<TreeNode> que = new LinkedList<>();
if(root == null){
return deep;
}
que.offerLast(root);
while(!que.isEmpty()){
deep++;
int len = que.size();
while(len > 0){
TreeNode node = que.poll();
if(node.left == null && node.right == null){
return deep;
}
if(node.left != null){
que.offer(node.left);
}
if(node.right != null){
que.offer(node.right);
}
len--;
}
}
return deep;
}
}