平衡二叉树

分析:

为了避免树的高度增长过快,降低二叉排序树的性能,我们规定在插入和删除二叉树的结点时,要保证任意结点

的左、右子树高度差的绝对值不能超过1,将这样的二叉树称为平衡二叉树

平衡二叉树可定义为它或者是一棵空树,或者是具有以下性质的二叉树:它的左子树和右子树都是平衡二叉树,且

左子树和右子树的高度差的绝对值不超过1。

先序遍历思想:

	public boolean IsBalanced_Solution(TreeNode root)
	{
		//judge_AVL(root, balance, h);
		//return balance;
		// 如果二叉树为空,是AVL
		if (root == null) 	
		{
			return true;
		}
		
		// 如果左右子树高度差大于1,不是AVL
		if (Math.abs(getHeight(root.left) - getHeight(root.right)) > 1) 
		{
			return false;
		}
		return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
		
		// 等价于
		/*
		 return (Math.abs(getHeight(root.left) - getHeight(root.right)) <= 1) &&
		 		IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
		 */
	}
	
	// 递归求解二叉树的某个结点的高度
	public int getHeight(TreeNode root)
	{
		if (root == null)
			return 0;
		return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
	}
	

这种做法的缺点是在判断上层结点的时候,会多次重复遍历下层结点,增加了不必要的开销。如果改为从

下往上遍历,如果子树是平衡二叉树,则返回子树的高度;如果发现子树不是平衡二叉树,则直接停止遍历,这

样至多只对每个结点访问一次。

public boolean IsBalanced_Solution(TreeNode root)
	{
		return getDepth(root) != -1;
	}

	private int getDepth(TreeNode root)
	{
		if (root == null)
			return 0;
		int left = getDepth(root.left); // 计算左子树高度
		if (left == -1) // 只要左子树不平衡,就不再判断右子树
			return -1;
		int right = getDepth(root.right); // 计算右子树高度
		if (right == -1) // 右子树不平衡,返回-1
			return -1;
		return Math.abs(left - right) > 1 ? -1 : 1 + Math.max(left, right);
	}
	

相比较上面一种解法,下面这种解法,就得需要遍历完所有的结点一次,才知道是否是AVL。

	private boolean isBalanced = true;
	public boolean IsBalanced_Solution(TreeNode root)
	{
		getDepth(root);
		return isBalanced;
	}
	
	public int getDepth(TreeNode root)
	{
		// 子树为空
		if (root == null)
			return 0;
		// 得到左子树的高度
		int left = getDepth(root.left);
		// 得到右子树的高度
		int right = getDepth(root.right);
		
		// 左右子树高度差大于1
		if (Math.abs(left - right) > 1)
			isBalanced = false;
		
		// 结点的高度为最高子树高度+1
		return right > left ? right + 1 : left + 1;
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值