zoukankan      html  css  js  c++  java
  • 剑指Offer面试题:5.重建二叉树

    一 题目:重建二叉树

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

    二 思路

      先根据前序遍历序列的第一个数字创建根结点,接下来在中序遍历序列中找到根结点的位置,这样就能确定左、右子树结点的数量。在前序遍历和中序遍历的序列中划分了左、右子树结点的值之后,就可以递归地去分别构建它的左右子树。

    三 代码实现

    (1)索引实现

    struct TreeNode
    {
        int data;
        TreeNode* pLeft;
        TreeNode* pRight;
    };
    
    // 重构二叉树
    TreeNode* RebulidTree(int *pre, int *mid, int len)
    {
        if(NULL == pre || NULL == mid || len < 0)
        {
            return NULL;
        }
        // 根据前序遍历得到根节点
        int root = pre[0];
        TreeNode *pNode = new TreeNode;
        pNode->data = root;
        pNode->pLeft = pNode->pRight = NULL;
        
        int i = 0;
        // 根据根节点将中序遍历结果分成左子树和右子树,前提肯定能找到
        for (; i < len;i ++)
        {
            if (root == mid[i])
            {
                break;
            }
        }
        if (i > 0)
        {
            int *midleft = new int[i];
            memcpy(midleft, mid, sizeof(int) * i);
            int *preleft = new int[i];
            memcpy(preleft, &pre[1], sizeof(int)*i);
            pNode->pLeft = RebulidTree(preleft, midleft, i);
            delete[] midleft;
            delete[] preleft;
        }
        if (i < len-1)
        {
            int *midright = new int[len - i - 1];
            // 将中序分配左子树,右子树
            memcpy(midright, &mid[i+1], sizeof(int)*(len-i-1));
            // 将前序分配左子树和右子树
            int *preright = new int[len-i-1];
            memcpy(preright, &pre[i + 1], sizeof(int)*(len-i-1));
            pNode->pRight = RebulidTree(preright, midright, len - i - 1);
            delete[] midright;
            delete[] preright;
        }
        
        return pNode;
    }

    (2)指针实现

    struct TreeNode
    {
        int data;
        TreeNode* pLeft;
        TreeNode* pRight;
    };
    
    TreeNode* StructNode(int *StartPre, int *EndPre, int *StartMid, int *EndMid)
    {
        // 根据前序遍历得到根节点
        int nRootValue = StartPre[0];
        TreeNode *pNode = new TreeNode;
        pNode->data = nRootValue;
        pNode->pLeft = pNode->pRight = NULL;
    
        if (StartPre == EndPre)
        {
            if ((StartMid == EndMid) && (*StartPre == *StartMid))
            {
                return pNode;
            }
            else
            {
                throw std::exception("Invalid input");
            }
        }
        // 在中序遍历中找到根结点的值
        int *RootMid = StartMid;
        while(RootMid < EndMid && *RootMid != nRootValue)
        {
            RootMid ++;
        }
        // 若没找到,抛出异常
        if(RootMid == EndMid && *RootMid != nRootValue)
        {
            throw std::exception("Invalid input");
        }
    
        int nLeftLength = RootMid - StartMid;
        int *LeftPreEnd = StartPre+nLeftLength;
        if (nLeftLength > 0)
        {
            pNode->pLeft = StructNode(++StartPre, LeftPreEnd, StartMid, RootMid-1);
        }
        if (nLeftLength < EndMid - StartMid)
        {
            pNode->pRight = StructNode(LeftPreEnd+1, EndPre,  RootMid+1, EndMid);
        }
        return pNode;
    }
    
    TreeNode* RebulidTree_2 (int *pre, int *mid, int len)
    {
        if(NULL == pre || NULL == mid || len < 0)
        {
            return NULL;
        }
    
        return StructNode(pre, pre + len -1, mid, mid+len-1);
    }
    
    void main()
    {
        int pre[] = {1,2,4,7,3,5,6,8};
        int mid[] = {4,7,2,1,5,3,8,6};
    
        TreeNode* p =RebulidTree_2(pre, mid, 8);
        return;
    }
  • 相关阅读:
    Python requests“Max retries exceeded with url” error
    命令行链接mongo、redis、mysql
    python 删除字典某个key(键)及对应值
    python标准模块(二)
    python标准模块(一)
    格式化输出
    LeetCode----1. Two Sum
    文件操作(初阶)
    python函数基础
    python3内置函数
  • 原文地址:https://www.cnblogs.com/xiaobingqianrui/p/8820660.html
Copyright © 2011-2022 走看看