表达式树
表达式树是一棵二叉树,其中每个内部节点对应于运算符,每个叶节点对应于操作数,因此例如 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)
表达式树的构建:
现在为了构建表达式树,我们使用堆栈。我们遍历输入表达式并对每个字符执行以下操作。
- 如果字符是操作数,则将其压入堆栈
- 如果一个字符是运算符,则从堆栈中弹出两个值,使其成为子节点并再次推送当前节点。
最后,堆栈的唯一元素将是表达式树的根。
例子:
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