二叉树的层序遍历
难度:中等
题目链接: 层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例:
输入:root = [3,9,20,null,null,15,7]
输出:[
[3],
[9,20],
[15,7]
]
层序遍一个二叉树。就是从左到右一层一层的去遍历二叉树。
这种操作需要借用一个辅助数据结构 队列 来实现, 队列先进先出,符合一层一层遍历思想,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑
层序遍历方式就是图论中的广度优先边路,只不过我们应用在二叉树上
图如下:
这样就实现了层序从左到右遍历二叉树。
二叉树结点定义:
//二叉树节点的定义。
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;
}
}
方式一:迭代方式 借助队列
思路:
1.创建一个集合resList嵌套集合itemList分别存入每层节点
2.判断如果树为空则直接return结束
3.借助队列queue,首先根节点入对
4.如果队列不为空进入循环
5.创建集合itemList存入每层节点(并且每次循环之后刷新集合为空 方便存入下一层)
6.len记录入队的长度,也就是每层不为空节点的数量
7.当队列的长度大于0时进入循环,节点根据循环依次出队并保存节点 tmpNode
8.把此出队节点存入内部集合itemList
9.判断当前根节点的左孩子节点 以及右孩子节点是否为空,若不为空就分别入队,为空不做任何操作
10.因每次循环都有节点出队,所以len--更新队列长度(即存入每层节点入集合后 进行下一个操作)
11.每次大循环结束后外部结合resList添加内部itemList入外部集合**
代码
public class Solution{
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return resList;
}
Queue<TreeNode> queue = new LinkedList<TreeNode>();
queue.offer(root);
while (!queue.isEmpty()) {
List<Integer> itemList = new ArrayList<>();
int len = queue.size();
while (len > 0) {
TreeNode tmpNode = queue.poll();
itemList.add(tmpNode.val);
if (tmpNode.left != null) queue.offer(tmpNode.left);
if (tmpNode.right != null) queue.offer(tmpNode.right);
len--;
}
resList.add(itemList);
}
return resList;
}
}
方式二:递归方式
代码:
class Solution{
public List<List<Integer>> resList = new ArrayList<List<Integer>>();
public List<List<Integer> levelOrder(TreeNode root){
levelOrder(root,0);
return resList;
}
public void levelOrder(TreeNode node,Integer deep){
//跳出递归条件
if(node == null){
return;
}
deep++; //层级增加
if(resList.size() < deep){
//当层级增加时,list的Item也增加,利用list的索引值进行层级界定
List<Integer> itemList = new ArrayList<>();
resList.add(itemList);
}
resList.get(deep - 1).add(node.val);
levelOrder(node.left,deep);
levelOrder(node.right,deep);
}
}