CS 201 Computer Systems Programming Chapter 7 “Printing Binary Trees” Herbert G. Mayer, PSU CS Status 9/27/2012
Syllabus Arithmetic Expressions and Trees Infix Without Parentheses Infix With Parentheses Postfix Without Parentheses Prefix Without Parentheses Interesting Examples Use of Postfix
Arithmetic Expressions and Trees Three typical notations for dyadic operations: Infix notation: write/process first/left operand, then list the operator, finally the last/right operand Clearly this order will not work for code emission in a compiler. Operator needs both operands available Postfix notation: write/process first/left operand, then list the last/right operand, finally the operator This order will work for code emission, as operator has both operands available at execution time Needs no parentheses, and still obeys operator precedence Postfix AKA Polish Postfix, after Jan Łukasiewicz, 1920 Prefix notation: First list the operator, next the first operand, finally the last/right operand Will also not work for code emission in a compiler Also needs to parentheses, but stacks to handle precedences
Arithmetic Expressions and Trees a + x ^ c Infix: ( a + ( x ^ c ) ) Postfix: a x c ^ + Prefix: + a ^ x c + a ^ x c ^ stands for exponentiation operator, highest precedence
Arithmetic Expressions and Trees ( x – a ) / b Infix: ( ( x – a ) ) / b Postfix: x a – b / Prefix: / - x a b / - b x a
Arithmetic Expressions and Trees a ^ ( b – c ) / d Infix: ( ( a ^ ( b – c ) ) / d ) Postfix: a b c - ^ d / Prefix: / ^ a – b c d / ^ d a - b c
Infix Without Parentheses // Print in infix notation without parentheses ( ) void Print_No_Paren( NodePtr Root ) { // Print_No_Paren if ( Root ) { Print_No_Paren ( Root->Left ); if ( Root->Class == Literal ) { printf( "%d", Root->LitVal ); }else{ printf( "%c", Root->Symbol ); } //end if Print_No_Paren ( Root->Right ); } //end Print_No_Paren Input: ( a + x ) / b prints as: a + x / b misleading
Infix With Parentheses // Print in infix notation with parentheses ( and ) // though prints tooo many ( ) pairs void Print_Infix( NodePtr Root ) { // Print_Infix if ( Root ) { if ( Root->Class == Operator ) { printf( "(" ); } //end if Print_Infix( Root->Left ); if ( Root->Class == Literal ) { printf( "%d", Root->LitVal ); }else{ printf( "%c", Root->Symbol ); Print_Infix( Root->Right ); printf( ")" ); } //end Print_Infix Input: ( a + x ) / b prints as: ( ( a + x ) / b ) -- OK
Postfix Without Parentheses // Print in Polish postfix notation, no parentheses void Print_Postfix( NodePtr Root ) { // Print_Postfix if ( Root ) { Print_Postfix( Root->Left ); Print_Postfix( Root->Right ); if ( Root->Class == Literal ) { printf( "%d", Root->LitVal ); }else{ printf( "%c", Root->Symbol ); } //end if } //end Print_Postfix Input: a ^ ( b – c ) / d prints as: a b c - ^ d / -- OK
Prefix Without Parentheses // Prefix: operator executes when 2 operands found void Print_Prefix( NodePtr Root ) { // Print_Prefix if ( Root ) { if ( Root->Class == Literal ) { printf( "%d", Root->LitVal ); }else{ printf( "%c", Root->Symbol ); } //end if Print_Prefix( Root->Left ); Print_Prefix( Root->Right ); } //end Print_Prefix Input: ( a + x ) / b prints as: / + a x b -- OK
Interesting Examples Input 1: a + b * c ^ ( x – 2 * d ) / ( e – f ) Infix: ( a + ( ( b * ( c ^ ( x – ( 2 * d ) ) ) ) / ( e – f ) ) ) Postfix: a b c x 2 d * - ^ * e f - / + Prefix: + a / * b ^ c – x * 2 d – e f Input 2: 4 / x ^ ( k – l / m ) * 8 * x - & 9 + n Infix: ( ( ( ( ( 4 / ( x ^ ( k - ( l / m ) ) ) ) * 8 ) * x ) - ( & 9 ) ) + n ) Postfix: 4 x k l m / - ^ / 8 * x * 9 & - n + Prefix: + - * * / 4 ^ x – k / l m 8 x & 9 n
Use of Postfix Polish Postfix notation is a natural for code generation targeted for stack machines Operands are needed first: Two for dyadic, or one for monadic operations Once generated and available on stack, execute next operation Easy for compiler writer, natural for stack machine Stack poor for execution, as all references are through memory: top of stack Even a GPR architecture needs both operands available somewhere (in regs) to execute operator
References Łukasiewicz: http://www.calculator.org/Lukasiewicz.aspx http://cslibrary.stanford.edu/110/BinaryTrees.html