📜  表达式树

📅  最后修改于: 2022-05-13 01:57:16.486000             🧑  作者: Mango

表达式树

表达式树是一棵二叉树,其中每个内部节点对应于运算符,每个叶节点对应于操作数,因此例如 3 + ((5+9)*2) 的表达式树将是:

表达

表达式树的中序遍历产生给定后缀表达式的中缀版本(与后序遍历相同,它给出后缀表达式)

评估由表达式树表示的表达式:

Let t be the expression tree
If  t is not null then
      If t.value is operand then  
                Return  t.value
      A = solve(t.left)
      B = solve(t.right)
 
      // calculate applies operator 't.value' 
      // on A and B, and returns value
      Return calculate(A, B, t.value)

表达式树的构建:

现在为了构建表达式树,我们使用堆栈。我们遍历输入表达式并对每个字符执行以下操作。

  1. 如果字符是操作数,则将其压入堆栈
  2. 如果一个字符是运算符,则从堆栈中弹出两个值,使其成为子节点并再次推送当前节点。

最后,堆栈的唯一元素将是表达式树的根。

例子:

Input:  A B C*+ D/
Output: A + B * C / D

前三个符号是操作数,因此创建树节点并将指向它们的指针压入堆栈,如下所示。

在下一步中,将读取一个运算符'*',因此弹出两个指向树的指针,形成一棵新树并将指向它的指针压入堆栈

在下一步中,将读取一个运算符“+”,因此弹出两个指向树的指针,形成一棵新树并将指向它的指针压入堆栈。

A3f.png

类似地,与上述情况一样,首先我们将'D'压入堆栈,然后在最后一步首先读取'/',然后像上一步一样,最顶层的元素将弹出,然后将是根'/'的右子树和其他节点将是右子树。

最终构造的表达式树是:

A4f.png

以下是上述方法的代码:

下面是上述方法的实现:

C++
// C++ program for expression tree
#include 
using namespace std;
class node {
public:
    char value;
    node* left;
    node* right;
    node* next = NULL;
    node(char c)
    {
        this->value = c;
        left = NULL;
        right = NULL;
    }
    node()
    {
        left = NULL;
        right = NULL;
    }
    friend class Stack;
    friend class expression_tree;
};
class Stack {
    node* head = NULL;
 
public:
    void push(node*);
    node* pop();
    friend class expression_tree;
};
class expression_tree {
public:
    void inorder(node* x)
    {
        // cout<<"Tree in InOrder Traversal is: "<left);
            cout << x->value << "  ";
            inorder(x->right);
        }
    }
};
 
void Stack::push(node* x)
{
    if (head == NULL) {
        head = x;
    }
    // We are inserting here nodes at the top of the stack [following LIFO principle]
    else {
        x->next = head;
        head = x;
    }
}
node* Stack::pop()
{
    // Popping out the top most[ pointed with head] element
    node* p = head;
    head = head->next;
    return p;
}
int main()
{
    string s = "ABC*+D/";
    // If you  wish take input from user:
    //cout << "Insert Postorder Expression: " << endl;
    //cin >> s;
    Stack e;
    expression_tree a;
    node *x, *y, *z;
    int l = s.length();
    for (int i = 0; i < l; i++) {
        // if read character is operator then popping two
        // other elements from stack and making a binary
        // tree
        if (s[i] == '+' || s[i] == '-' || s[i] == '*'
            || s[i] == '/' || s[i] == '^') {
            z = new node(s[i]);
            x = e.pop();
            y = e.pop();
            z->left = y;
            z->right = x;
            e.push(z);
        }
        else {
            z = new node(s[i]);
            e.push(z);
        }
    }
    cout << " The Inorder Traversal of Expression Tree: ";
    a.inorder(z);
    return 0;
}


C
#include 
#include 
 
/* A binary tree node has data, pointer to left child
   and a pointer to right child */
struct node {
    char data;
    struct node* left;
    struct node* right;
    struct node* next;
};
 struct node *head=NULL;
/* Helper function that allocates a new node with the
   given data and NULL left and right pointers. */
struct node* newNode(char data)
{
    struct node* node
        = (struct node*)malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    node->next = NULL;
     
    return (node);
}
void printInorder(struct node* node)
{
    if (node == NULL)
        return;
    else{
    /* first recur on left child */
    printInorder(node->left);
 
    /* then print the data of node */
    printf("%c ", node->data);
 
    /* now recur on right child */
    printInorder(node->right);
    }
}
 
void push(struct node* x)
{
    if(head==NULL)
    head = x;
    else
    {
        (x)->next = head;
        head  = x;
    }
    // struct node* temp;
    // while(temp!=NULL)
    // {
    //     printf("%c ", temp->data);
    //     temp = temp->next;
    // }
}
struct node* pop()
{
    // Poping out the top most[ pointed with head] element
    struct node* p = head;
    head = head->next;
    return p;
}
int main()
{
    char s[] = {'A','B','C','*','+','D','/'};
    int l = sizeof(s) / sizeof(s[0]) ;
    struct node *x, *y, *z;
    for (int i = 0; i < l; i++) {
        // if read character is operator then poping two
        // other elements from stack and making a binary
        // tree
        if (s[i] == '+' || s[i] == '-' || s[i] == '*'
            || s[i] == '/' || s[i] == '^') {
            z = newNode(s[i]);
            x = pop();
            y = pop();
            z->left = y;
            z->right = x;
            push(z);
        }
        else {
            z = newNode(s[i]);
            push(z);
        }
    }
    printf(" The Inorder Traversal of Expression Tree: ");
    printInorder(z);
    return 0;
}


Java
import java.util.Stack;
 
class Node{
    char data;
    Node left,right;
    public Node(char data){
        this.data = data;
        left = right = null;
    }
}
 
public class Main {
    public static boolean isOperator(char ch){
        if(ch=='+' || ch=='-'|| ch=='*' || ch=='/' || ch=='^'){
            return true;
        }
        return false;
    }
    public static Node expressionTree(String postfix){
        Stack st = new Stack();
        Node t1,t2,temp;
 
        for(int i=0;i


C#
using System;
using System.Collections.Generic;
 
 
class Node{
    public char data;
    public Node left,right;
    public Node(char data){
        this.data = data;
        left = right = null;
    }
}
 
public class GFG {
    public static bool isOperator(char ch){
        if(ch=='+' || ch=='-'|| ch=='*' || ch=='/' || ch=='^'){
            return true;
        }
        return false;
    }
    static Node expressionTree(String postfix){
        Stack st = new Stack();
        Node t1, t2, temp;
 
        for(int i = 0; i < postfix.Length; i++)
        {
            if(!isOperator(postfix[i])){
                temp = new Node(postfix[i]);
                st.Push(temp);
            }
            else{
                temp = new Node(postfix[i]);
 
                t1 = st.Pop();
                t2 = st.Pop();
 
                temp.left = t2;
                temp.right = t1;
 
                st.Push(temp);
            }
 
        }
        temp = st.Pop();
        return temp;
    }
    static void inorder(Node root){
        if(root == null) return;
 
        inorder(root.left);
        Console.Write(root.data);
        inorder(root.right);
    }
    public static void Main(String[] args)
    {
        String postfix = "ABC*+D/";
 
        Node r = expressionTree(postfix);
        inorder(r);
    }
}
 
// This code is contributed by 29AjayKumar


输出:

A+B*C/D