1 二叉树的层序遍历
二叉树的层序遍历即,按照层一排一排的读取节点的值,如下图,层序遍历得到的就应该是:“1234567”。
public static void levelOrder(TreeNode root) {
if (root == null) {
return;
}
// 创建一个链表,然后将根节点放到链表中
Queue<TreeNode> result = new LinkedList<>();
result.offer(root);
// 将头节点取出并打印,并把它非空的左右子树放入链表
// 循环执行,每次取出头节点
// 下一次进入取头节点就是取到上一个节点的左孩子,以此类推
while (true) {
TreeNode cur = result.poll();
if (cur == null) {
break;
}
System.out.print(cur.val);
if (cur.left != null) {
result.offer(cur.left);
}
if (cur.right != null) {
result.offer(cur.right);
}
}
}
2 判断是否是完全二叉树
完全二叉树概念:
完全二叉树是从满二叉树而来的,满二叉树即每一个节点都有两个子节点或者没有子节点。
完全二叉树是指若树的深度为 n,那么1 ~ (n-1) 层的节点都达到最大个数,即1 ~ (n-1) 层是满二叉树,n 层的节点全都连续排列在靠左边。
代码思路:(分两个阶段来判定)
第一阶段
–>
每个节点都有两个子树,如果某个节点没有子树,那么进入第二阶段;如果某个节点只有右子树没有左子树,直接返回false;如果某个节点只有左子树没有右子树,也进入第二阶段。
第二阶段
–>
每个节点都必须没有子树,如果遇到有子树的节点则判定 false。
public static boolean isCompleteTree(TreeNode root) {
// 通过层序遍历的方式来实现
if (root == null) {
return true;
}
// 分为两个阶段判定
// 这个变量为 false ,表示当前是第一阶段
// 变量名为 true 表示进入第二阶段
boolean isLevel2 = false;
// 利用层序遍历
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(true) {
TreeNode cur = queue.poll();
// cur == null 说明整个树已经遍历完了
if (cur == null) {
break;
}
// 针对当前节点进行访问
// 此处的访问是一系列的逻辑判断
if (!isLevel2) {
// 第一阶段的逻辑
if (cur.left != null && cur.right != null) {
// 符合要求的节点,继续往下遍历
// 此时直接把左右子树入队列
queue.offer(cur.left);
queue.offer(cur.right);
} else if (cur.left == null && cur.right != null) {
// 第一阶段发现只有右子树的节点
// 说明这个树一定不是完全二叉树
return false;
} else if (cur.left != null && cur.right == null) {
// 遇到了这个节点不符合第一阶段的条件
// 进入到第二阶段进行判定
isLevel2 = true;
queue.offer(cur.left);
} else {
// 这个节点没有子树
// 也是进入到第二阶段进行判定
// 因为上一个 elseif 中需要入队列,所以这两步不能合并
isLevel2 = true;
}
} else {
// 第二阶段的逻辑
if (cur.left != null || cur.right != null) {
// 发现第二阶段的某个节点的子树不为空
// 此时就不是完全二叉树
return false;
}
}
}
// 遍历了整个树,都没有找到反例 return false,就 return true
return true;
}