前序遍历和中序遍历的重建二叉树:
首先构建二叉树的节点:
struct TreeNode
{
int _value;
TreeNode* _left;
TreeNode* _right;
};
分析:
在二叉树的前序遍历中,第一个数字总是树的根节点的值,但在中序遍历的序列中,根节点的值在序列的中间,左子输的节点位于根节点的左侧,右子树的节点位于根节点的右侧。所以我们需要扫描一遍中序遍历才能知道它的根节点的值。
我们来分析如图所示的二叉树:
前序遍历的第一个节点1就是它的根节点。扫描中序遍历的序列,就能确定根节点的值。根据中序遍历的特点,在根结点的值1前面的3个数字都是左子树根节点的值,1右边的数字都是右子数节点的值。
由于在中序遍历序列中,有三个数是左子树节点的值,因此左子树有三个左子树的节点。同样在前序遍历的序列中,根据节点后面的三个数字就是三个左子树节点的值,再后面的所有数字都是右子树节点的值。这样我们就可以根据前序遍历和中序遍历分别找到左右子树对应的子序列。如图所示:
实现代码:
struct TreeNode
{
int _value;
TreeNode* _left;
TreeNode* _right;
};
TreeNode* Construct(int* prevorder, int* inorder, int* length)
{
if (prevorder == NULL || inorder == NULL || length < 0)
return NULL;
return ConstructCore(prevorder, prevorder + length - 1, inorder, inorder + lenghth - 1);
}
TreeNode* ConstructCore
{
int* startprevorder,int* endprevorder,
int* startinorder,int* endinorder
}
int rootvalue = startprevorder[0];
TreeNode* root = new TreeNode();
root->_value = rootvalue;
root->_left = root->_right = NULL;
if (startpreorder == endprevorder)
{
if (startinorder == endinorder&&*startprevorder == *startinorder)
return root;
else
throw std::exception("Invalid input");
}
int* rootinorder = startinorder;
while (rootinorder <= endinorder&&*rootinorder != rootvalue)
{
++rootinorder;
}
if (rootinorder == endinorder&&*rootinorder != rootvalue)
{
throw std::exception("Invalid input");
}
int leftlength = rootinorder - startinorder;
int*leftpreorderend = startprevorder + leftlength;
if (leftlength > 0)
{
root->_left = ConstructCore(startprevorder + 1, leftpreorderend, startinorder, rootinorder - 1);
}
if (leftlength < endpreorder - startpreorder)
{
root->_right = ConstructCore(leftpreorderend + 1, endpreorder, rootinorder + 1, endinorder);
}
return root;
}