int initTree(Tree *root,char *front,char *middle,int num)
{
in i=0;
root->data = front[0];
if(num==0) return 0;//全部结束
//找到根节点在middle中的位置
for(i=0;i<num;i++)
{
if(middle[i]==root->data) break;
}
//如果root存在左子树
if(i!=0)
{
root->lchild=new struct TreeNode();
initTree(root->lchild,front+1,middle,i);
}
if(i!=num-1)
{
root->rchild = new struct TreeNode();
initTree(root->rchild,front+i+1,middle+i+1,i);
}
return 1;
}
下面分析下以上代码,用前面的例子,先序遍历:ABDCF,中序遍历DBAFC:
1、第一层,
先序遍历:A B D C F,
↑
i=0,root->data=front[0]='A',
找A在middle中位置,for(---) i=2,
因为i!=0,所以,产生新节点,
递归左子树,front+1,
2、第二层,第一层:A左分支,num=2
先序: B D C F ,
↑
root->data = front[0]='B'
找B在middle中位置,for(---) i=1,
因为i!=0,所以,产生新节点,
递归左子树,front+1,
3、第二层:B 的左分支:,num=1
先序: D C F ,
↑
root->data = front[0]='D'
找D在middle中位置,for(---) i=0,
不满足i!=0,也不满足i!=num-1(此时,i=0,num=1)
所以return 1,至 2、第二层
4、返回到了上一层:第二层:B,
此时i=1,num=3
所以不满足if(i!=num-1)
所以return 1,至 1、第一层:A
5、第一层:A,i=2,num=5
因为满足if(i!=num-1)
产生新节点,
递归右子树,front+i+1,middle+i+1(即front+3,middle+3,即C,F)
6、第一层A的右分支,第二层,num=2
先序: C F , 后序:F C
↑ ↑
root->data=front[0]='C'
找C在middle中位置,for(---) i=1,
满足if(i!=0)
产生新节点,
递归左子树,front+1,middle
8、第二层的左分支,第三层,num=1
先序: F , 后序:F C
↑ ↑
root->data=front[0]='F'
找F在middle中位置,for(---) i=0,
不满足if(i!=0),不满足if(i!=num-1)
返回至上一层C,第6步
9、C右子树,
此时i=1,num=2,
不满足if(i!=num-1)
所以return 1,至 1、第一层。
return 1
程序结束.
通过以上分析,可以看出i与0,num-1的关系所代表的的意义
i:找字符在middle中位置,
而i代表包含当前节点左子树的个数,
若i==0,则说明该节点无左子树。
num代表所以节点个数,
如果i==num-1,则说明该节点在中序遍历时已经是最后一个节点,所以无右子树。
该方法的缺点:没有对越界的判断,