Create an Expression Tree from a Valid Algebraic Expression

packagecsu.matos;

importjava.util.Stack;

importjava.util.StringTokenizer;

publicclass Driver {

/**

* GOAL: 1. Parse an arithmetical expression. 2. Create an equivalent

* 'binary expression tree' 3. Traverse the tree in 'Post-Order', 'In-Order'

*

*/

Stack<Node<Character> stack = new Stack<Node<Character>();

publicstaticvoid main(String[] args) {

// Provide a correct infix expression to be converted

String expression = "(1+3/4*5-6)-7";

try {

String postfixExp = infixToPostfix(expression);

System.out.println(postfixExp);

Node<String> root = evaluateExpression(postfixExp);

Tree<String> tree = new Tree<String>(root);

tree.printTree();

System.out.println("BFS");

tree.bfs();

System.out.println("INORDER");

tree.inOrder(root);

System.out.println("POSTORDER");

tree.postOrder(root);

System.out.println("PRE-ORDER");

tree.preOrder(root);

} catch (Exception ex) {

System.out.println("Wrong expression");

}

}

// ------

publicstatic Node<String> evaluateExpression(String postfixExp) {

// CreateoperandStack to store operands

Stack<Node<String> operandStack = new Stack<Node<String>();

// Extract operands and operators

StringTokenizertokens = newStringTokenizer(postfixExp, " +-/*%", true);

// Phase 1: Scan tokens

Node<String> root = null;

while (tokens.hasMoreTokens()) {

String token = tokens.nextToken().trim(); // Extract a token

if (token.length() == 0) { // Blank space

continue; // Back to the while loop to extract the next token

} elseif (token.charAt(0) == '+' || token.charAt(0) == '-'

|| token.charAt(0) == '*' || token.charAt(0) == '/') {

root = processAnOperator(token.charAt(0), operandStack);

} else{ // An operand scanned

// Push an operand to the stack

root = operandStack.push(new Node<String>(token));

}

}

// Return the result

returnroot;

}

// Process one operator: Take an operator from operatorStack and

// apply it on the operands in the operandStack

publicstatic Node<String> processAnOperator(charop, Stack<Node<String> operandStack) {

Node<String> operatorNode = null;

if (op == '+') {

operatorNode = connectArgs2Operator("+", operandStack);

} elseif (op == '-') {

operatorNode = connectArgs2Operator("-", operandStack);

} elseif ((op == '*')) {

operatorNode = connectArgs2Operator("*", operandStack);

} elseif (op == '/') {

operatorNode = connectArgs2Operator("/", operandStack);

}

returnoperatorNode;

}//processAnOperator

// ------

privatestatic Node<String> connectArgs2Operator(

String operatorSymbol,

Stack<Node<String> operandStack) {

Node<String> rightArg = operandStack.pop();

Node<String> leftArg = operandStack.pop();

Node<String> operatorNode = new Node<String> (operatorSymbol);

operatorNode.setLeft(leftArg);

operatorNode.setRight(rightArg);

operandStack.push(operatorNode);

returnoperatorNode;

}

// ------

// use this method to convert from infix to postfix

publicstatic String infixToPostfix(String expression) {

// Result string

String s = "";

// CreateoperatorStack to store operators

Stack<Character> operatorStack = new Stack<Character>();

// Extract operands and operators

StringTokenizertokens = newStringTokenizer(expression, "()+-/*%",

true);

// Phase 1: Scan tokens

while (tokens.hasMoreTokens()) {

String token = tokens.nextToken().trim(); // Extract a token

if (token.length() == 0) { // Blank space

continue; // Back to the while loop to extract the next token

} elseif (token.charAt(0) == '+' || token.charAt(0) == '-') {

// remove all +, -, *, / on top of the operator stack

while (!operatorStack.isEmpty()

& (operatorStack.peek().equals('+')

|| operatorStack.peek().equals('-')

|| operatorStack.peek().equals('*') || operatorStack

.peek().equals('/'))) {

s += operatorStack.pop() + " ";

}

// push the incoming + or - operator into the operator stack

operatorStack.push(new Character(token.charAt(0)));

} elseif (token.charAt(0) == '*' || token.charAt(0) == '/') {

// remove all *, / on top of the operator stack

while (!operatorStack.isEmpty()

& (operatorStack.peek().equals('*') || operatorStack

.peek().equals('/'))) {

s += operatorStack.pop() + " ";

}

// Push the incoming * or / operator into the operator stack

operatorStack.push(new Character(token.charAt(0)));

} elseif (token.trim().charAt(0) == '(') {

operatorStack.push(new Character('(')); // Push '(' to stack

} elseif (token.trim().charAt(0) == ')') {

// remove all the operators from the stack until seeing '('

while (!operatorStack.peek().equals('(')) {

s += operatorStack.pop() + " ";

}

operatorStack.pop(); // Pop the '(' symbol from the stack

} else{ // An operand scanned

// Push an operand to the stack

s += token + " ";

}

}

// Phase 2: remove the remaining operators from the stack

while (!operatorStack.isEmpty()) {

s += operatorStack.pop() + " ";

}

// Return the result

returns;

}// main

}

