NAME REGISTER NUMBER
IDRIS 310623105018
NITHIYA PRAKASH 310623105037
DHARINEESH R M 310623105010
EASWARI ENGINEERING COLLEGE
GROUP PRESENTATION
EXPRESSION TREES
DATA
STRUCTURES
WITH C
231CSS421T
GROUP-16
DATE: 26-03-25
SECOND YEAR – IV SEM
Introduction to Expression
Expression Trees
Expression trees are essential for evaluating mathematical
expressions. They follow a hierarchical structure with operators
and numerical values. These trees are useful in compiler design
and expression simplifications.
Why Use Expression Trees?
1 Efficient Evaluation
Preserves the correct order of
operations.
2 Compiler Design
Converts high-level code into
machine instructions.
3 Expression Parsing
Eases processing of complex
mathematical operations.
Notations and Expression Trees
Infix Notation
Operators appear between operands
(e.g., A + B).
Familiar and widely used, but requires
parentheses for precedence.
Prefix Notation
Operators come before their
operands.The infix expression "A + B"
becomes "+ A B" in prefix notation.
Suitable for stack-based
computations, evaluates left to right.
Postfix Notation
Operators are placed after the
operands.The infix expression "A + B"
becomes "A B +" in postfix notation.
Eliminates parentheses by placing
operators before operands.
Structure of an
Expression Tree
Binary Tree
Leaf nodes represent operands.
Internal Nodes
Represent operators.
Bottom-Up Evaluation
Child nodes are processed before parent nodes.
Binary Tree Properties
Constructing an Expression Tree
Parsing the Expression
The first step is to break the input expression into tokens
(operators and operands).
Handle Parentheses
Evaluate grouped operations first.
Operator Precedence
Structure the tree accordingly.
Implementation in C
Node Structure
Define a structure. It should hold data, a left pointer, and
a right pointer.
Data Field
This field stores the operator or operand at each node. It
can be extended for more complex data types.
Pointers
Left and right pointers link each node. They connect to
child subtrees.
Tree Traversal
Recursive traversal ensures proper order. It performs
computations using postorder traversal.
Complete C Program: Expression Tree Implementation
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
// Structure definition for tree nodes
typedef struct Node {
char data;
struct Node *left, *right;
} Node;
// Function to create a new node
Node* createNode(char data) {
Node* newNode =
(Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->left = newNode->right =
NULL;
return newNode;
// Stack structure for tree nodes
typedef struct Stack {
Node* data[100]; // Stack to hold tree nodes
int top;
} Stack;
// Initialize stack
void initStack(Stack* stack) {
stack->top = -1;
}
// Push node onto stack
void push(Stack* stack, Node* node) {
stack->data[++stack->top] = node;
}
// Pop node from stack
Node* pop(Stack* stack) {
return stack->data[stack->top--];
// Function to construct an expression tree from
postfix expression
Node* constructTree(char postfix[]) {
Stack stack;
initStack(&stack);
int i;
for (i = 0; i < strlen(postfix); i++) {
char ch = postfix[i];
// If operand, create node and push onto stack
if (isdigit(ch)) {
push(&stack, createNode(ch));
}
// If operator, pop two nodes, create subtree,
and push back
else {
Node* newNode = createNode(ch);
newNode->right = pop(&stack);
newNode->left = pop(&stack);
push(&stack, newNode);
}
}
return pop(&stack); // Root node }
// Function to evaluate the expression
tree using recursion
int evaluate(Node* root) {
// If leaf node, return the operand
if (root->left == NULL && root->right == NULL)
return root->data - '0'; // Convert char to int
// Evaluate left and right subtrees
int leftVal = evaluate(root->left);
int rightVal = evaluate(root->right);
// Perform the corresponding arithmetic operation
switch (root->data) {
case '+': return leftVal + rightVal;
case '-': return leftVal - rightVal;
case '*': return leftVal * rightVal;
case '/': return leftVal / rightVal;
}
return 0;
}
// Inorder traversal (Left -> Root -> Right)
void inorder(Node* root) {
if (root != NULL) {
inorder(root->left);
printf("%c ", root->data);
inorder(root->right);
}
}
// Postorder traversal (Left -> Right -> Root)
void postorder(Node* root) {
if (root != NULL) {
postorder(root->left);
postorder(root->right);
printf("%c ", root->data);
}
}
// Preorder traversal (Root -> Left -> Right)
void preorder(Node* root) {
if (root != NULL) {
printf("%c ", root->data);
preorder(root->left);
preorder(root->right); } }
// Main function
int main() {
char postfix[] = "35+2*"; // Example expression: (3
+ 5) * 2
Node* root = constructTree(postfix);
printf("Infix Expression: ");
inorder(root);
printf("n");
printf("Postfix Expression: ");
postorder(root);
printf("n");
printf("Prefix Expression: ");
preorder(root);
printf("n");
printf("Evaluated Result: %dn", evaluate(root));
return 0;
}
Sample Output:
Infix Expression: 3 + 5 * 2
Postfix Expression: 3 5 + 2 *
Prefix Expression: * + 3 5 2
Evaluated Result: 16
preencoded.png
THANK YOU

Introduction---to-Expression---Trees.pdf

  • 1.
    NAME REGISTER NUMBER IDRIS310623105018 NITHIYA PRAKASH 310623105037 DHARINEESH R M 310623105010 EASWARI ENGINEERING COLLEGE GROUP PRESENTATION EXPRESSION TREES DATA STRUCTURES WITH C 231CSS421T GROUP-16 DATE: 26-03-25 SECOND YEAR – IV SEM
  • 2.
    Introduction to Expression ExpressionTrees Expression trees are essential for evaluating mathematical expressions. They follow a hierarchical structure with operators and numerical values. These trees are useful in compiler design and expression simplifications.
  • 3.
    Why Use ExpressionTrees? 1 Efficient Evaluation Preserves the correct order of operations. 2 Compiler Design Converts high-level code into machine instructions. 3 Expression Parsing Eases processing of complex mathematical operations.
  • 4.
    Notations and ExpressionTrees Infix Notation Operators appear between operands (e.g., A + B). Familiar and widely used, but requires parentheses for precedence. Prefix Notation Operators come before their operands.The infix expression "A + B" becomes "+ A B" in prefix notation. Suitable for stack-based computations, evaluates left to right. Postfix Notation Operators are placed after the operands.The infix expression "A + B" becomes "A B +" in postfix notation. Eliminates parentheses by placing operators before operands.
  • 5.
    Structure of an ExpressionTree Binary Tree Leaf nodes represent operands. Internal Nodes Represent operators. Bottom-Up Evaluation Child nodes are processed before parent nodes.
  • 6.
  • 7.
    Constructing an ExpressionTree Parsing the Expression The first step is to break the input expression into tokens (operators and operands). Handle Parentheses Evaluate grouped operations first. Operator Precedence Structure the tree accordingly.
  • 8.
    Implementation in C NodeStructure Define a structure. It should hold data, a left pointer, and a right pointer. Data Field This field stores the operator or operand at each node. It can be extended for more complex data types. Pointers Left and right pointers link each node. They connect to child subtrees. Tree Traversal Recursive traversal ensures proper order. It performs computations using postorder traversal.
  • 9.
    Complete C Program:Expression Tree Implementation #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> // Structure definition for tree nodes typedef struct Node { char data; struct Node *left, *right; } Node; // Function to create a new node Node* createNode(char data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->left = newNode->right = NULL; return newNode; // Stack structure for tree nodes typedef struct Stack { Node* data[100]; // Stack to hold tree nodes int top; } Stack; // Initialize stack void initStack(Stack* stack) { stack->top = -1; } // Push node onto stack void push(Stack* stack, Node* node) { stack->data[++stack->top] = node; } // Pop node from stack Node* pop(Stack* stack) { return stack->data[stack->top--];
  • 10.
    // Function toconstruct an expression tree from postfix expression Node* constructTree(char postfix[]) { Stack stack; initStack(&stack); int i; for (i = 0; i < strlen(postfix); i++) { char ch = postfix[i]; // If operand, create node and push onto stack if (isdigit(ch)) { push(&stack, createNode(ch)); } // If operator, pop two nodes, create subtree, and push back else { Node* newNode = createNode(ch); newNode->right = pop(&stack); newNode->left = pop(&stack); push(&stack, newNode); } } return pop(&stack); // Root node } // Function to evaluate the expression tree using recursion int evaluate(Node* root) { // If leaf node, return the operand if (root->left == NULL && root->right == NULL) return root->data - '0'; // Convert char to int // Evaluate left and right subtrees int leftVal = evaluate(root->left); int rightVal = evaluate(root->right); // Perform the corresponding arithmetic operation switch (root->data) { case '+': return leftVal + rightVal; case '-': return leftVal - rightVal; case '*': return leftVal * rightVal; case '/': return leftVal / rightVal; } return 0; }
  • 11.
    // Inorder traversal(Left -> Root -> Right) void inorder(Node* root) { if (root != NULL) { inorder(root->left); printf("%c ", root->data); inorder(root->right); } } // Postorder traversal (Left -> Right -> Root) void postorder(Node* root) { if (root != NULL) { postorder(root->left); postorder(root->right); printf("%c ", root->data); } } // Preorder traversal (Root -> Left -> Right) void preorder(Node* root) { if (root != NULL) { printf("%c ", root->data); preorder(root->left); preorder(root->right); } } // Main function int main() { char postfix[] = "35+2*"; // Example expression: (3 + 5) * 2 Node* root = constructTree(postfix); printf("Infix Expression: "); inorder(root); printf("n"); printf("Postfix Expression: "); postorder(root); printf("n"); printf("Prefix Expression: "); preorder(root); printf("n"); printf("Evaluated Result: %dn", evaluate(root)); return 0; }
  • 12.
    Sample Output: Infix Expression:3 + 5 * 2 Postfix Expression: 3 5 + 2 * Prefix Expression: * + 3 5 2 Evaluated Result: 16
  • 13.
  • 14.