【笔试】50、二叉树的深度&&判断平衡二叉树

二叉树结构

/**
 *题目:实现二叉树,输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。加上输入的前序遍历和中序遍历的结果中都不含重复的数字。
 *		例如输入前序遍历的序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出图2.6所示的二叉树并输出它的头结点。
 *		二叉树节点的定义如下:
 *时间:2015年8月26日11:32:52
 *文件:BinaryTreeNode.java
 *作者:cutter_point
 */
package bishi.Offer50.y2015.m08.d26;

public class BinaryTreeNode
{
	public int m_nValue;
	public BinaryTreeNode m_pLeft;
	public BinaryTreeNode m_pRight;
	
	public BinaryTreeNode()
	{
	}
	
	public BinaryTreeNode(int data)
	{
		m_nValue = data;
		m_pLeft = m_pRight = null;
	}
}


/**
 *题目:实现重建二叉树,输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。加上输入的前序遍历和中序遍历的结果中都不含重复的数字。
 *		例如输入前序遍历的序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出图2.6所示的二叉树并输出它的头结点。
 *		二叉树节点的定义如下:
 *时间:2015年8月26日11:40:36
 *文件:BinaryTree.java
 *作者:cutter_point
 */
package bishi.Offer50.y2015.m08.d26;

public class BinaryTree
{
	public BinaryTreeNode root;
	
	public static void main(String[] args)
	{
		int preorder[] = {1,2,4,7,3,5,6,8};
		int inorder[] = {4,7,2,1,5,3,8,6};
		BinaryTree bt = new BinaryTree();
		bt.construct(preorder, inorder);
		BinaryTreeNode test = bt.root;
	}
	
	/**
	 * 给出前序和总序,得到我们的二叉树
	 * @param Preorder
	 * @param Inorder
	 */
	public void construct(int Preorder[], int Inorder[])
	{
		if(Preorder == null || Inorder == null || Preorder.length != Inorder.length)
			return;
		
		try
		{
			root = constructCore(Preorder, 0, Preorder.length - 1, Inorder, 0, Inorder.length - 1);
		} 
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	/**
	 * 这个是根据前序和中序来遍历二叉树
	 * @param Preorder
	 * @param startPreorderIndex
	 * @param endPreorderIndex
	 * @param Inorder
	 * @param startInorderIndex
	 * @param endInorderIndex
	 * @return
	 * @throws Exception
	 */
	private BinaryTreeNode constructCore
	(
			int Preorder[], int startPreorderIndex, int endPreorderIndex, 
			int Inorder[], int startInorderIndex, int endInorderIndex
	) throws Exception
	{
		int rootValue = Preorder[startPreorderIndex];
		BinaryTreeNode btn = new BinaryTreeNode(rootValue);
		btn.m_pLeft = btn.m_pRight = null;
		
		//然后是递归终止条件
		if(startPreorderIndex == endPreorderIndex)
		{
			if(startInorderIndex == endInorderIndex && Preorder[startPreorderIndex] == Inorder[startInorderIndex])
			{
				return btn;
			}
			else
			{
				throw new Exception("前序和中序序列不匹配");
			}//else
		}//if
		
		int rootInorderIndex = startInorderIndex;
		while(Inorder[rootInorderIndex] != rootValue && rootInorderIndex <= endInorderIndex)
		{
			++rootInorderIndex;
		}//while
		
		//最后判断是找到了,还是没找到,到了末尾
		if(Inorder[rootInorderIndex] != rootValue && rootInorderIndex == endInorderIndex)
		{
			throw new Exception("前序和中序序列不匹配");
		}//if
		
		int leftLength = rootInorderIndex - startInorderIndex;
		if(leftLength > 0)
		{
			btn.m_pLeft = constructCore(Preorder, startPreorderIndex + 1, startPreorderIndex + leftLength, 
										Inorder, startInorderIndex, startInorderIndex + leftLength - 1);
		}//if
		
		if(leftLength < (endPreorderIndex - startPreorderIndex))
		{
			btn.m_pRight = constructCore(Preorder, startPreorderIndex + leftLength + 1, endPreorderIndex, 
										Inorder, startInorderIndex + leftLength + 1, endInorderIndex);
		}//if
		
		return btn;
	}
}



题目实现

/****************************************************************************************
 *题目:二叉树的深度
 *		1、输入一颗二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根,叶节点)形成树的一条路径,最长路径的长度为树的深度。
 *		class BinaryTreeNode
 *		{
 *			int m_nValue;
 *			BinaryTreeNode m_pLeft;
 *			BinaryTreeNode m_pRight;
 *		}
 *		2、输入一颗二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树。
 *		例如,图6.1中的二叉树就是一颗平衡二叉树
 *									1
 *						/						\
 *					   2						 3
 *				/				\						\
 *			   4				 5    					 6
 *							/
 *						   7
 *时间:2015年10月3日16:46:51
 *文件:TreeDepth.java
 *作者:cutter_point
 ****************************************************************************************/
package bishi.Offer50.y2015.m10.d03;

import org.junit.Test;

import bishi.Offer50.y2015.m08.d26.*;

public class TreeDepth
{
	/**
	 * 这个题的本质就是深度优先遍历树
	 * @param tree
	 * @return
	 */
	public int treeDep(BinaryTreeNode pRoot)
	{
		if(pRoot == null)
		{
			return 0;
		}//if
		
		
		int left = treeDep(pRoot.m_pLeft);
		int right = treeDep(pRoot.m_pRight);
		//我们输出一下我们的节点值
		System.out.println("当前访问的节点:" + pRoot.m_nValue);
		
		return (left > right) ? left + 1 : right + 1;
	}
	
