LintCode-剑指Offer-(73)前序遍历和中序遍历树构造二叉树

原创 2015年11月21日 17:05:29
class Solution {
    /**'
    * '
    *@param preorder : A list of integers that preorder traversal of a tree
    *@param inorder : A list of integers that inorder traversal of a tree
    *@return : Root of a tree
    */
public:
    //获取一个元素在vector中的下标
    int getLoc(vector<int >& ino, int ele){
        for ( int i = 0; i < ino.size( ); i++ ){
            if ( ino[i] == ele ){
                return i;
            }
        }
        return -1;
    }
    //是否在左边子树中
    bool IsInChildLeftTree(int ele, int s, int e, vector<int> v){
        for ( int i = s; i < e; i++ ){
            if ( ele == v[i] )
                return true;
        }
        return false;
    }
public:

    //找到右子树的根节点
    //s:中序遍历中左子树的起点
    //incurpos:当前子树根节点在中序遍历的位置,是查找的终点
    //precurpos:当前子树根节点在前序遍历的位置 ,也是左子树的终点
    int findRightRoot(vector<int> pre, vector<int> ino, int s, int precurpos, int incurpos)
    {
        int i = precurpos + 1; //当前根的起点,是在前序遍历中的
        while ( i < pre.size( ) && IsInChildLeftTree(pre[i], s, incurpos, ino) == true ){  //如果处于左子树中,下标增加
            i++;
        }
        if ( i >= pre.size( ) )return -1;
        return i;
    }
    //s:子树起点
    //e:子树终点,这两个都是指在中序遍历中的位置
    //precurpos:当前子树根节点的在前序遍历中的位置
    //incurpos:当前子树根节点在中序遍历的位置
    //node:传入的根节点
    TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
        // write your code here
        TreeNode* root = NULL;
        if ( preorder.size( ) == 0 )
            return NULL;
        buildTree(preorder, inorder, 0, preorder.size( ), 0, getLoc(inorder, preorder[0]), root);
        return root;
    }

     //s,e指定了区间长度
    //precurpos:当前根在前序遍历中的位置
    //incurpos:当前根在中序遍历中的位置
    void buildTree(vector<int> &preorder, vector<int> &inorder, int s, int e, int precurpos, int incurpos, TreeNode*& node) {
        static int* inblocked = new int[preorder.size( )];  //保存当前已经构造完毕的节点
        if ( s >= e || precurpos > preorder.size( ) || incurpos > preorder.size( ) || e > preorder.size( ) ){
            node = NULL;
            return;
        }
        node = new TreeNode(preorder[precurpos]);//当前节点已经构造,不用再次构造
        int currentblockloc = getLoc(inorder, preorder[precurpos]);
        inblocked[currentblockloc] = 1;//所以不用再次构造,blocked=1
        //cout << "constructing node:" << node->val << endl;   
        //从先序遍历中找到右边子节点
        int tmprightcur = findRightRoot(preorder, inorder, s, precurpos, incurpos);
        int ttt; //找到当前节点在中序遍历中的位置,这个位置可以将中序遍历的序列分为左边和右边
        ttt= getLoc(inorder, preorder[precurpos]);
        //cout << "start from:" << s << "end with:" << ttt << endl;
        //如果当前左边已经到边界,或者已经有值,那么左边不用处理
        if ( !( currentblockloc < 0 || (currentblockloc>0&& inblocked[currentblockloc - 1] == 1 ) ) && precurpos + 1<preorder.size() )
            buildTree(preorder, inorder, s, ttt, precurpos + 1, getLoc(inorder, preorder[precurpos + 1]), node->left);
        //cout << "start from:" << ttt << "end with:" << tmprightcur << endl;
        //如果当前右边已经到了边界,或者已经有值,那么右边不用处理
        if ( !( currentblockloc >= preorder.size() || (currentblockloc<preorder.size()-1&& inblocked[currentblockloc + 1] == 1)&&tmprightcur!=-1 )
            && tmprightcur<preorder.size() )
            buildTree(preorder, inorder, ttt,e, tmprightcur,getLoc(inorder,preorder[tmprightcur]), node->right);
    }
    void DisplayTree(TreeNode* root){
        if ( root == NULL )
            return;
        cout << root->val << endl;
        DisplayTree(root->left);
        DisplayTree(root->right);
    }
};
版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

[LintCode]73.前序遍历和中序遍历树构造二叉树

根据前序遍历和中序遍历树构造二叉树. 注意事项:你可以假设树中不存在相同数值的节点 样例:给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: 2...

73.Construct Binary Tree from Preorder and Inorder Traversal-前序遍历和中序遍历树构造二叉树(中等题)

前序遍历和中序遍历树构造二叉树 题目根据前序遍历和中序遍历树构造二叉树.注意事项 你可以假设树中不存在相同数值的节点 样例给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: ...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

73前序遍历和中序遍历树构造二叉树

根据前序遍历和中序遍历树构造二叉树. 给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树: 2 / \ 1 3 解题思路:1.先序遍历的第一个节...

根据前序遍历和中序遍历树构造二叉树

根据前序遍历和中序遍历树构造二叉树.注意事项:你可以假设树中不存在相同数值的节点

LintCode(72)中序遍历和后序遍历树构造二叉树

题目  中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3...
  • fly_yr
  • fly_yr
  • 2016-06-15 20:46
  • 1384

前序遍历和中序遍历构造二叉树[lintcode]

/** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left,...

(剑指offer笔记)根据前序遍历和中序遍历重建二叉树

问题:输入某二叉树的前序遍历和中序遍历的结果,重建出该二叉树,假设输入的前序遍历和终须遍历的结果

剑指offer 重建二叉树-前序遍历和中序遍历重建

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果都不含重复的数字。 二叉树定义如下: 1 2 3 4 5 6 ...

中序遍历和后序遍历树构造二叉树

题目描述:根据中序遍历和后序遍历树构造二叉树 这是典型的递归算法的应用。 什么是中序遍历、后序遍历,我想无需多说了。直接看看遍历之后列表的结构。 中序遍历:[left s...

剑指offer给定二叉树,求中序遍历的下一个 节点,前序遍历,后序遍历扩展

题目链接https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)