Review

Lecture P5: Abstract Data Types :

Set of values and collection of operations on those values.

Example: int

Set of values: between -32,767 and 32,767 (minimum limits).

Operations: +, -, *, /, %, printf("%d"), sqrt

How is an int represented? multiply 16 ? negative integers? shouldn't care! add int print

...

2

Overview "Non ADT’s"

Is Rational data type an ? Separate implementation from specification. No: Representation in . INTERFACE: specify the allowed operations. Client can directly manipulate the data type: a.num = 5; IMPLEMENTATION: provide code for operations.

CLIENT: code that uses operations. RAT.h client.

Abstract data type (ADT): typedef struct { #include "RAT.h" int num; Data type whose representation is HIDDEN. int den; int main(void) { Don’t want client to directly manipulate data type. } Rational; Rational a;

Operations ONLY permitted through interface. legal C, but very bad a.num = 5; Rational RATadd(Rationalsoftware a, Rational design b); a.den = 8; Rational RATmul(Rational a, Rational b); RATshow(a); Principle of least privilege. Rational RATshow(Rational a); return 0; Rational RATinit(int x, int y); }

Violates "principle of least privilege."

3 6 ADT's for Stacks and Queues Stack Interface

Fundamental data type. Stack operations.

Set of operations (insert, delete) on generic data. STACKinit(): initialize empty stack

STACKisempty(): return 1 if stack is empty; 0 otherwise

Stack ("last in first out" or LIFO). STACKpush(int): insert new item

push: add info to the STACKpop(): delete and return item most recently added

pop: remove the info MOST recently added

initialize, test if empty STACK.h

Queue ("first in first out" or FIFO). void STACKinit(void); put: add info to the data structure int STACKisempty(void);

get: remove the info LEAST recently added void STACKpush(int item);

initialize, test if empty int STACKpop(void);

Could use EITHER array or "linked list" to implement EITHER stack or queue.

7 9

Stack Implementation with Arrays Stack Client: Balanced Parentheses

stackarray.c Push and pop at the end of array. par.c #include "STACK.h" #include Demo: #define MAX_SIZE 1000 #include "STACK.h" static int s[MAX_SIZE]; static int N; int main(void) { int c, balanced = 1; void STACKinit(void) { STACKinit(); N=0; } . . . /* MAIN CODE HERE */

int STACKisempty(void) { if (balanced) return N == 0; printf("Balanced.\n"); } else printf("NOT Balanced.\n"); void STACKpush(int item) { s[N] = item; N++; s[N++] = item; return 0; } } int STACKpop(void) { N--; Good: ((()())) return s[N]; return s[--N]; Bad: (()))(()

} 10 12 Stack Client: Balanced Parentheses Stack Client: Balanced Parentheses

par.c (cont) Check if your C program has unbalanced parentheses.

stop loop if unbalanced Read from stdin Unix % gcc par.c stackarray.c while (balanced && (c = getchar()) != EOF) { % a.out < myprog.c if ( c == '(' ) balanced STACKpush(c); push left parentheses else if ( c == ')' ) { % a.out < someprogram.c if (STACKisempty()) check for matching unbalanced balanced = 0; left parenthesis else How could valid C program have STACKpop(); unbalanced parentheses? } } if (!STACKisempty()) balanced if empty stack balanced = 0; when no more input Exercise: extend to handle square and curly braces.

Good: {([([])()])}

Good: ((()())) Bad: (([)]) Bad: (()))(()

13 14

Stack Client: Postfix Evaluation Stack Client: Postfix Evaluation

Practical example of use of stack abstraction. Practical example of use of stack abstraction.

Put operator after operands in expression. Put operator after operands in expression.

Use stack to evaluate. Use stack to evaluate. – operand: push it onto stack. – operand: push it onto stack. – operator: pop operands, push result. – operator: pop operands, push result.

Systematic way to save intermediate results. Systematic way to save intermediate results.

Example 1. Example 2a: convert 27531 from octal to decimal.

12345*+6**789++*+ 28888****7888***588**38*1++++

Example 2b: convert 27531 from octal to decimal.

28*7+8*5+8*3+8*1+

Stack never has more than two numbers on it!

Horner’s method (see lecture P2).

15 17 Stack Client: Postfix Evaluation Stack Client: Postfix Evaluation

postfix.c Program has some flaws. Unix #include #include 2+5 % gcc postfix.c stackarray.c #include "STACK.h" 16 12 + % a.out 24+ int main(void) { top of stack = 6 int c; STACKinit(); % a.out while ((c = getchar()) != EOF) { 12345*+6**789++* if ('+' == c) top of stack = 6624 pop 2 elements STACKpush(STACKpop() + STACKpop()); and push sum else if ('*' == c) % a.out STACKpush(STACKpop() * STACKpop()); 598+46**7+* else if (isdigit(c)) convert char to top of stack = 2075 STACKpush(c - '0'); integer and push } % a.out 28*7+8*5+8*3+8*1+ printf("top of stack = %d\n", STACKpop()); top of stack = 12121 return 0; }

18 19

Stack Client: Infix to Postfix ADT Review

Unix infix2postfix.c Client can access data type ONLY through interface.

% gcc infix2postfix.c ... #include Example: STACK. % a.out #include (2 + ((3 + 4) * (5 * 6))) #include "STACK.h" Representation is HIDDEN in the implementation. 234+56**+ int main(void) { Provides security. int c; Infix to postfix algorithm: STACKinit(); Convenient way to organize large problems.

while ((c = getchar()) != EOF) { Left paren: ignore. Decompose into smaller problems. if (c == ')')

Right paren: pop and print. Substitute alternate solutions (time / space tradeoffs). printf("%c ", STACKpop()); Separation compilation. Operator: push. else if (c == '+' || c == '*') Build libraries. Digit: print. STACKpush(c); else if (isdigit(c)) Different clients can share the same ADT. printf("%c ", c); } Powerful mechanism for building layers of abstraction. printf("\n"); Client works at a higher level of abstraction. return 0; }

