(一)
从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。
例如:
给定二叉树: [3,9,20,null,null,15,7]
返回:
[3,9,20,15,7]
提示:
节点总数 <= 1000
解法:利用队列层序遍历
思路
- 将头结点入队列
- 记录当前队列的长度n
- 从队头出一个结点,并将其值加入到数组内,再判断其左右结点是否为空,如果不为空则加入队列,此步骤执行n次
- 重复步骤2,3直到队列为空为止
特殊情况
如果root为空,返回一个空数组
代码
public int[] levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if(root == null) return new int[0];
List<Integer> list = new ArrayList<>();
queue.add(root);
while (!queue.isEmpty()){
// 将上一层的结点出队,并且将他们的左右孩子结点入队
for (int i = queue.size(); i > 0; --i) {
TreeNode temp = queue.poll();
list.add(temp.val);
if(temp.left != null) queue.add(temp.left);
if(temp.right != null) queue.add(temp.right);
}
}
int n = list.size();
// ArrayList<Integer> 转换为 int数组,因为Integer数组不能直接转换为int,因此需要遍历
int[] result = new int[n];
for (int i = 0; i < n; i++) {
result[i] = list.get(i);
}
return result;
}
提交结果
(二)
从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。
例如:
给定二叉树: [3,9,20,null,null,15,7],
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
限制
节点总数 <= 1000
解法:利用队列特性层序遍历
思路
和(一)的思路一样,区别在于返回时将每一层的结点分别开来
那么相应的,执行步骤3时,新建一个数组,用来存放当前层的结点值,当前层遍历完成后,将数组加入到List中
特殊情况
如果root为空,返回一个空数组
代码
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new LinkedList<>();
// 先进先出
Queue<TreeNode> queue = new LinkedList<>();
if(root == null) return result;
// 首先根节点入队
queue.add(root);
// 当前层的结点个数(因为第一层只有根结点,所以是1),下一层的结点个数
int currCount = 1, nextCount;
while (!queue.isEmpty()){
// 下一层个数初始为0;
nextCount = 0;
// 存储当前层的结点数值
List<Integer> currNum = new LinkedList<>();
// 遍历当前层结点,看是否有子结点,如果有就入队,并且下一层的结点数加一
for (int i = 0; i < currCount; i++) {
// 出队列
TreeNode temp = queue.poll();
currNum.add(temp.val);
// 如果左右不空,则入队
if(temp.left != null){
queue.add(temp.left);
++nextCount;
}
if(temp.right != null){
queue.add(temp.right);
++nextCount;
}
}
// 增加一层
result.add(currNum);
// 下一层变为当前层
currCount = nextCount;
}
return result;
}
提交结果
(三)
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,
第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7]
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
提示:
节点总数 <= 1000
解法:层序遍历
思路
同(二)的区别在于,偶数层需要逆序
借助双端队列,如果当前是奇数层,那么数值依次加入到队尾
如果当前层是偶数层,那么数值依次加入到队头
特殊情况
根节点为空
代码
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
if(root == null) return result;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
int m = 1;
while (!queue.isEmpty()){
LinkedList<Integer>list = new LinkedList<>();
for (int i = queue.size(); i > 0 ; --i) {
TreeNode temp = queue.poll();
// 如果为奇数层,将数值加入到链表尾部,偶数层则加入到头部
if((m & 1) == 1) list.addLast(temp.val);
else list.addFirst(temp.val);
if(temp.left != null) queue.add(temp.left);
if(temp.right != null) queue.add(temp.right);
}
// 层数加一
++m;
result.add(list);
}
return result;
}