树的递归思想套路使用

* 二叉树的递归套路总结(递归的最核心思想:通过递归,可以把任何问题都简化为根节点,左儿子,右儿子的问题
* 即:把左右子树通过递归给归一化为左右儿子节点(把整棵树看作一个整体))
* 1.进行递归,分别从根节点向左子树和右子树进行递归(对任何问题通用)

* 2.分析题目所要求的条件,去根据题目要求得到根节点,左子树和右子树的逻辑关系,并在每一次递归中将这种
* 关系给模拟出来(因为使用了递归,其实就可以把一整棵子树看作一个节点来进行考虑)
*
* 补充:因为我们通常是把一棵子树抽象成一个节点来进行考虑,一般来说这个节点要存储多个所需要的值,所以一般
* 都要自己去定义一个返回类型,让所有需要的值都能在递归中返回传递

* 适用条件:对于那些值能够通过递归正常传递的题目类型,可使用该套路。不可使用的例子:求一棵树的中位数
* 得到左子树和右子树的中位数是无法得到新树的中位数,所以无法用该方法求解

 

举例分析:

例子1:

平衡二叉树:任意节点的左子树和右子树的高度差小于等于1
判断一棵树是否为平衡二叉树

* 套路解析:
* 1.确认递归的方式:从某个节点递归到它的左儿子节点和右儿子节点
* 2.对每个节点的分析(要拆分递归):即该节点的左子树和右子树的高度差小于等于1

代码:

 1 public static class ReturnType{//定义一个特殊的返回类型,能同时返回这棵树的最大高度和是否平衡
 2         public int height;
 3         public boolean isBalance;
 4         
 5         public ReturnType(int height,boolean isBalance) {
 6             this.height = height;
 7             this.isBalance = isBalance;
 8         }
 9     }
10     
11     //执行递归过程
12     public static ReturnType process(Node root) {
13         if (root == null) {
14             return new ReturnType(0,true);
15         }
16         //对左右子树进行递归
17         ReturnType lt = process(root.left);
18         ReturnType rt = process(root.right);
19         //对每一次递归进行具体的判断分析
20         int height = Math.max(lt.height, rt.height) + 1;
21         //只有当左子树平衡,右子树平衡,且两树高度差小于1时,这棵树才平衡
22         boolean isBalance = lt.isBalance && rt.isBalance && (Math.abs(rt.height - lt.height) <= 1);
23         return new ReturnType(height,isBalance);
24     }
25     //原函数
26     public static boolean isBalanceTree(Node root) {
27         return process(root).isBalance;
28     }

 

 

例子2:

判断一棵树是否为搜索二叉树:
1.递归判断左树和右树是否为搜索二叉树
2.判断根节点是否大于左树的最大值(这个最大值因为有了递归,所以不用遍历整棵树,只要在每次递归时都把这个值保存住,一直递归传递即可),是否小于右树的最小值

 1 public static class DataType{
 2         public boolean isBST;
 3         public int max;//用于左树求最大值
 4         public int min;//用于右树求最小值 
 5         
 6         public DataType(boolean isBST,int max,int min) {
 7             this.isBST = isBST;
 8             this.max = max;
 9             this.min = min;
10         }
11     }
12     
13     public static DataType process1(Node root) {
14         if (root == null) {
15             return null;
16         }
17         //分别获得左右树的信息
18         DataType ld = process1(root.left);
19         DataType rd = process1(root.right);
20         
21         //进行比较分析处理
22         int min = root.val, max = root.val;
23         boolean isBST = true;
24         //通过以下操作就可以得到整棵树的最小值和最大值(必须要得到,因为这棵树也可能是子树,用于下一步的递归返回)
25         if (ld != null) {
26             min = Math.min(min, ld.min);
27             max = Math.max(max, ld.max);
28         }
29         if (rd != null) {
30             min = Math.min(min, rd.min);
31             max = Math.max(max, rd.max);
32         }
33         //判断是否为搜索二叉树
34         if (ld != null && (ld.isBST == false || ld.max > root.val)) {//若左树不为空,且不是搜索二叉树
35                                                                     //或左树最大值大于根节点的值
36             isBST = false;
37         }
38         if (rd != null && (rd.isBST == false || rd.min < root.val)) {//若右树不为空,且不是搜索二叉树
39                                                                     //或右树最小值小于根节点的值
40             isBST = false;
41         }
42         return new DataType(isBST,max,min);
43     }

 

例子3:判断一棵树是否为满二叉树:

* 1.向左右子树递归
* 2.每次收集子树的高度和节点总数,判断高度和节点的总数关系只要在最后总子树即可

代码及解析:

 1 //返回类型:树所在的高度和这棵子树的节点个数
 2     public static class Info{
 3         public int height;
 4         public int nodes;
 5         
 6         public Info(int height,int nodes) {
 7             this.height = height;
 8             this.nodes = nodes;
 9         }
10     }
11     
12     public static Info process2(Node root) {
13         if (root == null) {
14             return new Info(0,0);
15         }
16         Info info1 = process2(root.left);
17         Info info2 = process2(root.right);
18         int height = Math.max(info1.height, info2.height) + 1;
19         int nodes = info1.nodes + info2.nodes + 1;
20         return new Info(height,nodes);
21     }
22     
23     public static boolean isFull(Node root) {
24         if (root == null) {
25             return true;
26         }
27         int height = process2(root).height;
28         int nodes = process2(root).nodes;
29         if (Math.pow(2, height) - 1 == nodes) {
30             return true;
31         }
32         else {
33             return false;
34         }
35     }

 

posted @ 2022-04-13 22:39  jue1e0  阅读(119)  评论(0)    收藏  举报