思想:
1. 假设以x节点为头,且可以向x左树和x右树要任何信息
2. 在上一步假设下讨论以x为头节点的树得到答案的可能性
3. 列出所有可能性后,确定到底需要向左树和右树要什么样的信息
4. 把左树信息和右树信息求全集,就是任何一棵子树都需要返回的信息S
5. 递归函数都返回S,每一棵子树都这么要求
6. 写代码,在代码中考虑如何把左树信息和右树信息整合出整棵树信息
模板:
三部曲:1.定义结构体S;2.写递归入口函数;3.写递归函数;
写递归函数又分三部曲:1.BaseCase;2.递归调用;3.为x构造S属性
// 定义S的数据结构体,方便处理private static class Info {public boolean isBalanced;public int height;public Info(boolean i, int h) {isBalanced = i;height = h;}}// 递归函数入口,即对外提供的方法名public boolean checkNodeIsBalance(Node head) {// 返回S结构体中的某一属性return process(head).isBalanced;}// 递归函数返回Sprivate Info process(Node x) {// 递归终止条件,BaseCaseif (x == null) {return new Info(); // 或者return null}// 递归调用,遍历左右子树(可以认为左右子树分别准备好了想获取的数据S)Info leftInfo = process(x.left);Info rightInfo = process(x.right);// 为x节点构造S结构属性信息boolean isBalanced; // 略int height; // 略// 返回x节点整体的统计结果return new Info(isBalanced, height);}
举个例子,给定头节点,求这棵二叉树是不是平衡二叉树
// 定义节点private static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value = data;}}// 定义S结构体private static class Info{public boolean isBalanced;public int height;public Info(boolean i, int h) {isBalanced = i;height = h;}}// 递归函数入口,对外方法public static boolean isBalanced(Node head) {return process(head).isBalanced;}private static Info process(Node x) {// BaseCaseif(x == null) {return new Info(true, 0);}// 递归调用Info leftInfo = process(x.left);Info rightInfo = process(x.right);// 为x节点准备S属性int height = Math.max(leftInfo.height, rightInfo.height) + 1;boolean isBalanced = true;if(!leftInfo.isBalanced || !rightInfo.isBalanced || Math.abs(leftInfo.height - rightInfo.height) > 1) {isBalanced = false;}// 返回x节点整体统计结果return new Info(isBalanced, height);}
