剑指offer之重建二叉树

本文介绍了一种根据二叉树的前序遍历和中序遍历结果重建二叉树的算法。通过分析两种遍历序列的特点,使用递归方法构建二叉树,并提供了完整的实现代码。

题目: 

    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含有重复的数字。例如,前序遍历序列:{1,2,3,7,3,5,6,8},中序遍历序列:{4,7,2,1,5,3,8,6},请重建出如图所示的二叉树。


分析:

    如图所示,前序遍历序列的第一个数字1就是跟结点的值。扫描中序遍历序列,就能确定跟结点的值的位置。根据中序遍历特点,在根结点的值1前面的3个数字都是左子树结点的值,为于1后面的数字都是右子树的值。在中序遍历中,有3个数字是左子树的值,因此左子树总共有3个左子结点。同样,在前序遍历中,根结点后面的3个数字就是3个左子树节点的值,同后面的所有数字都是右子树节点的值。既然分别找到了左右子树的前序遍历序列和中序遍历序列,我们可以用同样的方法去构建左右字树。用递归的方法。


代码:

struct BinaryTreeNode 

{

     int  m_nValue ;

    BinaryTreeNode  * m_pLeft;

    BinaryTreeNode  * m_pRight;

}

     

BinaryTreeNode * constuct(int* preorder, int* inorder, int length)
{
    if(preorder == NULL || inorder == NULL || length <= 0)
    {
        return NULL;
    }

    return construct_method(preorder, preorder+length-1, inorder,inorder+length-1);

}
BinaryTreeNode * construct_method(int* preorder, int* endpreorder, int* inorder, int* endinorder)
{ int root_value = preorder[0];
         BinaryTreeNode * root = new BinaryTreeNode();
    root->m_nValue = root_value ;
root->left = NULL; root->right = NULL;

    if(preorder == endpreorder) { //如果只有一个结点,则返回该结点的指针。
        if(inorder == endinorder && *preorder == *endpreorder)
            return root;
        else
            throw std::exception("Invalid input.");
    }
    
//在中序遍历中查找根结点的值
    int* rootInorder = inorder;
    while(*rootInorder != root_value && rootInorder < endinorder)
        rootInorder++;

    int left_len = rootInorder - inorder;
    int* left_preorder_end = preorder + left_len;
    //构建左子树
    if(left_len > 0)
    {
        root->m_pLeft = construct_method(preorder+1, left_preorder_end, inorder, rootInorder-1);
    }
    //构建右子树
    if(left_len < endpreorder - preorder)
    {
        root->m_pRight = construct_method(left_preorder_end+1, endpreorder, rootInorder+1, endinorder);
    }

    return root;
}

//测试
int main()
{
    int pre[8] = {1,2,4,7,3,5,6,8};
    int in[8]  = {4,7,2,1,5,3,8,6};
    binary_tree_node* root = binary_tree_constuct(pre, in, 8);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值