二叉树结构
/**
*题目:实现二叉树,输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。加上输入的前序遍历和中序遍历的结果中都不含重复的数字。
* 例如输入前序遍历的序列{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]);
}
}