Post on 01-Feb-2016
description
1
CS 201Computer Systems Programming
Chapter 7“Printing Binary Trees”
Herbert G. Mayer, PSU CSHerbert G. Mayer, PSU CSStatus 7/9/2014Status 7/9/2014
2
Syllabus Arithmetic Expressions and TreesArithmetic Expressions and Trees
Infix Without ParenthesesInfix Without Parentheses
Infix With ParenthesesInfix With Parentheses
Postfix Without ParenthesesPostfix Without Parentheses
Prefix Without ParenthesesPrefix Without Parentheses
Interesting ExamplesInteresting Examples
Use of PostfixUse of Postfix
3
Arithmetic Expressions and Trees
Three typical notations for dyadic operations:Three typical notations for dyadic operations:
Infix Infix notation: write as the first the left notation: write as the first the left operand, reading left-to-right, then list the operand, reading left-to-right, then list the dyadic operator, finally list the right operanddyadic operator, finally list the right operand
For CPU: Order will not work for code emission, as the CPU needs both operands for processing the operator
For humans: requires parentheses for proper operator precedence
Note exception: programming language APL
PostfixPostfix notation: write left operand first, then notation: write left operand first, then list the right operand, finally the operatorlist the right operand, finally the operator
This order will work for code emission, as operator has both operands available at processing time
Needs no parentheses, and still obeys operator precedence
Postfix notation AKA Polish Postfix, after Jan Łukasiewicz, 1920
PrefixPrefix notation: First list the operator, next the notation: First list the operator, next the first (left) operand, finally the second (right) first (left) operand, finally the second (right) operandoperand
4
Arithmetic Expressions and Treesa + x ^ ca + x ^ c
++
aa ^̂
xx cc
Infix:Infix: ( a + ( x ^ c ( a + ( x ^ c ) )) )
Postfix:Postfix: a x c ^ +a x c ^ +
Prefix:Prefix: + a ^ x c+ a ^ x c
^ ^ stands for exponentiation operator, with highest precedence: stands for exponentiation operator, with highest precedence:
higher than higher than ** or or // which in turn have higher priority than which in turn have higher priority than ++ or or --
5
Arithmetic Expressions and Trees( x – a ) / b( x – a ) / b
//
-- bb
aaxx
Infix:Infix: ( ( x – ( ( x – a ) / b )a ) / b )
Postfix:Postfix: x a – b /x a – b /
Prefix:Prefix: / – x a b / – x a b
/ / stands for division operator, with higher precedence stands for division operator, with higher precedence than, say, than, say, ––
6
Arithmetic Expressions and Treesa ^ ( b – c ) / da ^ ( b – c ) / d
//
^̂ dd
--aa
Infix:Infix: ( ( a ^ ( b – ( ( a ^ ( b – c ) ) / d )c ) ) / d )
Postfix:Postfix: a b c - ^ a b c - ^ d /d /
Prefix:Prefix: / ^ a – b c d/ ^ a – b c d
Wrong: a ^ ( ( b – Wrong: a ^ ( ( b – c ) / d )c ) / d )
bb cc
7
Data Structure to Print Trees
Express tree and printing it via a C programExpress tree and printing it via a C program
To do so, define a NodeType data structureTo do so, define a NodeType data structure
Thus a node needs to haver operand operator Thus a node needs to haver operand operator classification, and 2 possible subtreesclassification, and 2 possible subtrees
For practical purposes, distinguish literals For practical purposes, distinguish literals from variable (i.e. symbolic names)from variable (i.e. symbolic names)
Represent the arithmetic expression as tree Represent the arithmetic expression as tree of such nodesof such nodes
And define functions that traverse the tree And define functions that traverse the tree and print operands and operators in the and print operands and operators in the right orderright order
8
Data Structure to Print Trees// node has class: literal, identifier, or operator.// node has class: literal, identifier, or operator.
// Parenthesized expressions have been reduced: no ( )// Parenthesized expressions have been reduced: no ( )
typedef enum { Literal, Identifier, Operator } NodeClass;typedef enum { Literal, Identifier, Operator } NodeClass;
typedef struct NodeType * NodePtr; // forwardtypedef struct NodeType * NodePtr; // forward
// actual node structure; using the forward pointers// actual node structure; using the forward pointers
typedef struct NodeTypetypedef struct NodeType
{{
NodeClass Class; // 3 classes. NodeClass Class; // 3 classes. Not C++ ‘class’Not C++ ‘class’
char Symbol; // stores ident or small literalchar Symbol; // stores ident or small literal
int LitVal; // if Class == Literal: its valueint LitVal; // if Class == Literal: its value
NodePtr Left; // left subtreeNodePtr Left; // left subtree
NodePtr Right; // right subtreeNodePtr Right; // right subtree
} s_node_tp;} s_node_tp;
9
Infix Without Parentheses// Print in infix notation without parentheses ( )// Print in infix notation without parentheses ( )void Print_No_Paren( NodePtr Root )void Print_No_Paren( NodePtr Root ){ // Print_No_Paren{ // Print_No_Paren
if ( Root ) {if ( Root ) {Print_No_Paren ( Root->Left );Print_No_Paren ( Root->Left );if ( Root->Class == Literal ) {if ( Root->Class == Literal ) {
printf( "%d", Root->LitVal );printf( "%d", Root->LitVal );}else{}else{
printf( "%c", Root->Symbol );printf( "%c", Root->Symbol );} //end if} //end ifPrint_No_Paren ( Root->Right );Print_No_Paren ( Root->Right );
} //end if} //end if} //end Print_No_Paren} //end Print_No_Paren
Input: Input: ( a + x ) / b( a + x ) / b prints as: prints as: a + x / ba + x / b misleadingmisleading
10
Infix With Parentheses// Print in infix notation with parentheses ( and )// Print in infix notation with parentheses ( and )// though prints too many ( ) pairs// though prints too many ( ) pairsvoid Print_Infix( NodePtr Root )void Print_Infix( NodePtr Root ){ // Print_Infix{ // Print_Infix
if ( Root ) {if ( Root ) {
if ( Root->Class == Operator ) { if ( Root->Class == Operator ) { printf( "(" );printf( "(" );
} //end if} //end ifPrint_Infix( Root->Left );Print_Infix( Root->Left );if ( Root->Class == Literal ) {if ( Root->Class == Literal ) {
printf( "%d", Root->LitVal );printf( "%d", Root->LitVal );}else{}else{
printf( "%c", Root->Symbol );printf( "%c", Root->Symbol );} //end if} //end ifPrint_Infix( Root->Right );Print_Infix( Root->Right );
if ( Root->Class == Operator ) {if ( Root->Class == Operator ) {printf( ")" );printf( ")" );
} //end if} //end if} //end if} //end if
} //end Print_Infix} //end Print_Infix
Input: Input: ( a + x ) / b( a + x ) / b prints as: prints as: ( ( a + x ) / ( ( a + x ) / b )b ) -- -- OKOK
11
Postfix Without Parentheses// Print in // Print in Polish Postfix Polish Postfix notation, no parenthesesnotation, no parenthesesvoid Print_Postfix( NodePtr Root )void Print_Postfix( NodePtr Root ){ // Print_Postfix{ // Print_Postfix
if ( Root ) {if ( Root ) {Print_PostfixPrint_Postfix( Root->Left );( Root->Left );Print_PostfixPrint_Postfix( Root->Right );( Root->Right );if ( Root->Class == Literal ) {if ( Root->Class == Literal ) {
printf( "%d", Root->LitVal );printf( "%d", Root->LitVal );}else{}else{
printf( "%c", Root->Symbol );printf( "%c", Root->Symbol );} //end if} //end if
} //end if} //end if} //end Print_Postfix} //end Print_Postfix
Input: Input: a ^ ( b – c ) / da ^ ( b – c ) / d prints as: prints as: a b c - ^ d a b c - ^ d / / -- -- OKOK
12
Prefix Without Parentheses// Prefix: operator executes when 2 operands found// Prefix: operator executes when 2 operands found
void Print_Prefix( NodePtr Root )void Print_Prefix( NodePtr Root )
{ // Print_Prefix{ // Print_Prefix
if ( Root ) {if ( Root ) {
if ( Root->Class == Literal ) {if ( Root->Class == Literal ) {
printf( "%d", Root->LitVal );printf( "%d", Root->LitVal );
}else{}else{
printf( "%c", Root->Symbol );printf( "%c", Root->Symbol );
} //end if} //end if
Print_PrefixPrint_Prefix( Root->Left );( Root->Left );
Print_PrefixPrint_Prefix( Root->Right );( Root->Right );
} //end if} //end if
} //end Print_Prefix} //end Print_Prefix
Input: Input: ( a + x ) / b( a + x ) / b prints as: prints as: / + a x b/ + a x b -- -- OKOK
13
Interesting Examples
Input 1:Input 1: a + b * c ^ ( x – 2 * d ) / ( e – f )a + b * c ^ ( x – 2 * d ) / ( e – f )
Infix:Infix: ( a + ( ( b * ( c ^ ( x – ( 2 * d ) ) ) ( a + ( ( b * ( c ^ ( x – ( 2 * d ) ) ) ) / ( e – f ) ) )) / ( e – f ) ) )
Postfix:Postfix: a b c x 2 d * - ^ * e f - / + a b c x 2 d * - ^ * e f - / +
Prefix:Prefix: + a / * b ^ c – x * 2 d – e f+ a / * b ^ c – x * 2 d – e f
Input 2:Input 2: 4 / x ^ ( k – l / m ) * 8 * x - & 9 + n4 / x ^ ( k – l / m ) * 8 * x - & 9 + n
Infix:Infix: ( ( ( ( ( 4 / ( x ^ ( k - ( l / ( ( ( ( ( 4 / ( x ^ ( k - ( l / m ) ) ) ) * 8 ) * x ) - ( & 9 ) ) + n )m ) ) ) ) * 8 ) * x ) - ( & 9 ) ) + n )
Postfix:Postfix: 4 x k l m / - ^ / 8 * x * 9 & - n +4 x k l m / - ^ / 8 * x * 9 & - n +
Prefix:Prefix: + - * * / 4 ^ x – k / l m 8 x & 9 n+ - * * / 4 ^ x – k / l m 8 x & 9 n
14
Use of Postfix Postfix, Postfix, AKA AKA Polish Postfix Polish Postfix notation is a notation is a
natural for code generation, not just for stack natural for code generation, not just for stack machinesmachines
Operands are needed first: Two for Operands are needed first: Two for dyadicdyadic, or , or one for one for monadicmonadic operations operations
Once generated and available on stack, stack Once generated and available on stack, stack machine can execute the next operationmachine can execute the next operation
Easy for compiler writer, natural for stack Easy for compiler writer, natural for stack machinemachine
Stack poor for execution, as all references are Stack poor for execution, as all references are through memory: top of stackthrough memory: top of stack
Even a GPR architecture needs both operands Even a GPR architecture needs both operands available somewhere (in regs) to execute available somewhere (in regs) to execute operatoroperator
15
References ŁukasiewiczŁukasiewicz: :
http://www.calculator.org/Lukasiewicz.ashttp://www.calculator.org/Lukasiewicz.aspxpx
http://cslibrary.stanford.edu/110/http://cslibrary.stanford.edu/110/BinaryTrees.htmlBinaryTrees.html