关于二叉树的概念:
百度百科给的定义是:
二叉树是一个连通的无环图,并且每一个顶点的度不大于3。有根二叉树还要满足根结点的度不大于2。有了根结点之后,每个顶点定义了唯一的父结点,和最多2个子结点。然而,没有足够的信息来区分左结点和右结点。如果不考虑连通性,允许图中有多个连通分量,这样的结构叫做森林。
二叉树是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
图一
(1)空二叉树——如图(a);
(2)只有一个根结点的二叉树——如图(b);
(3)只有左子树——如图(c);
(4)只有右子树——如图(d);
(5)完全二叉树——如图(e)。
注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形
我们来提炼一下定义中存在的信息:二叉树是符合每个节点的子树个数不能超过2的,且仅有一个根节点特征的树的集合
关于二叉树的先序遍历,中序遍历和后序遍历:(此处只做大概的解释,想要详细了解的朋友可以点这里)
先序遍历:先访问根节点,在访问左节点,最后访问右节点(根左右)
中序遍历:先访问左节点,在访问根节点,最后访问右节点(左根右)
后序遍历:先访问左节点,在访问右节点,最后访问根节点(左右根)
做了这么多的准备工作,接下来我们来看看如何通过一个二叉树的先序遍历和中序遍历确定一颗树:
我们先分析一下:根据先序遍历的特性,我们能知道,第一个节点一定是整棵树的根节点,知道了根节点后,我们可以在中序遍历总找到根节点的位置,通过中序遍历的特性,我们可以知道在根节点左边的节点都是左子树即根节点的孙子节点,在根节点右边的都是根节点的右子树即根节点的孙子节点。通过下面的实例能理解更深:
先:ABDECFGHI
中:DBEAGFHIC
第一步:通过先序找到根节点为A,并且找到A在中序中的位置
第二步:通过A我们将序列划分为
左子树及其子节点:DBE
右子树及其节点:GFHIC
这样的话,我们就可以对于得到的新序列进行再一次划分,这个熟悉递归的朋友就能知道,接下来就是递归的典型使用场景了。我就不多加叙述,一切尽在代码中。
算法流程如下:
1.将先序序列及中序序列划分为左区和右区域
2.重复步骤1,直到以下情况才能终止递归
a.当序列长度仅为1时,只剩下一个节点
b.当序列长度为0时,返回节点null
本人使用java实现的代码如下:(仅贴出部分重要代码)
需要阅读完整代码的朋友可以移步到通过先序中序创建二叉树
class TreeNode{
public String nodeName;
public TreeNode lchild;
public TreeNode rchild;
public TreeNode(String nodeName,TreeNode lchild,TreeNode rchild) {
this.nodeName=nodeName;
this.lchild=lchild;
this.rchild=rchild;
}
}
这是一个表示节点的类,用于存储节点
public TreeNode creatTree(String bef,String mid) {
String root=bef.substring(0, 1);
int rootindex=mid.indexOf(root);
System.out.println(rootindex);
String leftBef=bef.substring(1, rootindex+1);
String leftMid=mid.substring(0, rootindex);
System.out.println("left child:"+leftBef+" "+leftMid);
TreeNode lchild=initTree(leftBef,leftMid);
int len=mid.length();
String rightBef=bef.substring(rootindex+1,len);
String rightMid=mid.substring(rootindex+1,len);
System.out.println("right child:"+rightBef+" "+rightMid);
TreeNode rchild=initTree(rightBef,rightMid);
rootNode=new TreeNode(root, lchild, rchild);
return rootNode;
}
/**
* 递归
* @param bef
* @param mid
* @return
*/
public TreeNode initTree(String bef,String mid) {
if(bef.length()==1&&mid.length()==1) {
return new TreeNode(bef, null, null);
}
String root=bef.substring(0, 1);
int rootindex=mid.indexOf(root);
String leftBef=bef.substring(1, rootindex+1);
String leftMid=mid.substring(0, rootindex);
TreeNode lchild=null;
if(leftBef.length()==leftMid.length()&&leftBef.length()!=0) { //不为空时
lchild=initTree(leftBef,leftMid);
}
int len=mid.length();
String rightBef=bef.substring(rootindex+1,len);
String rightMid=mid.substring(rootindex+1,len);
TreeNode rchild=null;
if(rightMid.length()==rightBef.length()&&rightBef.length()!=0) {
rchild=initTree(rightBef,rightMid);
}
TreeNode rootNode=new TreeNode(root, lchild, rchild);
return rootNode;
}