剑指offer| |重建二叉树

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

对于重建二叉树的思路:
根据前序序列可以得到二叉树的根节点,然后再在中序遍历中找到该根节点,于是就将二叉树分为了两个部分,左边为左子树,右边为右子树,然后再对左右子树进行刚才的步骤进行:每次都要将左右子树的前序遍历和中序遍历的起始地址和结束地址求出来。

代码如下:

代码:

//根据前序序列和中序序列重建二叉树
BTNode* Construct(int* Prevstart, int* Prevend, int* Instart, int* Inend)
{
    assert(Prevend && Prevstart && Instart && Inend);

    //创建根节点
    BTNode* root = BuyBTNode(*Prevstart);

    //判断该二叉树是不是只有一个根节点
    if (Prevend - Prevstart == 0)
    {
        if (Inend - Instart == 0 && *Prevstart == *Instart)
        {
            return root;
        }
        else
        {
            printf("请检查输入是否正确1!\n");
            exit(1);
        }
    }

    //该二叉树具有不止一个节点
    //在中序序列中,找到根节点,将其分为两个部分,在递归进行重建
    int* InOrderRoot = Instart;
    while (*InOrderRoot != *Prevstart && InOrderRoot < Inend)
    {
        InOrderRoot++;
    }

    //在中序遍历中,没有找到根节点
    if (InOrderRoot == Inend && *InOrderRoot != *Prevstart)
    {
        printf("请检查输入是否正确2!\n");
        exit(1);
    }

    //左子树的长度
    int length_left = InOrderRoot - Instart;
    //对左子树进行重建
    if (length_left > 0)
    {
        root->_left = Construct(Prevstart + 1, Prevstart + length_left, Instart, InOrderRoot - 1);
    }

    //对右子树进行重建
    if (length_left < Prevend - Prevstart)
    {
        root->_right = Construct(Prevstart + length_left + 1, Prevend, InOrderRoot + 1, Inend);
    }
    return root;
}

猜你喜欢

转载自blog.csdn.net/qq_40399012/article/details/82432704