题目:输入某二叉树的前序遍历和中序遍历结果,请重建二叉树。假设输入的前序遍历和中序遍历都没有重复数字,例如{1,2,4,7,3,5,6,8}和{4,7,2,1,5,3,8,6},返回根节点,二叉树定义如下:
struct BtNode
{
int m_val;
BtNode* m_pleft;
BtNode* m_pright;
};
首先根据前序遍历的第一个节点找到根结点,然后从中序遍历的结点中找到该值,就能确定出在中序遍历中根结点之前的点都是左子树上的点,根结点之后的点都是右子树的点,然后再用递归的思维,就能得出树的结构了。
BtNode* Construct(int* preorder,int* inorder,int length)
{
if(preorder == NULL || inorder == NULL || length <= 0)
return NULL;
return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
}
BtNode* ConstructCore(int *startPreorder,int* endPreorder,int* startInorder,int* endInorder)
{
int rootval = startPreorder[0];
BtNode* root = new BtNode;
root->m_val = rootval;
root->m_pleft = root->m_pright = NULL;
if(startPreorder == endPreorder)
{
if(startInorder == endInorder && *startInorder == *startPreorder)
{
return root;
}
else
{
throw exception("Invalid input.");
}
}
//中序遍历找根结点
int *rootInorder = startInorder;
while(rootInorder <= endInorder && *rootInorder != rootval)
{
++rootval;
}
if(rootInorder == endInorder && *rootInorder != rootval)
{
throw exception("Invalid input.");
}
int leftlength = rootInorder - startInorder;
int* leftend = startPreorder + leftlength;
if(leftlength > 0)
{
//构建左子树
root->m_pleft = ConstructCore(startPreorder+1,leftend,startInorder,rootInorder-1);
}
if(leftlength < endPreorder - startPreorder)
{
//构建右子树
root->m_pright = ConstructCore(leftend+1,endPreorder,rootInorder+1,endInorder);
}
return root;
}
//输入两棵树,判断B是不是A的子结构
bool DoesTree1HaveTree2(BtNode* pRoot1,BtNode* pRoot2)
{
if(pRoot2 == NULL)
return true;
if(pRoot1 == NULL)
return false;
if(pRoot1->m_val!=pRoot2->m_val)
return false;
return DoesTree1HaveTree2(pRoot1->m_pleft,pRoot2->m_pleft) &&
DoesTree1HaveTree2(pRoot1->m_pright,pRoot2->m_pright);
}
bool IsSubTree(BtNode* pRoot1,BtNode* pRoot2)
{
bool result = false;
if(pRoot1!=NULL&&pRoot2!=NULL)
{
if(pRoot1->m_val == pRoot2->m_val)
result = DoesTree1HaveTree2(pRoot1,pRoot2);
if(!result)
result = IsSubTree(pRoot1->m_pleft,pRoot2);
if(!result)
result = IsSubTree(pRoot1->m_pright,pRoot2);
}
return result;
}
//二叉树的镜像
void MirrorResursively(BtNode* pNode)
{
if((pNode == NULL)||(pNode->m_pleft == NULL&&pNode->m_pright == NULL))
return;
BtNode* pTemp = pNode->m_pleft;
pNode->m_pleft = pNode->m_pright;
pNode->m_pright = pTemp;
if(pNode->m_pleft)
MirrorResursively(pNode->m_pleft);
if(pNode->m_pright)
MirrorResursively(pNode->m_pright);
}