假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。 例如,前序遍历序列:{1,2,4,5,6},中序遍历序列:{3,2,4,1,6,5}
在二叉树的前序遍历序列中,第一个数字总是根节点的值。在中序遍历序列中,根节点的值在中间,左子树的值在根节点值的左边,右子树的值在根节点的值的右边。
#include<iostream>
using namespace std;
template<class T>
struct BinaryTreeNode
{
T _value; //数据
BinaryTreeNode<T>* _left; //左孩子
BinaryTreeNode<T>* _right; //右孩子
BinaryTreeNode()
: _value()
, _left(NULL)
, _right(NULL)
{}
};
template<class T>
class BinaryTree
{
public:
BinaryTreeNode<T>* ConstructCore(int* startPre,int* endPre,int* startIn,int* endIn)
{
int rootValue = startPre[0]; //前序遍历的第一个数字就是根节点的值
BinaryTreeNode<T>* root = new BinaryTreeNode<T>();
root->_value = rootValue;
root->_left = root->_right = NULL;
cout << root->_value<< " ";
if (startPre == endPre)
{
if (startIn == endIn && *startPre == *startIn)
{
return root;
}
else
{
return NULL;
}
}
int* rootIn = startIn;
//在中序遍历中找根节点的值
while (*rootIn != rootValue && rootIn <= endIn)
{
++rootIn;
}
if (rootIn == endIn && *rootIn != rootValue)
return NULL;
int leftLength = rootIn - startIn;//左子树长度 中序遍历序列中根节点前面的数字都是左子树节点的值
int* leftEnd = startPre + leftLength;//前序遍历序列中左子树的值
//构建左子树
if (leftLength > 0)
{
root->_left=ConstructCore(startPre+1,leftEnd,startIn,rootIn-1);
}
//构建右子树
if (leftLength < endPre - startPre)
{
root->_right = ConstructCore(leftEnd+1,endPre,rootIn+1,endIn);
}
return root;
}
BinaryTreeNode<T>* 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);
}
};
int main()
{
int preorder[] = { 1,2,4,7,3,5,6,8 };
int inorder[] = { 4,7,2,1,5,3,8,6 };
BinaryTree<int> bt;
BinaryTreeNode<int>* root=bt.Construct(preorder, inorder, 8);
return 0;
}