您的位置:首页 > 其它

根据前序和后序构建二叉树

2013-08-03 20:09 148 查看
编程之美上有道题是根据前序和中序来构建二叉树,当元素不同时,此树是唯一的。

当要根据前序和后序来构建二叉树时,此时即使元素都不同,也不是唯一的,举个例子

//    1     1

//   /         \

//  2         2

// /             \

//3             3

// preorder  1 2 3
// postorder 3 2 1

从上面的例子我们可以看到,此时可以构建出一个映像的二叉树来,即当只有左子树或者右子树的时候,是无法确定二叉树的。

下面是代码// 3.1重构二叉树,根据前序、后序数列
// 1 1
// / \
// 2 2
// / \
//3 3
// preorder 1 2 3
// postorder 3 2 1
BinaryTreeNode* rebuildCorePP( int *preStart, int *preEnd, int *postStart, int *postEnd )
{
BinaryTreeNode *pRoot = new BinaryTreeNode(*preStart);
if ( preStart == preEnd )
{
if ( postEnd == postStart && *postStart == *preStart )
return pRoot;
else
throw exception("Invalid input.");
}
int leftRootValue = preStart[1];
int *postLeftEnd = postStart;
while ( postLeftEnd < postEnd && leftRootValue != *postLeftEnd )
++postLeftEnd;
if ( postLeftEnd >= postEnd )
throw exception("Invalid input.");

//int leftLen = postLeftStart - postStart;
// 如果 postLeftEnd + 1 = postEnd , 此时树不唯一,有两种情况,或者是只有左子树,或者是只有右子树
if ( postLeftEnd + 1 == postEnd )
throw exception("tree is not only.");
int leftLen = postLeftEnd - postStart + 1;

pRoot->m_pLeft = rebuildCorePP(preStart+1, preStart+leftLen, postStart, postLeftEnd );
pRoot->m_pRight = rebuildCorePP(preStart+leftLen+1, preEnd, postLeftEnd+1, postEnd-1 );

return pRoot;
}

BinaryTreeNode* rebuildBinaryTreeByPP(int *preOrder, int *postOrder, int length )
{
if ( preOrder == NULL || postOrder == NULL || length <= 0 )
return NULL;
return rebuildCorePP( preOrder, preOrder+length-1, postOrder, postOrder+length-1);
}
// ====================测试代码====================
void Test2(char* testName, int* preorder, int* postorder, int length)
{
if(testName != NULL)
printf("%s begins:\n", testName);

printf("The preorder sequence is: ");
for(int i = 0; i < length; ++ i)
printf("%d ", preorder[i]);
printf("\n");

printf("The postorder sequence is: ");
for(int i = 0; i < length; ++ i)
printf("%d ", postorder[i]);
printf("\n");

try
{
BinaryTreeNode* root = rebuildBinaryTreeByPP(preorder, postorder, length);
PrintTree(root);
}
catch(std::exception& exception)
{
printf("Invalid Input.\n");
}

}
void TestRebuildTreeByPP()
{
/*
测试用例
功能性测试:完全二叉树、满二叉树
边界测试:没有左子树,没有右子树
特殊输入测试:NULL,不符合序列

*/
{
// 普通二叉树
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
const int length = 7;
int preorder[length] = {1, 2, 4, 5, 3, 6, 7};
int postorder[length] = {4, 5, 2, 6, 7, 3, 1};
//int inorder[length] = {4, 2, 5, 1, 6, 3, 7};

Test2("Test1", preorder, postorder, length);
}
{
// 所有结点都没有右子结点
// 1
// /
// 2
// /
// 3
// /
// 4
// /
// 5
const int length = 5;
int preorder[length] = {1, 2, 3, 4, 5};
int postorder[length] = {5, 4, 3, 2, 1};
//int inorder[length] = {5, 4, 3, 2, 1};

Test2("Test2", preorder, postorder, length);
}
{
// 所有结点都没有左子结点
// 1
// \
// 2
// \
// 3
// \
// 4
// \
// 5
const int length = 5;
int preorder[length] = {1, 2, 3, 4, 5};
int postorder[length] = {5, 4, 3, 2, 1};
//int inorder[length] = {5, 4, 3, 2, 1};

Test2("Test3", preorder, postorder, length);
}
{

// 树中只有一个结点
const int length = 1;
int preorder[length] = {1};
int postorder[length] = {1};
//int inorder[length] = {5, 4, 3, 2, 1};

Test2("Test4", preorder, postorder, length);
}
}    有此可知,基本上由前序后后序只能确定完全二叉树,或者满二叉树。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