「这是我参与2022首次更文挑战的第33天,活动详情查看:2022首次更文挑战」。
一、判断二叉树是否是完全二叉树
1、分析
判断二叉树是否是完全二叉树的核心思路:二叉树的按层遍历(队列,宽度优先遍历),一个一个的判断是否出现过情况一或情况二
-
情况一:Y节点,没有左孩子,只有右孩子,则一定不是完全二叉树
-
情况二:当第一次遇到左右不双全,剩下节点必须为叶子节点
2、实现
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static boolean isCBT1(Node head) {
if (head == null) {
return true;
}
LinkedList<Node> queue = new LinkedList<>();
// 是否遇到过左右两个孩子不双全的节点
boolean leaf = false;
Node l = null;
Node r = null;
queue.add(head);
while (!queue.isEmpty()) {
head = queue.poll();
l = head.left;
r = head.right;
if (
// 如果遇到了不双全的节点之后,又发现当前节点不是叶节点
(leaf && (l != null || r != null))
||
(l == null && r != null)
) {
return false;
}
if (l != null) {
queue.add(l);
}
if (r != null) {
queue.add(r);
}
if (l == null || r == null) {
leaf = true;
}
}
return true;
}
二、判断二叉树是否是满二叉树
1、分析
满二叉树的性质:如果树的高度是h,那么节点数为2^h - 1
任何以x为头的整个树,看它的高度h与它的节点数,满不满足这个关系
2、实现
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static class Info {
public int height;
public int nodes;
public Info(int h, int n) {
height = h;
nodes = n;
}
}
// 收集整棵树的高度h,和节点数n
// 只有满二叉树满足 : 2 ^ h - 1 == n
public static boolean isFull(Node head) {
if (head == null) {
return true;
}
Info all = process(head);
return (1 << all.height) - 1 == all.nodes;
}
private static Info process(Node head) {
if (head == null) {
return new Info1(0, 0);
}
Info leftInfo = process(head.left);
Info rightInfo = process(head.right);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
int nodes = leftInfo.nodes + rightInfo.nodes + 1;
return new Info(height, nodes);
}
三、整颗二叉树的最大距离
给定一棵二叉树的头节点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离
1、分析
人为规定距离就是从开始到结束的节点数量(沿途经过的节点数量)
目标:x为头的整颗树的最大距离,罗列可能性
x无关
- 可能一:x左树上的最大距离
- 可能二:x右树上的最大距离
x有关:x左树与x最远(左树的高度)+ x右树与x最远(右树的高度)+ 1(自身节点)
2、实现
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static class Info {
public int maxDistance;
public int height;
public Info(int m, int h) {
maxDistance = m;
height = h;
}
}
public static int maxDistance(Node head) {
return process(head).maxDistance;
}
private static Info process(Node x) {
if (x == null) {
return new Info(0, 0);
}
Info leftInfo = process(x.left);
Info rightInfo = process(x.right);
int height = Math.max(leftInfo.height, rightInfo.height) + 1;
int p1 = leftInfo.maxDistance;
int p2 = rightInfo.maxDistance;
int p3 = leftInfo.height + rightInfo.height + 1;
int maxDistance = Math.max(Math.max(p1, p2), p3);
return new Info(maxDistance, height);
}
四、总结
罗列可能性的时候,要想着,x有关的可能性,x无关的可能性
怎么确定有关的可能性?怎么确定无关的可能性?
这道题跟距离有关,那么x有关的可能性就是沿途中经过(路过)x,x无关的可能性就是沿途中不经过(路过)x