表达树构造
表达树是一个二叉树的结构,用于衡量特定的表达。所有表达树的叶子都有一个数字字符串值。而所有表达树的非叶子都有另一个操作字符串值。
给定一个表达数组,请构造该表达的表达树,并返回该表达树的根。
逆波兰式转换为表达式树相对比较简单,只需要一个栈保存node,遇到操作符是,弹出前两个node,分别为左右子节点。
解题思路
1.将中缀表达式转换为逆波兰式(或称后缀表达式)
2. 逆波兰式转换为表达式树
(a+b)*(c*(d+e);
对该树进行后序遍历得到后缀表达式
ab+cde+**;
这里实现的是如何根据一个后缀表达式,构造出其相应的表达式树。
算法思想:其实很简单,主要就是栈的使用。算法时间复杂度是O(n),n是后缀表达式长度。
从前向后依次扫描后缀表达式,如果是操作数就建立一个单节点树,并把其指针压入栈。如果是操作符,则
建立一个以该操作符为根的树,然后从栈中依次弹出两个指针(这2个指针分别指向2个树),作为该树的
左右子树。然后把指向这棵树的指针压入栈。直到扫描完后缀表达式。
最后栈中就会只有一个指针。这个指针指向构造的表达式树的根节点。
/**
* Definition of ExpressionTreeNode:
* class ExpressionTreeNode {
* public:
* string symbol;
* ExpressionTreeNode *left, *right;
* ExpressionTreeNode(string symbol) {
* this->symbol = symbol;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
private:
bool isOp(string str)
{
if((str.compare("+") == 0) || (str.compare("-") == 0) ||
(str.compare("*") == 0) || (str.compare("/") == 0))
{
return true;
}
return false;
}
int compareOrder(string str1, string str2)
{
int order1 = ((str1.compare("*") == 0) || (str1.compare("/") == 0)) ? 1 : 0;
int order2 = ((str2.compare("*") == 0) || (str2.compare("/") == 0)) ? 1 : 0;
return order1 - order2;
}
// 将中缀表达式转换为后缀表达式(逆波兰式)
vector<string> convertToRPN(vector<string> &expression){
vector<string> rpnList;
stack<string> opStack;
for(int i = 0; i < expression.size(); i++){
string now = expression[i];
if(now.compare("(") == 0){
opStack.push(now);
}
else if(now.compare(")") == 0){
while(!opStack.empty() &&
opStack.top().compare("(") != 0){
rpnList.push_back(opStack.top());
opStack.pop();
}
if(!opStack.empty()) {
opStack.pop();
}
}
else if(isOp(now)){
while(!opStack.empty() &&
isOp(opStack.top()) &&
compareOrder(now, opStack.top()) <= 0){
rpnList.push_back(opStack.top());
opStack.pop();
}
opStack.push(now);
}
else {
rpnList.push_back(now);
}
}
while(!opStack.empty()){
rpnList.push_back(opStack.top());
opStack.pop();
}
return rpnList;
}
ExpressionTreeNode* buildFromRPN(vector<string> &expression){
if(expression.size() == 0){
return NULL;
}
stack<ExpressionTreeNode*> s;
for(int i = 0; i < expression.size(); i++){
string now = expression[i];
if(isOp(now)){
ExpressionTreeNode * right = s.top();
s.pop();
ExpressionTreeNode * left = s.top();
s.pop();
ExpressionTreeNode * node = new ExpressionTreeNode(now);
node->left = left;
node->right = right;
s.push(node);
}
else{
s.push(new ExpressionTreeNode(now));
}
}
return s.top();
}
public:
/**
* @param expression: A string array
* @return: The root of expression tree
*/
ExpressionTreeNode* build(vector<string> &expression) {
// write your code here
if(expression.size() == 0) {
return NULL;
}
vector<string> rpe = convertToRPN(expression);
return buildFromRPN(rpe);
}
};