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

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);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值