思路:
关键在每次读取两个数组的范围问题:
in(中序遍历数组)的边界比较好确定:
有左子树时为[start2,i-1];
有右子树时为[i+1,end2]。
pre(先序遍历数组)的边界要根据in确定:
1)有左子树时根据aft和i求出左子树节点个数为:i-start2。所以pre的边界就要包括接下来的i-start2个节点,即:从start1+1到start1+(i-start2)此时综合in的边界为[start1+1,start1+i-start2,start2,i-1];
2)有右子树时也要根据aft和i求出左子树节点个数:i-start2。pre的边界就要跳过接下来的i-start2个已建立过的节点, 即:从start1+1+(i-start2)到end1,此时综合in的边界为[start1+i-start2+1,end1,i+1,end2];
同时还要注意两个数组不匹配的情况。
总之:在跳到右子树时一定要跨过前面已经建立过的左子树的节点,即使没有左子树(此时i-start2等于0)。
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
BinaryTreeNode* ReBuild(int* pre,int*in,int start1,int end1,int start2,int end2)
{
if((end1-start1)==0)
assert(pre[start1]==in[start2]);
if(end2<start2)
return NULL;
BinaryTreeNode* Temp_Node=new BinaryTreeNode();
Temp_Node->m_nValue=pre[start1];
Temp_Node->m_pLeft=NULL;
Temp_Node->m_pRight=NULL;
for(int i=start2;i<=end2&&in[i]!=pre[start1];i++)
;
assert(i<=end2);
if (i>start2)
Temp_Node->m_pLeft=ReBuild(pre,in,start1+1,start1+i-start2,start2,i-1);
if (i<end2)
Temp_Node->m_pRight=ReBuild(pre,in,start1+i-start2+1,end1,i+1,end2);
return Temp_Node;
}