25、剑指 Offer 32 - II. 从上到下打印二叉树 II
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
扫描二维码关注公众号,回复:
15339805 查看本文章
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
package com.example.lecode.Tree;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
/**
* 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
* 例如:
* 给定二叉树: [3,9,20,null,null,15,7],
*
* 3
* / \
* 9 20
* / \
* 15 7
* 返回其层次遍历结果:
*
* [
* [3],
* [9,20],
* [15,7]
* ]
*
*/
public class levelOrder {
public static void main(String[] args) {
levelOrder Solution = new levelOrder();
TreeNode root = new TreeNode(3);
TreeNode node1 = new TreeNode(9);
TreeNode node2 = new TreeNode(20);
TreeNode node3 = new TreeNode(15);
TreeNode node4 = new TreeNode(7);
root.left = node1;
root.right = node2;
node2.left = node3;
node2.right = node4;
List<List<Integer>> lists = Solution.levelOrder(root);
System.out.print("二叉树层序遍历结果为:");
for(List<Integer> list : lists){
System.out.print(list + " ");
}
}
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> list = new ArrayList<>();
if(root == null ){
return list;
}
/**
* Queue<TreeNode> 是一个队列的数据结构,其中 TreeNode 是队列中存储的元素类型。
* 队列是一种先进先出(First-In-First-Out, FIFO)的数据结构,类似于现实生活中的排队。
* 新的元素被添加到队列的尾部,而从队列中取出元素时,总是从队列的头部开始。
* 在Java中,可以使用接口 java.util.Queue 来表示队列,并通过其实现类(如 LinkedList 和 ArrayDeque)来创建具体的队列对象。
* 常见的队列操作方法包括 offer()、poll()、peek()、isEmpty() 和 size() 等。
*
* 底层数据结构:LinkedList底层基于链表实现,而ArrayDeque底层基于数组实现。
* LinkedList是List接口的实现类,它同时也实现了Queue接口。在Java中,List是一种有序的集合,
* 可以按照元素的插入顺序进行访问和操作。LinkedList在实现List接口的基础上,通过链表结构提供了对元素的插入、删除和访问等操作。
*/
Queue<TreeNode> queue = new LinkedList<>();
// offer(element) 向队列尾部插入一个元素,如果成功则返回true,如果队列满了则返回false
// poll() 移除并返回队列头部元素,如果队列为空则返回null
// peek() 返回队列头部元素但不移除元素,如果队里为空则返回null
// isEmpty()
// size() 返回队列元素个数
// queue.offer(root) 将整个 root 对象作为一个元素添加到队列 queue 中。
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
List<Integer> newList = new ArrayList<>();
// 循环这个queue.size(); 主要是为了配合下面防止头节点(这里也就是实现分层的(第0层循环1次,第二次循环了两次))
// 为什么我们在第二次准确的循环了两次,因为我们在其队列中放置了两个节点对象。(也就是左右节点放置进去了)
for(int i = 0; i<size; i++){
//poll() 移除并返回队列头部元素,如果队列为空则返回null
TreeNode node = queue.poll();
// 虽然这里TreeNode node = root; 和 TreeNode node = queue.poll()的效果一样的,但是我们是想要将queue腾空为后面继续装载腾出位置
// TreeNode node = root;
// 这里是放置我们的头结点的。
newList.add(node.val);
if(node.left != null){
// 如何实现将node上一个头结点去掉?就是将其下的子节点放进队列中
// 这里也是将node.left这个整个对象添加到队列中
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
list.add(newList);
}
return list;
}
}