版权声明:本文为博主原创文章,未经许可,不得转载! https://blog.csdn.net/bin_ge_love/article/details/51921666
依据前序遍历序列和中序序列重构二叉树
前序遍历:1,2,3,4,5,6,7
首先分析前序遍历和中序遍历序列的特点:
前序遍历:遍历的第一个为根节点
中序遍历:以根节点为分隔,根节点之前的全部为左子树,根节点之后的全部为右子树
依据这两个性质,要重建二叉树的话,我们就是先找到根节点,然后再分别找出它的左右子树,然后再分别以左右孩子为根节点,确定它的左右孩子
前序遍历:1,2,3,4,5,6,7
中序遍历:3,2,4,1,6,5,7
前序遍历:遍历的第一个为根节点
中序遍历:以根节点为分隔,根节点之前的全部为左子树,根节点之后的全部为右子树
依据这两个性质,要重建二叉树的话,我们就是先找到根节点,然后再分别找出它的左右子树,然后再分别以左右孩子为根节点,确定它的左右孩子
我们可以运用递归的思想来解决此题
下边是代码:
#include<iostream>
#include<stack>
using namespace std;
struct BinaryTreeNode
{
BinaryTreeNode* _left;
BinaryTreeNode* _right;
int _value;
};
BinaryTreeNode* _RebuildTree(int* startPrev,int* endPrev,int* startIn,int* endIn)
{
int rootValue = startPrev[0]; //前序遍历的第一个数字就是根节点的值
BinaryTreeNode* root = new BinaryTreeNode;
root->_value = rootValue;
root->_left = NULL;
root->_right = NULL;
if (startPrev == endPrev) //只有一个节点情况
{
if (startIn == endIn && *startPrev == *startIn)
{
return root;
}
else
{
throw exception("Invalid input!");
}
}
//在中序遍历中找根节点的值
int* rootIn = startIn;
while (rootIn <= endIn && *rootIn != rootValue)
{
++rootIn;
}
if (rootIn == endIn && *rootIn != rootValue)//在中序遍历中没有找到的情况
{
throw exception("Invalid input!");
}
int leftLength = rootIn - startIn;
int* leftPrevEnd = startPrev + leftLength;
if (leftLength > 0) //递归构建左子树
{
root->_left = _RebuildTree(startPrev + 1, leftPrevEnd, startIn, rootIn - 1);
}
if (leftLength < endPrev - startPrev)//递归构建右子树
{
root->_right = _RebuildTree(leftPrevEnd + 1, endPrev, rootIn + 1, endIn);
}
return root;
}
BinaryTreeNode* RebuildTree(int* prev, int* in, int len)
{
if (prev == NULL || in == NULL || len <= 0)
{
return NULL;
}
return _RebuildTree(prev, prev + len - 1, in, in + len + -1);
}
void PreOrder(BinaryTreeNode* root)
{
if (root == NULL)
return;
cout << root->_value << " ";
PreOrder(root->_left);
PreOrder(root->_right);
}
void PostOrder(BinaryTreeNode* root)
{
if (root == NULL)
return;
PostOrder(root->_left);
PostOrder(root->_right);
cout << root->_value << " ";
}
void RebuildTreeTest()
{
int prev[] = { 1, 2, 3, 4, 5, 6, 7 };
int in[] = { 3, 2, 4, 1, 6, 5, 7};
BinaryTreeNode* ret = RebuildTree(prev, in, 7);
cout << "前序遍历: ";
PreOrder(ret);
cout << endl;
cout << "后序遍历: ";
PostOrder(ret);
cout << endl;
}
int main()
{
RebuildTreeTest();
return 0;
}
这个代码关键之处是在于递归时函数传参问题,下边给出图片帮助理解。
下边是运行结果截图,为了检验其正确性,可以用后序遍历和监视窗口来检验。