NODE

packagecsu.matos;

publicclass Node<E extends Comparable<E> > {

Node<E> left;

Node<E> right;

E data;

public Node( E data ) {

super();

this.left = null;

this.right = null;

this.data = data;

}

public Node<E> getLeft() {

returnleft;

}

publicvoidsetLeft(Node<E> left) {

this.left = left;

}

public Node<E> getRight() {

returnright;

}

publicvoidsetRight(Node<E> right) {

this.right = right;

}

public E getData() {

returndata;

}

publicvoidsetData(E data) {

this.data = data;

}

// use only for DEBUGGING

publicvoidprintNode() {

String result= (this)

+ ": Node ["+ " data=" + data

+ ",\t left=" + (left)

+ ",\t right=" + (right)

+ "]";

System.out.println(result );

}

}

TREE

packagecsu.matos;

importjava.util.LinkedList;

importjava.util.Queue;

publicclass Tree <E extends Comparable<E> >{

publicvoidprintTree() {

System.out.println("Tree [root=" + root + "]" );

}

Node<E> root;

public Tree() {

this.root= null;

}

public Tree(Node<E> root) {

this.root= root;

}

public Node<E> getRoot() {

returnroot;

}

publicvoidsetRoot(Node<E> root) {

this.root = root;

}

//------

publicvoidaddNode( E data ){

Node<E> newNode = new Node<E>(data );

if ( root == null ){

root = newNode;

return;

}

Node<E> ptr = root;

Node<E> parent = null;

booleancomingFromLeft = true;

while(ptr != null ){

parent = ptr;

if ( ptr.getData().compareTo(newNode.getData()) > 0) {

ptr = ptr.getLeft();

comingFromLeft = true;

}else {

ptr = ptr.getRight();

comingFromLeft = false;

}

}//while

if(comingFromLeft ){

parent.setLeft(newNode );

} else {

parent.setRight(newNode );

}

}//addNode

publicvoidinOrder(Node<E> ptr ){

if ( ptr != null ){

inOrder(ptr.getLeft() );

ptr.printNode();

inOrder(ptr.getRight() );

}

}

publicvoidpreOrder(Node<E> ptr ){

if ( ptr != null ){

ptr.printNode();

preOrder(ptr.getLeft() );

preOrder(ptr.getRight() );

}

}

publicvoidpostOrder(Node<E> ptr ){

if ( ptr != null ){

postOrder(ptr.getLeft() );

postOrder(ptr.getRight() );

ptr.printNode();

}

}

public Node<E> find (E searchValue){

Node<E> ptr = root;

while(ptr != null ){

if(ptr.getData().compareTo(searchValue) == 0 ){

returnptr;

}

if(ptr.getData().compareTo(searchValue) > 0 ){

ptr = ptr.getLeft();

}else {

ptr = ptr.getRight();

}

}

returnnull;

}//find

// ------

publicvoidbfs(){

System.out.print("\nBFS\n");

Queue<Node<E> queue = newLinkedList<Node<E>();

queue.add(root);

while ( !queue.isEmpty() ){

Node<E> ptr = queue.remove();

//System.out.print(ptr.getData() + ", ");

ptr.printNode();

if ( ptr.getLeft()!= null ) queue.add(ptr.getLeft() );

if ( ptr.getRight()!= null ) queue.add(ptr.getRight() );

}

}

}//class

CONSOLE

1 3 4 / 5 * + 6 - 7 -

Tree [root=csu.matos.Node@19d1b44b]

BFS

BFS

csu.matos.Node@19d1b44b: Node [ data=-, left=csu.matos.Node@2dd7e4d6, right=csu.matos.Node@38f0b51d]

csu.matos.Node@2dd7e4d6: Node [ data=-, left=csu.matos.Node@4302a01f, right=csu.matos.Node@615e7597]

csu.matos.Node@38f0b51d: Node [ data=7, left=null, right=null]

csu.matos.Node@4302a01f: Node [ data=+, left=csu.matos.Node@7a3e72, right=csu.matos.Node@5999ae9c]

