Algorithm 构建二叉表达式树

Algorithm 构建二叉表达式树,algorithm,expression-trees,Algorithm,Expression Trees,有人能解释一下如何建立一个二进制表达式树吗 * | \ | \ 2 + |\ 1 * |\ 2 1 例如,我有一个字符串2*(1+(2*1))如何将其转换为二进制表达式树 * | \ | \ 2 + |\ 1 * |\ 2 1 将表达式转换为前缀或后缀表示法。从这里开始,它应该非常简单。以下wiki链接中提到了算法 您需要: 定义描述您的语言的语法 编写一个从字符串中读取标记的词法分析器

有人能解释一下如何建立一个二进制表达式树吗

 *
 | \
 |  \
 2  +
    |\
    1 *
      |\
      2 1
例如,我有一个字符串
2*(1+(2*1))如何将其转换为二进制表达式树

 *
 | \
 |  \
 2  +
    |\
    1 *
      |\
      2 1

将表达式转换为前缀或后缀表示法。从这里开始,它应该非常简单。以下wiki链接中提到了算法

您需要:

  • 定义描述您的语言的语法
  • 编写一个从字符串中读取标记的词法分析器
  • 编写一个解析器,从标记构建树
  • 例如,看看这种方法:


    还有一些

    将中缀转换为后缀或前缀

    后缀输入是:ab+cde+**

  • 考虑第一个字符,若它不是符号,则创建节点并将其添加到堆栈中
  • 若字符是symbol,则使用symbol pop元素创建节点,并将其添加到symbol的左侧和右侧
  • 将符号节点推入堆栈
  • 重复1、2和3,直到迭代器没有更多的元素
  • Java实现

    public Tree.TreeNode createExpressionTree(){
        Iterator<Character>itr = postOrder.iterator();
        Tree tree = new Tree();
        NodeStack nodeStack = new NodeStack();
        Tree.TreeNode node;
        while (itr.hasNext()) {
            Character c = itr.next();
            if(!isDigit(c)){
                node = tree.createNode(c);
                node.right = nodeStack.pop();
                node.left = nodeStack.pop();
                nodeStack.push(node);
            }else{
                node = tree.creteNode(c);
                nodeStack.push(node);
            }
        }
        node = nodeStack.pop();
        return node;
    }
    
    public Tree.TreeNode createExpressionTree(){
    Iteratoritr=postOrder.iterator();
    树=新树();
    NodeStack NodeStack=新的NodeStack();
    Tree.TreeNode节点;
    while(itr.hasNext()){
    字符c=itr.next();
    如果(!isDigit(c)){
    node=tree.createNode(c);
    node.right=nodeStack.pop();
    node.left=nodeStack.pop();
    nodeStack.push(节点);
    }否则{
    node=tree.creteNode(c);
    nodeStack.push(节点);
    }
    }
    node=nodeStack.pop();
    返回节点;
    }
    

    更多信息:

    可分为两个步骤:

  • 计算每个令牌的优先级值

    例如:“+”:1,“x”:2,数字:inf,”(“:将10添加到基数中“)”:从基数中减去10)

  • 使用堆栈基于优先级构建(大约5行代码)


  • 您可以在一次扫描中完成。

    对于一个相当简单的赋值来说,这可能是一个过火的操作,它可以直观地显示表达式是如何解析的。这里symbol=operator您可以使用调车场算法实现一个解决方案。以下是有关wikipiedia的一些详细信息:。这个算法是由Edsger Dijkstra发明的,它是一个很好的选择。如果您需要一些详细信息,我可以发布一个我不久前用C#编写的代码示例,但我想维基百科链接已经足够了。