	/**
	 * 判断是否是平衡二叉树,也是深度遍历的意识
	 * @param pRoot
	 * @return
	 */
	public boolean isBalanced(BinaryTreeNode pRoot)
	{
		if(pRoot == null)
			return true;
		
		//当两边的子树深度相差超过1的时候为false
		int left = treeDep(pRoot.m_pLeft);
		int right = treeDep(pRoot.m_pRight);
		int diff = left - right;
		if(diff > 1 || diff < -1)
			return false;
		//递归到所有的节点
		return isBalanced(pRoot.m_pLeft) && isBalanced(pRoot.m_pRight);
	}
	
	/**
	 * 这个每个节点遍历一次,然后获取相应的深度,进行比较
	 * @param pRoot
	 * @param dept
	 * @return
	 */
	public boolean isBalanced(BinaryTreeNode pRoot, int dept[])
	{
		if(pRoot == null)
		{
			dept[0] = 0;
			return true;
		}//if
		
		System.out.println("判断平衡数当前访问:" + pRoot.m_nValue);
		int left[] = new int[1]; int right[] = new int[1];
		//判断这个节点的左右子树的深度是否相差大于1
		if(isBalanced(pRoot.m_pLeft, left) && isBalanced(pRoot.m_pRight, right))
		{
			//求的其子树的深度差
			int dif = left[0] - right[0];
			if(dif <= 1 && dif >= -1)
			{
				//在可以继续的范围内
				dept[0] = 1 + (left[0] > right[0] ? left[0] : right[0]);
				return true;
			}//if
		}//if
		
		return false;
	}
	
	@Test
	public void test()
	{
		int preorder[] = {1,2,4,5,7,3,6};
		int inorder[] = {4,2,7,5,1,3,6};
		BinaryTree bt = new BinaryTree();
		bt.construct(preorder, inorder);
		TreeDepth td = new TreeDepth();
		int dept[] = new int[1];
		System.out.println("树深度" + td.treeDep(bt.root));
		System.out.println("是否是平衡二叉树:" + td.isBalanced(bt.root));
		System.out.println("是否是平衡二叉树2:" + td.isBalanced(bt.root, dept) + "\t深度:" + dept[0]);
	}
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值