csu.matos.Node@615e7597: Node [ data=6, left=null, right=null]

csu.matos.Node@7a3e72: Node [ data=1, left=null, right=null]

csu.matos.Node@5999ae9c: Node [ data=*, left=csu.matos.Node@7896b1b8, right=csu.matos.Node@6d6de4e1]

csu.matos.Node@7896b1b8: Node [ data=/, left=csu.matos.Node@49cda7e7, right=csu.matos.Node@5cca548b]

csu.matos.Node@6d6de4e1: Node [ data=5, left=null, right=null]

csu.matos.Node@49cda7e7: Node [ data=3, left=null, right=null]

csu.matos.Node@5cca548b: Node [ data=4, left=null, right=null]

INORDER

csu.matos.Node@7a3e72: Node [ data=1, left=null, right=null]

csu.matos.Node@4302a01f: Node [ data=+, left=csu.matos.Node@7a3e72, right=csu.matos.Node@5999ae9c]

csu.matos.Node@49cda7e7: Node [ data=3, left=null, right=null]

csu.matos.Node@7896b1b8: Node [ data=/, left=csu.matos.Node@49cda7e7, right=csu.matos.Node@5cca548b]

csu.matos.Node@5cca548b: Node [ data=4, left=null, right=null]

csu.matos.Node@5999ae9c: Node [ data=*, left=csu.matos.Node@7896b1b8, right=csu.matos.Node@6d6de4e1]

csu.matos.Node@6d6de4e1: Node [ data=5, left=null, right=null]

csu.matos.Node@2dd7e4d6: Node [ data=-, left=csu.matos.Node@4302a01f, right=csu.matos.Node@615e7597]

csu.matos.Node@615e7597: Node [ data=6, left=null, right=null]

csu.matos.Node@19d1b44b: Node [ data=-, left=csu.matos.Node@2dd7e4d6, right=csu.matos.Node@38f0b51d]

csu.matos.Node@38f0b51d: Node [ data=7, left=null, right=null]

POSTORDER

csu.matos.Node@7a3e72: Node [ data=1, left=null, right=null]

csu.matos.Node@49cda7e7: Node [ data=3, left=null, right=null]

csu.matos.Node@5cca548b: Node [ data=4, left=null, right=null]

csu.matos.Node@7896b1b8: Node [ data=/, left=csu.matos.Node@49cda7e7, right=csu.matos.Node@5cca548b]

csu.matos.Node@6d6de4e1: Node [ data=5, left=null, right=null]

csu.matos.Node@5999ae9c: Node [ data=*, left=csu.matos.Node@7896b1b8, right=csu.matos.Node@6d6de4e1]

csu.matos.Node@4302a01f: Node [ data=+, left=csu.matos.Node@7a3e72, right=csu.matos.Node@5999ae9c]

csu.matos.Node@615e7597: Node [ data=6, left=null, right=null]

csu.matos.Node@2dd7e4d6: Node [ data=-, left=csu.matos.Node@4302a01f, right=csu.matos.Node@615e7597]

csu.matos.Node@38f0b51d: Node [ data=7, left=null, right=null]

csu.matos.Node@19d1b44b: Node [ data=-, left=csu.matos.Node@2dd7e4d6, right=csu.matos.Node@38f0b51d]

PRE-ORDER

csu.matos.Node@19d1b44b: Node [ data=-, left=csu.matos.Node@2dd7e4d6, right=csu.matos.Node@38f0b51d]

csu.matos.Node@2dd7e4d6: Node [ data=-, left=csu.matos.Node@4302a01f, right=csu.matos.Node@615e7597]

csu.matos.Node@4302a01f: Node [ data=+, left=csu.matos.Node@7a3e72, right=csu.matos.Node@5999ae9c]

csu.matos.Node@7a3e72: Node [ data=1, left=null, right=null]

csu.matos.Node@5999ae9c: Node [ data=*, left=csu.matos.Node@7896b1b8, right=csu.matos.Node@6d6de4e1]

csu.matos.Node@7896b1b8: Node [ data=/, left=csu.matos.Node@49cda7e7, right=csu.matos.Node@5cca548b]

csu.matos.Node@49cda7e7: Node [ data=3, left=null, right=null]

csu.matos.Node@5cca548b: Node [ data=4, left=null, right=null]

csu.matos.Node@6d6de4e1: Node [ data=5, left=null, right=null]

csu.matos.Node@615e7597: Node [ data=6, left=null, right=null]

csu.matos.Node@38f0b51d: Node [ data=7, left=null, right=null]