void create_tree(node* &root,int l1,int l2,int len){
if(len==0) return;
root=new node;
root->data=pre[l2];
if(len==1) return;
int i;
for(i=l1;i<l1+len;i++){
if(in[i]==pre[l2]) break;
}
create_tree(root->left,l1,l2+1,i-l1);
create_tree(root->right,i+1,l2+i-l1+1,len-i+l1-1);
}
7 2 3 4 6 5 1 8 LNR
5 3 7 2 6 4 8 1 NLR
create_tree(root->left,l1,l2+1,i-l1);
左子树在inorder的LNR,就是N之前的都是L,也就是从l1开始
左子树在preorder的NLR,是N之后的一个开始,也就是l2+1
左子树区间是:i-l1
可以带入验证:1⃣️l1=0
2⃣️l2=1
3⃣️I-l1=5 1~100的个数为100,一半会有100-1+1,此处不加1是因为不要根。即i所指结点不算在内
create_tree(root->right,i+1,l2+i-l1+1,len-i+l1-1);
右子树在inorder的LNR,即N之后都是R,就是N后边一个结点开始i+1
右子树在preorder的NLR,即L之后一个,在当前l2的基础上加上一个根结点,加上左子树区间的长度
对比由前序和后序构造二叉树:
void create_tree(node* &root,int l1,int l2,int len){
if(len==0) //两个递归出口
return;
root= new node;
root->data=pre[l1];
if(len==1)return; //只有一个根结点,不用再对左右子树进行处理
int i;
for(i=l2;i<l2+len;i++){ //找左右子树区间
if(post[i]==pre[l1+1])
break;
}
int leftlen,rightlen;
leftlen=i-l2+1;
rightlen=len-leftlen-1; //减一是pre[l1]为根
if(rightlen==0) //之间没有元素,说明只有一棵子树
uni=false;
create_tree(root->left,l1+1,l2,leftlen); //如果只有一个结点默认判为左子树
create_tree(root->right,l1+1+leftlen,i+1,rightlen);
}