这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战
二叉树的遍历从来都是高频题型,从深度遍历的前序 + 中序 + 后序 遍历二叉树,到广度的层序遍历;简单来说,层序遍历就是把二叉树分层,然后每一层从左到右遍历。并且拓展出递归算法和非递归;再从性能安全的角度,分析递归的压栈导致栈溢出问题;采用非递归实现。
二叉树的层序遍历
该题出自力扣的102题 —— 二叉树的层序遍历【中等题】
审题
给你二叉树的根节点
root,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
- 该题题意十分明了,就是层序遍历
- 需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
- 使用队列实现二叉树广度优先遍历
- 但是之所以是中等题,应该就是需要返回List<List>,也就是需要分析出同一层的节点
- 解题
- 判断当前节点是否为空
- 利用队列去实现非递归的层序遍历
- 节点进队列
- 弹出队列头部节点
- 节点左右子节点进队列
- 判断是否为同一层的节点
- 定义变量count,当前队列的长度
- 每次新增队列操作后,count--
- 时间复杂度O(n),每个节点进队列 + 出队列 为O(n)
- 空间复杂度O(n),创建一个长度为n的队列
编码
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;
}
}
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null)return new ArrayList<>();
List<List<Integer>> lists = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()){
//计算queue的长度
int count = queue.size();
List<Integer> list = new ArrayList<>();
while (count>0){
TreeNode node = queue.poll();
list.add(node.val);
if (node.left != null)queue.add(node.left);
if (node.right != null)queue.add(node.right);
count--;
}
lists.add(list);
}
return lists;
}