剑指 offer代码解析——面试题39判断平衡二叉树(高效方法)

时间:2022-05-03
本文章向大家介绍剑指 offer代码解析——面试题39判断平衡二叉树(高效方法),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:输入一颗二叉树的根结点,判断该树是不是平衡二叉树。

如果某二叉树中任意结点的左右子树的高度相差不超过1,那么它就是一棵平衡二叉树。

分析:所谓平衡二叉树就是要确保每个结点的左子树与右子树的高度差在-1到1之间。

由于之前一题已经给出了二叉树高度的计算方法,因此本题最直观的思路就是分别计算每个结点的左子树高和右子树高,从而判断一棵树的所有结点是否均为平衡二叉树。

上一篇博客中采用了一种较为常规的思路,但由于涉及到重复计算子树的高度,因此性能并不好,接下来提出一种从下而上,依次判断每个子树是否为平衡二叉树的同时计算每棵子树的高度,并将其记录下供上层结点使用。

常规思路请移步至:点击打开链接

上述方法效率很低,因为采用了从上至下的判断方向,因此某些结点的高度被重复计算。

若要避免高度的重复计算,我们需要从下至上计算每棵子树的高度,并保存每棵子树的高度,供上方的结点在计算高度时使用。

若要从下至上遍历结点,那就得使用后序遍历,先遍历左右子树,最后遍历根结点。

/**
 * 题目:输入一颗二叉树的根结点,判断该树是不是平衡二叉树。
 * 如果某二叉树中任意结点的左右子树的高度相差不超过1,那么它就是一棵平衡二叉树。
 * @author 大闲人柴毛毛
 * @date 2016年4月2日
 */
public class BalanceTree {
	/**
	 * 上述方法效率很低,因为采用了从上至下的判断方向,因此某些结点的高度被重复计算。
	 * 若要避免高度的重复计算,我们需要从下至上计算每棵子树的高度,并保存每棵子树的高度,供上方的结点在计算高度时使用。
	 * 若要从下至上遍历结点,那就得使用后序遍历,先遍历左右子树,最后遍历根结点。
	 * 代码如下:
	 */
	Height height = new Height();
	public static <T> boolean isBalanceTree_2(Node<T> root,Height height){
		//健壮性判断:若树为空
		if(root==null){
			height.height = 0;
			return true;
		}
		
		Height left_height = new Height();
		Height right_height = new Height();
		//若左右子树均是平衡二叉树
		if(isBalanceTree_2(root.left,left_height) && isBalanceTree_2(root.right,right_height)){
			//判断当前是否为平衡二叉树
			int diff = left_height.height-right_height.height;
			if(diff==-1 || diff==1 || diff==0){
				//计算当前子树的高度
				height.height = (left_height.height<right_height.height ? right_height.height : left_height.height)+1;
				return true;
			}
			return false;
		}
		
		return false;
	}
	
	/**
	 * 测试
	 */
	public static void main(String[] args){
		//构造一棵平衡二叉树
		Node<Integer> node1 = new Node<Integer>();
		Node<Integer> node2 = new Node<Integer>();
		Node<Integer> node3 = new Node<Integer>();
		Node<Integer> node4 = new Node<Integer>();
		Node<Integer> node5 = new Node<Integer>();
		Node<Integer> node6 = new Node<Integer>();
		Node<Integer> node7 = new Node<Integer>();
		Node<Integer> node8 = new Node<Integer>();
		Node<Integer> node9 = new Node<Integer>();
		
		node1.data = 1;
		node2.data = 2;
		node3.data = 3;
		node4.data = 4;
		node5.data = 5;
		node6.data = 6;
		node7.data = 7;
		node8.data = 8;
		node9.data = 9;
		
		node1.left = node2;
		node1.right = node3;
		node2.left = node4;
		node2.right = node5;
		node5.left = node7;
		node3.right = node6;
//		node7.left = node8;
//		node8.left = node9;
		
		System.out.println(isBalanceTree_2(node1,new Height()));
	}
}

//存放当前树的高度
class Height{
	int height;
}