二叉树遍历的变形题
树结点的定义
public static class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}//TreeNode
1. 牛客BM27 按之字形打印顺序打印二叉树
思路:
- 层序遍历:用list收集当前层的节点,res收集遍历结果
- 层数判断:若根为第0层,则到单数层时就需要将list反转
代码:
public ArrayList<ArrayList<Integer> > Print(TreeNode root) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();//收集遍历序列
if(root == null) return res;
Queue<TreeNode> que = new LinkedBlockingQueue<TreeNode>();
que.add(root);
int ceng = 0;//当前层
while(!que.isEmpty()) {
int size = que.size();
ArrayList<Integer> level = new ArrayList<Integer>();//当前层的序列
for(int i = 0; i < size; i++) {
TreeNode cur = que.poll();
level.add(cur.val);
if(cur.left != null) que.offer(cur.left);
if(cur.right != null) que.offer(cur.right);
}
if(ceng++ % 2 == 1) Collections.reverse(level);
res.add(level);
}
return res;
}//fun
技术要点:list逆置
Collections.reverse(level);//Collections工具类
2. 牛客BM28 二叉树的最大深度
思路:层序遍历
其他的遍历方式也可以,但如果是前/中/后序遍历的话,每遍历道一个叶子都要判断迭代当前最大深度,个人觉得有点麻烦。而使用层序遍历的话,每遍历一层就层数++即可。
题目5.1中也涉及了层数标记,标记方法都是一样的
代码:
public int maxDepth (TreeNode root) {
if(root == null) return 0;
//不空
LinkedBlockingQueue<TreeNode> que = new LinkedBlockingQueue<TreeNode>();
que.add(root);
int deep = 0;
while(!que.isEmpty()) {
deep++;
int size = que.size();//上一层的节点数
for(int i = 0; i < size; i++) {
TreeNode cur = que.poll();
if(cur.left != null) que.add(cur.left);
if(cur.right != null) que.add(cur.right);
}//for
}//while
return deep;
}//fun
3. 牛客NC234 二叉树的最小深度
思路:层序遍历
需要记录当前层数。
在将当前结点的左右结点分别加入队列之前,如果当前结点的左右孩子均为空,则停止遍历,当前层数即为最大深度。
代码:
public int run (TreeNode root) {
if(root == null) return 0;
Queue<TreeNode> que = new LinkedBlockingQueue<TreeNode>();
que.add(root);
int depth = 0;
outer: while(!que.isEmpty()) {
int size = que.size();//当前层
depth++;
for(int i = 0; i < size; i++) {
TreeNode cur = que.poll();
if(cur.left == null && cur.right == null) break outer;
if(cur.left != null) que.add(cur.left);
if(cur.right != null) que.add(cur.right);
}
}//while
return depth;
}//fun
4. 牛客NC84 完全二叉树的结点数
思路:层序遍历,标记结点数
代码:
public int nodeNum(TreeNode root) {
if(root == null) return 0;
Queue<TreeNode> que = new LinkedBlockingQueue<TreeNode>();
que.add(root);
int count = 0;
while(!que.isEmpty()) {
TreeNode cur = que.poll();
count++;
if(cur.left != null) que.add(cur.left);
if(cur.right != null) que.add(cur.right);
}//while
return count;
}