LintCode 表达树构造(栈,二叉树)

LintCode上的一道题,表达树构造,大意是给出一个算术表达式,要我们构造它的表达树。

可以通过压栈和出栈来处理表达式中的括号,但乘除法优先级比加减法高且不需要括号标识,处理起来比较麻烦。

琢磨了半天才搞出来,写得比较别扭,以后有时间再改进。

/**
 * Definition of ExpressionTreeNode:
 * class ExpressionTreeNode {
 * public:
 *     string symbol;
 *     ExpressionTreeNode *left, *right;
 *     ExpressionTreeNode(string symbol) {
 *         this->symbol = symbol;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param expression: A string array
     * @return: The root of expression tree
     */
     vector<ExpressionTreeNode*> stack;
     
    ExpressionTreeNode* build(vector<string> &expression) {
        // write your code here
        ExpressionTreeNode* root = new ExpressionTreeNode("");
        stack.push_back(root);
        for(int i = 0; i < expression.size(); ++i){
            ExpressionTreeNode* node = getNode(0);
            string& s = expression[i];
            if(s == "+" || s == "-"){
                if(node->symbol == "*" || node->symbol == "/"){ //前面是乘除法的要出栈
                    unbrackSub();
                }
                
                node = getNode(0);
                if(node->symbol == ""){
                    node->symbol = s;
                    continue;
                }
                
                lfunc(s);
                
            }else if(s == "*" || s == "/"){
                if(node->symbol == "*" || node->symbol == "/"){
                    lfunc(s);
                }else { 
                    rfunc(s);
                }
                
            }else if(s == "(" || s == "[" || s == "{"){
                brack();
            }else if(s == ")" || s == "]" || s == "}"){
                unbrack();
            }else{
                if(node->symbol == ""){
                    node->symbol = s;
                }else if(node->left == NULL){
                    node->left = new ExpressionTreeNode(s);
                }else if(node->right == NULL){
                    node->right = new ExpressionTreeNode(s);
                }
            }       
        }
        
        unbrack(); //再出栈一次清除符号为""的情况
        
        if(root->symbol == ""){ //考虑到只有括号的情况
            return NULL;
        }else{
            return root;    
        }
    }
    
    void lfunc(string& s){ //平等优先级操作符
        ExpressionTreeNode* node = getNode(0);
        ExpressionTreeNode* lnode = new ExpressionTreeNode(node->symbol);
        lnode->left = node->left;
        lnode->right = node->right;
        node->left = lnode;
        node->symbol = s;
        node->right = NULL;
    }
    
    void rfunc(string& s){ //高优先级操作符
        ExpressionTreeNode* node = getNode(0);
        ExpressionTreeNode* rnode = new ExpressionTreeNode(s);
        if(node->right == NULL){
            if(node->left == NULL){ //叶子节点
                rnode->left = new ExpressionTreeNode(node->symbol);
                node->symbol = "";
            }else{ //缺右子树的加减法节点
                rnode->left = node->left;
                node->left = NULL;
            }
        }else{ //完整的加减法节点
            rnode->left =  node->right;
            node->right = NULL;
        }
        stack.push_back(rnode); //乘除法都压栈
    }
    
    void brack(){ //括号操作
        stack.push_back(new ExpressionTreeNode(""));
    }
    
    void unbrack(){ //反括号操作
        ExpressionTreeNode* node = getNode(0);
        if(node->symbol == "*" || node->symbol == "/"){ //如果有乘除法未出栈先将他们出栈
            unbrackSub();    
        }
        unbrackSub(); //再进行一次针对括号的出栈操作
    }
    
    void unbrackSub(){//出栈操作
        ExpressionTreeNode* pnode = getNode(-1);
        ExpressionTreeNode* node = getNode(0);
        if(node->symbol == ""){
            ExpressionTreeNode* l = node->left;
            if(l != NULL){
                node->symbol = l->symbol;
                node->left = l->left;
                node->right = l->right;
            }
        }
        
        if(pnode != NULL){
            if(pnode->left == NULL){
                pnode->left = node;
            }else{
                pnode->right = node;
            }
            stack.pop_back();
        }
    }
    
    ExpressionTreeNode* getNode(int index){
        int p = stack.size() + index - 1;
        if(p >= 0){
            return stack[p];
        }else{
            return NULL;
        }
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值