从上到下打印二叉树题集
题目
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
分析
考虑使用队列先进先出的特点;
-
算法流程:
- 特例处理: 当树的根节点为空,则直接返回空列表 [] ;
- 初始化: 打印结果列表 res = [] ,包含根节点的队列 queue = [root] ;* BFS 循环: 当队列 queue 为空时跳出;
- 出队: 队首元素出队,记为 node;
- 打印: 将 node.val 添加至列表 tmp 尾部;
- 添加子节点: 若 node 的左(右)子节点不为空,则将左(右)子节点加入队列 queue ;
- 返回值: 返回打印结果列表 res 即可。
-
复杂度:
- 时间: O(N) : N为树的节点个数,BFS搜说是需要循环N次。
- 空间: O(N): 最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N) 大小的额外空间。
code
// 主要涉及到队列和数组的相关操作还不是很熟~~~
class Solution {
public int[] levelOrder(TreeNode root) {
if(root == null) return new int[0];
Queue<TreeNode> queue = new LinkedList<>(){{ add(root); }}; // LinkedList实现了Queue的接口;
ArrayList<Integer> ans = new ArrayList<>();
while(!queue.isEmpty()){
TreeNode node = queue.poll();
ans.add(node.val);
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
int[] res = new int[ans.size()];
for(int i = 0; i < ans.size(); i++){
res[i] = ans.get(i);
}
return res;
}
}
python
python版本对队列的操作更简单,不用记复杂的函数;
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if root == None:
return []
queue = [root]
res = []
# 使用队列保证了先进先出的特性
while(queue):
node = queue.pop(0)
res.append(node.val)
if(node.left): queue.append(node.left)
if(node.right): queue.append(node.right)
return res
32 - II
题目:
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
分析:
只用考虑将每一层的节点单独的存放在一个数组中。对每一层的节点个数做一个循环就行。
- java
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>(); // LinkedList实现了Queue的接口;
List<List<Integer>> ans = new ArrayList<>();
if(root != null) queue.add(root);
while(!queue.isEmpty()){
List<Integer> temp = new ArrayList<>();
// for(int i = 0; i < queue.size(); i++){ // 倒着来????
for(int i = queue.size(); i > 0; i--){
TreeNode node = queue.poll();
temp.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
}
ans.add(temp);
}
return ans;
}
}
- python
class Solution(object):
def levelOrder(self, root):
"""
:type root: TreeNode
:rtype: List[List[int]]
"""
if not root: return []
queue = [root]
res = []
while queue:
temp = [] // 用一维存放每一层的节点值
for _ in range(len(queue)): // 把位于同一层的节点存放在temp中;
node = queue.pop(0)
temp.append(node.val)
if node.left: queue.append(node.left)
if node.right: queue.append(node.right)
res.append(temp)
return res
按之字形顺序打印二叉树
##题目描述
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
分析
解题思路:其实就是二叉树的层级遍历,不过是在遍历的时候,需要将偶数层的节点逆序。
关键点:每次只处理上次在queue中剩余的节点,这是上一层的所有节点。 处理完后刚好将下一层的所有节点(包含null)又全部放了进去。
数据结构: 用队列queue保存上一层的所有节点,一个list保存上一层的遍历结果。 (节点按照先进先出,处理到某个节点时,将某节点的左右子树入队)。
code
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.Queue;
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer> >();
if(pRoot == null) return res;
// LinkedList类实现了Queue接口,
Queue<TreeNode> queue = new LinkedList<TreeNode>();
int count = 0;
//Queue使用时要尽量避免Collection的add()和remove()方法,add()和remove()方法在失败的时候会抛出异常。
queue.offer(pRoot);
// queue.isEmpty(), stack用empty();
while(!queue.isEmpty()){
ArrayList<Integer> list = new ArrayList<>();
int size = queue.size(); // 得到队列的长度
for(int i = 0; i < size; i++){
TreeNode node = queue.poll(); // 对头出队;
if(node == null){
continue;
}
if(count % 2 == 0){
list.add(node.val);
}
if(count % 2 == 1){
list.add(0, node.val); // 每次添加在第一个位置,自动实现该层的元素逆序;
}
queue.offer(node.left);
queue.offer(node.right);
}
count++;
//res.add(list); //如果为空,最后一个元素会变成[],例如: [[8],[10,6],[5,7,9,11],[]]
if(queue.size() > 0){
res.add(list);
}
}
return res;
}
}
写法二
import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer> >();
if(pRoot == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(pRoot);
int count = 0;
while(! queue.isEmpty()){
ArrayList<Integer> ans = new ArrayList<>();
int size = queue.size();
for(int i = 0; i < size; i++){
TreeNode node = queue.poll();
if(node == null) continue;
if(count % 2 == 0){
ans.add(node.val);
}
if(count % 2 == 1){
ans.add(0, node.val);
}
if(node.left != null) queue.offer(node.left);
if(node.right != null) queue.offer(node.right);
}
count++;
res.add(ans);
}
return res;
}
}
参考Krahets