树的遍历方式被分为前序、中序、后序,其中采用前序+中序或者后序+中序的组合可以构建每一的一棵树。本文采用C++,根据用户提供的前序和中序构建树结构。
首先,定义树的结点:
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
树的重构代码如下:
BinaryTreeNode* rebuild_tree_form_aheadAndMiddle(int* ahead,int* middle,int length)
{
if(ahead==nullptr||middle==nullptr||length<=0)
{
return nullptr;
}
//如何从前序和中序中抽取根节点,并据此拆分左右子树
int root_value=ahead[0];
BinaryTreeNode *tree_node=new BinaryTreeNode();
tree_node->m_nValue=root_value;
tree_node->m_pLeft=tree_node->m_pRight=nullptr;
if(length==1)
{
return tree_node;
}
int root_index;
for(root_index=0;root_index<length;root_index++)
{
if(middle[root_index]==root_value)
{
break;
}
}
// cout<<"length="<<length<<",the node is:"<<tree_node->m_nValue<<",root_index="<<root_index<<endl;
tree_node->m_pLeft=rebuild_tree_form_aheadAndMiddle(&(ahead[1]),middle,root_index);
tree_node->m_pRight=rebuild_tree_form_aheadAndMiddle(&(ahead[root_index+1]),&(middle[root_index+1]),length-root_index-1);
return tree_node;
}
代码中,首先对输入信息的正确性进行判断,目的是使代码更加健壮。
前序遍历的数列中,根节点总是第一个出现,因此根节点的值为前序遍历中下标为0的数值。在中序遍历中查找根节点数值所在的下标root_index。root_index将中序遍历分为了两个部分,在其左边的数组均出现在根节点的左子树中,右边的数组均出现在其右子树中。
递归的将左右子树重构,即可获取最终的树结构。
为了验证程序能正常使用,可以使用以下测试代码进行测试:
void PrintTree(const BinaryTreeNode* pRoot)
{
PrintTreeNode(pRoot);
if(pRoot != nullptr)
{
if(pRoot->m_pLeft != nullptr)
PrintTree(pRoot->m_pLeft);
if(pRoot->m_pRight != nullptr)
PrintTree(pRoot->m_pRight);
}
}
void PrintTreeNode(const BinaryTreeNode* pNode)
{
if(pNode != nullptr)
{
printf("value of this node is: %d\n", pNode->m_nValue);
if(pNode->m_pLeft != nullptr)
printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue);
else
printf("left child is nullptr.\n");
if(pNode->m_pRight != nullptr)
printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue);
else
printf("right child is nullptr.\n");
}
else
{
printf("this node is nullptr.\n");
}
printf("\n");
}
void DestroyTree(BinaryTreeNode* pRoot)
{
if(pRoot != nullptr)
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;
delete pRoot;
pRoot = nullptr;
DestroyTree(pLeft);
DestroyTree(pRight);
}
}
void test7()
{
int ahead_array[] = {1, 2, 4, 7, 3, 5, 6, 8};
int middle_array[] = {4, 7, 2, 1, 5, 3, 8, 6};
int length = 8;
printf("The preorder sequence is: ");
for (int i = 0; i < length; ++i)
printf("%d ", ahead_array[i]);
printf("\n");
printf("The inorder sequence is: ");
for (int i = 0; i < length; ++i)
printf("%d ", middle_array[i]);
printf("\n");
BinaryTreeNode *root = rebuild_tree_form_aheadAndMiddle(ahead_array, middle_array, length);
PrintTree(root);
DestroyTree(root);
}
int main(int argc, char *argv[])
{
test7();
return 0;
}