现在已经知道二叉树的先序和中序序列,分别存储在数组BiTree A[]和B[]中。A代表先序
本方法要用到递归,采取一种自顶向下开辟结点空间,而自底向上使连接结点的思路
①首先开辟root空间,并将当前先序序列A中第一号元素赋到root中(之所以说当前A中第一号是因为随着程序运行序列A范围减小,每次读入新序列的第一个元素才能保证根结点正确???)
②在B中找到和root值一样的那个结点(记下它的序号i),以此节点为界把B分为左子树和右子树
③用i和己经给的序列首位和序列末位计算出左子树和右子树的长度,长度要用来判断是否继续递归执行函数
④如果左树长度还不为0,就把左树的范围作为参数输入执行这个函数本身(递归),并把返回值连到本层的root->lchild
⑤如果左树长度还不为0,就把左树的范围作为参数输入执行这个函数本身(递归),并把返回值连到本层的root->rchild
⑥4,5两步之所以说把返回值连到l/rchild,因为本函数设计中返回值就是当前层创建的那个新root,上一层得到的子树范围作为参数输入到本层,新创建了一个根,操作完之后把当前层的根返回给上一层根的l/rchild,因此成为自顶向下创建root,但自下向上连接(递归到最底层完之后才开始返回root开始连接)
Bitree PreInCreat(ElemType A[],ElemType B[],int l1,int h1,int l2,int h2){
//l表示一个序列中第一个结点在数组中的号码,h表示最后一个结点,l和h围出一个序列。
//1表示存储先序的数组A,2表示存储中序的数组B,初始时设定l1=l2=1,h1=h2=n
int i;
root=(BiTNode*)malloc(sizeof(BiTNode));//不可以直接(BiTree)吗?这杨不是直接得到指针了吗
root->data=A[l1];
for(i=l2;B[i]!=root->data;i++);//该for的目的在于在B[]中找到与A[l1]相等的结点的位置,因此应该从B中第一号开始寻找,即从l2开始循环
llen=i-l2;//退出for循环说明在B中找到了和A[l1](即本层中输入的根结点)相等的结点,该结点的序号是i
rlen=h2-i;//i即下一层函数递归的根结点,以i为中心,把B序列分为左树和右树两个部分,llen表示左树的长度,r同理
if(llen)
root->lchild=PreInCreat(A,B,l1+1,l1+llen,l2,l2+llen-1);//(l1+1)和(l1+llen)是左树在A中的范围,(l2)和(l2+llen-1)是在B中的范围
else//PreInCreat()函数的最终返回是一个root,该if的目的在于进到最底层的结点,然后一层一层返还(连接)上来
root->lchild=NULL;
if(rlen)
root->rchild=PreInCreat(A,B,h1-rlen+1,h1,h2-rlen+1,h2);//参数同上
else
root->rchild=NULL;
return root;
}//该方法每层分割一次数组AB,自上而下每层创建一个新root,自下而上的把本层的root连接到上一层root的rchild或者lchild上