1 cs 410 mastery in programming chapter 8 printing binary trees herbert g. mayer, psu cs status...

Post on 14-Dec-2015

222 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

CS 410Mastery in Programming

Chapter 8Printing Binary Trees

Herbert G. Mayer, PSU CSHerbert G. Mayer, PSU CSStatus 5/22/2013Status 5/22/2013

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 operand, reading left-to-notation: write as the first the left operand, reading left-to-right, then list the dyadic operator, finally list the right operandright, then list the dyadic 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 list the right notation: write left operand first, then list the right operand, finally the operatoroperand, 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 first (left) notation: First list the operator, next the first (left) operand, finally the second (right) operandoperand, finally the second (right) operand

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: higher than stands for exponentiation operator, with highest precedence: higher than ** or or //

5

Arithmetic Expressions and Trees

( x – a ) / b( x – a ) / b

//

-- bb

aaxx

Infix:Infix: ( ( x – a ) ) / b( ( x – 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 than, say, stands for division operator, with higher precedence than, say, ––

6

Arithmetic Expressions and Trees

a ^ ( b – c ) / da ^ ( b – c ) / d

//

^̂ dd

--aa

Infix:Infix: ( ( a ^ ( b – c ) ) / d )( ( a ^ ( b – c ) ) / d )

Postfix:Postfix: a b c - ^ d /a b c - ^ d /

Prefix:Prefix: / ^ a – b c d/ ^ a – b c d

bb cc

7

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;

8

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 misleading misleading

9

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 ) / b )( ( a + x ) / b ) -- -- OKOK

10

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

11

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

12

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 ) ) ) ) / ( e – f ) ) )( a + ( ( b * ( c ^ ( x – ( 2 * d ) ) ) ) / ( 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 / m ) ) ) ) * 8 ) * x ) - ( & 9 ) ) + n )( ( ( ( ( 4 / ( x ^ ( k - ( l / 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

13

Use of Postfix Postfix, Postfix, AKA AKA Polish Postfix Polish Postfix notation is a natural for notation is a natural for

code generation, targeted for stack machinescode generation, targeted for stack machines

Operands are needed first: Two for Operands are needed first: Two for dyadicdyadic, or one , or one for 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 machineEasy for compiler writer, natural for stack machine

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 operatoravailable somewhere (in regs) to execute operator

14

References ŁukasiewiczŁukasiewicz: :

http://www.calculator.org/Lukasiewicz.aspxhttp://www.calculator.org/Lukasiewicz.aspx

http://cslibrary.stanford.edu/110/BinaryTrees.htmlhttp://cslibrary.stanford.edu/110/BinaryTrees.html

top related