How to do different traversals of an expression tree?

Tim Chaffin :

I'm trying to figure out how to do the different traversals through an expression tree. For example, if I type in " - + 10 * 2 8 3 ", I want it to print out the prefix, postfix, and infix versions of that expression.

I also need to calculate the result of the expression through a postorder traversal, which should be the evaluate function.

However, when I run my program, I only get the first character of each expression. Is my understanding of how these traversals work wrong?

EDIT: Following suggestions, I saved the result of the buildtree and also changed sc.next to sc.nextLine.

Also, every method should be recursive.

Given "- + 10 * 2 8 3", the expected answer would be:

prefix expression:
- + 10 * 2 8 3
postfix expression:
10 2 8 * + 3 -
infix expression:
( ( 10 + ( 2 * 8 ) ) - 3 )
Result = 23

I understand I haven't implemented anything with parentheses for the infix expression, but that's okay for now.

public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Enter a prefix expression: ");

        Node root = buildTree(sc);

        System.out.println("prefix expression: ");
        infix(root);

        System.out.println("postfix expression: ");
        postfix(root);

        System.out.println("infix expression: ");   
        infix(root);

        System.out.print("Result = ");
        evaluate(root);
    }

    static Node buildTree(Scanner sc) {
        Node n = new Node(null);
        int i = 0;
        String prefixExpression  = sc.nextLine();
        String[] temp = prefixExpression.split(" ");

        if(n.isLeaf()) {

            n.value = temp[i];
            n.left = null;
            n.right = null;

            i++;

        }

        return n;
    }

    static void infix(Node node) {

        if(node.isLeaf()){
            System.out.println(node.value);
        }

        else {
            infix(node.left);
            System.out.println(node.value + " ");
            infix(node.right);
        }

    }

    void prefix(Node node) {

        if(node.isLeaf()){
            System.out.println(node.value);
        }
        else {
            switch(node.value) {
            case "+":
                System.out.print("+");
                break;
            case "-":
                System.out.print("-");
                break;
            case "*":
                System.out.print("*");
                break;
            case "/":
                System.out.print("/");
                break;
            }
        }

        prefix(node.left);
        System.out.print(" ");
        prefix(node.right);

    }

    static void postfix(Node node) {

        if(node.isLeaf()){
            System.out.println(node.value);
        }
        else {
            postfix(node.left);
            postfix(node.right);

            switch (node.value) {
            case "+":
                System.out.print("+");
                break;
            case "-":
                System.out.print("-");
                break;
            case "*":
                System.out.print("*");
                break;
            case "/":
                System.out.print("/");
                break;
            }
        }

    }

    public static int evaluate(Node node) {

        if(node.isLeaf()) {
            return Integer.parseInt(node.value);
        }

        else {
            int leftHandSide = evaluate(node.getLeft());
            int rightHandSide = evaluate(node.getRight());
            String operator = node.getValue();

            if("+".equals(operator)) {
                return leftHandSide + rightHandSide;
            }
            else if("-".equals(operator)) {
                return leftHandSide - rightHandSide;
            }
            else if("*".equals(operator)) {
                return leftHandSide * rightHandSide;
            }
            else if("/".equals(operator)) {
                return leftHandSide / rightHandSide;
            }
            else {
                System.out.println("Unexpected problem. Error.");
            }

            return 0;

        }
    }

}

Here is Node.java, There's getters and setters too.

public class Node<E> {

    String value;
    Node<E> left;
    Node<E> right;

    Node(String value){
        left = null;
        right = null;
        this.value = value;
    }

    Node(String value, Node<E> left, Node<E> right) {
        this.value = value;
        this.left = left;
        this.right = right;
    }

    boolean isLeaf() {

        return (left == null && right == null);

    }
MOnkey :

EDIT:

Since your question says "How to do different traversals of an expression tree?, The problem I can see in your code is building the tree ( i.e. buildTree() method).

In order to correct this, I have used buildExpressionTree(array) method to convert your prefix input to an expression tree using Stack data structure.

Construction of Expression Tree:

For constructing expression tree I have use a stack. Since in your case input is in prefix form so Loop in reverse through input expression and do following for every character.

  1. If character is operand push that into stack
  2. If character is operator pop two values from stack make them its child and push current node again.

At the end only element of stack will be root of expression tree.

Also while printing different traversals, you do not need all those if conditions to check for different operators.You can simply do the traversal as shown in my code below.

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    System.out.println("Enter a prefix expression: ");

    String prefixExpression  = sc.nextLine();
    String[] temp = prefixExpression.split(" ");
    Node n = null; 

    n = buildExpressionTree(temp);

    System.out.println("prefix expression: ");

    prefix(n);

    System.out.println();
    System.out.println("postfix expression: ");

    postfix(n);

    System.out.println();
    System.out.println("infix expression: ");

    infix(n);

    System.out.println();

    int result = evaluate(n);
    System.out.print("Result = "+ result);

}

static Node buildExpressionTree(String[] input) { 
    Stack<Node> st = new Stack(); 
    Node t, t1, t2; 
    // Traverse through every character of 
    // input expression 
    for (int i = (input.length-1); i >= 0; i--) { 

        // If operand, simply push into stack 
        if (isNumber(input[i])) { 
            t = new Node(input[i]); 
            st.push(t); 
        } else // operator 
        { 
            t = new Node(input[i]); 

            // Pop two top nodes 
            // Store top 
            t1 = st.pop();      // Remove top 
            t2 = st.pop(); 

            //  make them children 
            t.left = t1; 
            t.right = t2; 

            st.push(t); 
        } 
    } 

    t = st.peek(); 
    st.pop(); 

    return t; 
}

static boolean isNumber(String s) {

    boolean numeric = true;
    try {
        Integer num = Integer.parseInt(s);
    } catch (NumberFormatException e) {
        numeric = false;
    }
    return numeric;
}



static void infix(Node node) {

    if( null == node) {
        return;
    }
    infix(node.left);
    System.out.print(node.value + " ");
    infix(node.right);
}

static void prefix(Node node) {

    if( null == node) {
        return;
    }
    System.out.print(node.value+ " ");
    prefix(node.left);
    prefix(node.right);

}

static void postfix(Node node) {

    if( null == node) {
        return;
    }
    postfix(node.left);
    postfix(node.right);
    System.out.print(node.value+ " ");

}

public static int evaluate(Node node) {

    if(node.isLeaf()) {
        return Integer.parseInt(node.value);
    }

    else {
        int leftHandSide = evaluate(node.left);
        int rightHandSide = evaluate(node.right);
        String operator = node.value;

        if("+".equals(operator)) {
            return leftHandSide + rightHandSide;
        }
        else if("-".equals(operator)) {
            return leftHandSide - rightHandSide;
        }
        else if("*".equals(operator)) {
            return leftHandSide * rightHandSide;
        }
        else if("/".equals(operator)) {
            return leftHandSide / rightHandSide;
        }
        else {
            System.out.println("Unexpected problem. Error.");
        }

        return 0;

    }
}

OUTPUT:

Enter a prefix expression: 
- + 10 * 2 8 3
prefix expression: 
- + 10 * 2 8 3 
postfix expression: 
10 2 8 * + 3 - 
infix expression: 
10 + 2 * 8 - 3 
Result = 23 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=347964&siteId=1