下面的递归套路如果可以灵活应用的话,几乎可以解决所有二叉树的题目,包括树上的动态规划
二叉树的递归套路:
- 假设以x节点为头,假设可以向X左树和X右树要任何信息
- 在上一步的假设下,讨论以X为头节点的树,得到答案的可能性(最重要)
- 列出所有可能性后,确定到底需要向左树和右树要什么样的信息
- 把左树信息和右树信息求全集,就是任意一棵子树都需要返回的信息S
- 递归函数都返回S,每一棵子树都这么求
- 写代码,在代码中考虑如何把左树的信息和右树的信息整合出整棵树的信息
一、判断是否为满二叉树
代码如下:
package com.Algorithm;
public class Code6_IsFull {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static class Info {
int height;
int nodes;
public Info(int height, int nodes) {
this.height = height;
this.nodes = nodes;
}
}
public static boolean isFullBT(Node head) {
if (head == null)
return true;
return (1 << process(head).height - 1) == process(head).nodes ? true : false;
}
public 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 allNodes = leftInfo.nodes + rightInfo.nodes + 1;
return new Info(height, allNodes);
}
}
二、判断是否为完全二叉树
代码如下:
package com.Algorithm;
import java.util.LinkedList;
import java.util.Queue;
//判断是否为完全二叉树
public class Code3_IsCBT {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static boolean IsCBT(Node head) {
if(head==null) {
return true;
}
Queue<Node> queue = new LinkedList<>();
boolean leaf = false;//判断是否有左右双全的节点
Node l = null;
Node r = null;
queue.add(head);
while(!queue.isEmpty()) {
Node node = queue.poll();
l= node.left;
r= node.right;
if((l==null&&r!=null)||(leaf&&(l!=null||r!=null))) return false;
if(l!=null) queue.add(node.left);
if(r!=null) queue.add(node.right);
if(l==null||r==null) leaf = true;
}
return true;
}
}
三、判断是否为二叉搜索树
代码如下:
package com.Algorithm;
import java.util.ArrayList;
public class Code4_IsBST {
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 boolean IsBST;
public int max;
public int min;
public Info(boolean IsBST,int max,int min) {
IsBST = IsBST;
max = max;
min = min;
}
}
public static boolean isBST2(Node head) {
if(head==null) return true;
return process(head).IsBST;
}
public static Info process(Node x) {
if(x==null) return null;
Info leftInfo = process(x.left);
Info rightInfo = process(x.right);
int max = x.value;
int min = x.value;
if(leftInfo!=null) {
max = Math.max(max, leftInfo.max);
}
if(rightInfo!=null) {
max = Math.max(max, rightInfo.max);
}
if(rightInfo!=null) {
min = Math.min(min, rightInfo.min);
}
if(leftInfo!=null) {
min = Math.min(min, leftInfo.min);
}
boolean IsBST = false;
if(leftInfo!=null&&!leftInfo.IsBST) {
IsBST=false;
}
if(leftInfo!=null&&(leftInfo.max>=x.value)) {
IsBST=false;
}
if(rightInfo!=null&&!rightInfo.IsBST) {
IsBST=false;
}
if(rightInfo!=null&&(rightInfo.min<=x.value)) {
IsBST=false;
}
return new Info(IsBST, max, min);
}
}
四、判断是否为平衡二叉树
代码如下:
package com.Algorithm;
public class Code5_IsBalanced {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static class Info{
boolean isBalanced;
int height;
public Info(boolean isBalanced, int height) {
this.isBalanced = isBalanced;
this.height = height;
}
}
public static boolean isBalanced(Node head) {
if(head==null) {
return true;
}
return process1(head).isBalanced;
}
public static Info process1(Node x) {
if(x==null) return new Info(true, 0);
Info leftInfo = process1(x.left);
Info rightInfo = process1(x.right);
int height = Math.max(leftInfo.height, rightInfo.height)+1;
boolean isBalanced = true;
if(!leftInfo.isBalanced) isBalanced = false;
if(!rightInfo.isBalanced) isBalanced = false;
if(Math.abs(leftInfo.height-rightInfo.height)>1) isBalanced = false;
return new Info(isBalanced, height);
}
}
最后加上一道面试题目中考过的一道题目:
题目描述: 给定一棵二叉树的头结点head,任何两个节点之间都存在距离,返回整棵二叉树的最大距离
运用上面的二叉树递归套路,这道题目会变得非常简单
代码如下:
package com.Algorithm;
public class Code7_MaxDistance {
public static class Node {
public int value;
public Node left;
public Node right;
public Node(int data) {
this.value = data;
}
}
public static class Info {
int maxDistance;
int height;
public Info(int maxDistance, int height) {
this.maxDistance = maxDistance;
this.height = height;
}
}
public static int MaxDistance(Node head) {
if (head == null)
return 0;
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 maxDistance = 0;
int p1 = leftInfo.maxDistance;
int p2 = rightInfo.maxDistance;
int p3 = leftInfo.height + rightInfo.height + 1;
maxDistance = Math.max(Math.max(p1, p2), p3);
return new Info(maxDistance, height);
}
}