20 21 PostScript: Abstract Stack Machine PostScript: Abstract Stack Machine

Language of most printers nowadays. Some commands:

Postfix language. Coordinate system: rotate, translate, scale,...

Abstract stack machine. Turtle commands: moveto, lineto, rmoveto, rlineto, ...

Graphics commands: stroke, fill, ...

Ex: convert 27531 from octal to decimal. Arithmetic: add, sub, mul, div, ...

28mul7add8mul5add8mul3add8mul1add Stack commands: copy, exch, dup, currentpoint, ...

Control constructs: if, ifelse, while, for, ...

Stack uses: Define functions: /XX { ... } def

Operands for operators.

Arguments for functions. Everyone’s first PostScript program (draw a box).

Return value(s) for functions. %! 50 50 translate 0 0 moveto 0 512 rlineto 512 0 rlineto 0 -512 rlineto -512 0 rlineto stroke showpage

22 23

Summary

Data type. Lecture P5: Supplemental Notes Set of values and collection of operations on those values.

ABSTRACT data type (ADT).

Data type whose representation is completely HIDDEN from client.

Stacks and queues.

Fundamental ADT's. – calculators – printers and PostScript language – uses to implement functions (see next lecture)

24 First Class ADT First Class ADT Client: Infix infix.c So far, only 1 stack per program. STACKinit(); #include ... #include First Class ADT: STACKpush(a); #include "STACK.h" ... int main(void) { ADT that is just like a built-in C type. Stack s1 = STACKinit(); s1 = stack of operatorsUnix b = STACKpop(); Stack s2 = STACKinit(); Can declare multiple instances of s2 =% stack gcc of infix.c integers ... int c, op; them. % a.out while ((c = getchar()) != EOF) { (2 + ((3 + 4) * (5 * 6))) Pass specific instances of them to if (c == ')') { interface as inputs. Stack s1, s2; op = STACKpop(s1); 212 if (op == '+') Details omitted in COS 126. STACKpush(s2, STACKpop(s2) + STACKpop(s2)); (See Sedgewick 4.8 or COS 226.) s1 = STACKinit(); else if (op == '*') s2 = STACKinit(); STACKpush(s2, STACKpop(s2) * STACKpop(s2)); ... } else if (c == '+' || c == '*') STACKpush(s1, a); STACKpush(s1, c); STACKpush(s2, b); else if (isdigit(c)) ... STACKpush(s2, c - '0'); c = STACKpop(s2); } printf("Result = %d\n", STACKpop(s2)); return 0; } 26 27

"Non ADT’s" Queue Interface

Is an ABSTRACT data type? Queue operations.

NO: Representation in interface. QUEUEinit(): initialize empty queue.

QUEUEisempty(): return 1 if queue is empty; 0 otherwise

Are C built-in types like int ADT’s? QUEUEput(int): insert new item at end of list.

ALMOST: we generally ignore representation. QUEUEget(): return and remove item at beginning of list.

NO: set of values depends on representation. – might use (x & 0) to test if even – works only if they’re stored as "two’s complement integers" QUEUE.h CONSEQUENCE: strive to write programs that function properly independent of representation. void QUEUEinit(void); – (x % 2 == 0) is more portable way to test if even int QUEUEisempty(void); – also, use for machine-specific ranges of int, long void QUEUEput(int item); int QUEUEget(void);

28 29 Queue Implementation Queue Client: Josephus Problem

queuearray.c queuearray.c Flavius Josephus. (first century)

Band of 41 Jewish rebels trapped in cave by Romans. #include "QUEUE.h" void QUEUEput(int item) { #define MAX_SIZE 1000 q[back++] = item; Preferring suicide to capture, rebels formed a circled and killed back %= MAX_SIZE; every 3rd remaining person until no one was left.

static int q[MAX_SIZE]; } Where should you stand to be among last two survivors? static int front, back; 31 and and 16 int QUEUEget(void) { void QUEUEinit(void) { int r = q[front++]; front = back = 0; front %= MAX_SIZE; } return r; } int QUEUEisempty(void) { return front == back; } front

Variable q[0] q[1] q[2] q[3] q[4] q[5] MAX_SIZE = 6 Value M D T E X A

back 30 31

Queue Client: Josephus Problem

josephus.c

N=8,M=3 #include #include "QUEUE.h" #define N 41 1 2 3 4 5 6 7 8 #define M 3 2 3 4 5 6 7 8 1 int main(void) { 3 4 5 6 7 8 1 2 int i; QUEUEinit(); for (i = 1; i <= N; i++) 4 5 6 7 8 1 2 QUEUEput(i); 5 6 7 8 1 2 4 while (!QUEUEisempty()) { for(i=0;i

32