思想:

1. 假设以x节点为头,且可以向x左树和x右树要任何信息

2. 在上一步假设下讨论以x为头节点的树得到答案的可能性

3. 列出所有可能性后,确定到底需要向左树和右树要什么样的信息

4. 把左树信息和右树信息求全集,就是任何一棵子树都需要返回的信息S

5. 递归函数都返回S,每一棵子树都这么要求

6. 写代码,在代码中考虑如何把左树信息和右树信息整合出整棵树信息

模板:

三部曲:1.定义结构体S;2.写递归入口函数;3.写递归函数;

写递归函数又分三部曲:1.BaseCase;2.递归调用;3.为x构造S属性

  1. // 定义S的数据结构体,方便处理
  2. private static class Info {
  3. public boolean isBalanced;
  4. public int height;
  5. public Info(boolean i, int h) {
  6. isBalanced = i;
  7. height = h;
  8. }
  9. }
  10. // 递归函数入口,即对外提供的方法名
  11. public boolean checkNodeIsBalance(Node head) {
  12. // 返回S结构体中的某一属性
  13. return process(head).isBalanced;
  14. }
  15. // 递归函数返回S
  16. private Info process(Node x) {
  17. // 递归终止条件,BaseCase
  18. if (x == null) {
  19. return new Info(); // 或者return null
  20. }
  21. // 递归调用,遍历左右子树(可以认为左右子树分别准备好了想获取的数据S)
  22. Info leftInfo = process(x.left);
  23. Info rightInfo = process(x.right);
  24. // 为x节点构造S结构属性信息
  25. boolean isBalanced; // 略
  26. int height; // 略
  27. // 返回x节点整体的统计结果
  28. return new Info(isBalanced, height);
  29. }

举个例子,给定头节点,求这棵二叉树是不是平衡二叉树

  1. // 定义节点
  2. private static class Node {
  3. public int value;
  4. public Node left;
  5. public Node right;
  6. public Node(int data) {
  7. this.value = data;
  8. }
  9. }
  10. // 定义S结构体
  11. private static class Info{
  12. public boolean isBalanced;
  13. public int height;
  14. public Info(boolean i, int h) {
  15. isBalanced = i;
  16. height = h;
  17. }
  18. }
  19. // 递归函数入口,对外方法
  20. public static boolean isBalanced(Node head) {
  21. return process(head).isBalanced;
  22. }
  23. private static Info process(Node x) {
  24. // BaseCase
  25. if(x == null) {
  26. return new Info(true, 0);
  27. }
  28. // 递归调用
  29. Info leftInfo = process(x.left);
  30. Info rightInfo = process(x.right);
  31. // 为x节点准备S属性
  32. int height = Math.max(leftInfo.height, rightInfo.height) + 1;
  33. boolean isBalanced = true;
  34. if(!leftInfo.isBalanced || !rightInfo.isBalanced || Math.abs(leftInfo.height - rightInfo.height) > 1) {
  35. isBalanced = false;
  36. }
  37. // 返回x节点整体统计结果
  38. return new Info(isBalanced, height);
  39. }