Overview
Lecture P5: Abstract Data Types Data type:
■ Set of values and collection of operations on those values.
■ Ex. short int – set of values between -32,768 and 32,767 – arithmetic operations: + - * / %
Abstract data type (ADT):
■ Data type whose representation is HIDDEN.
■ Don’t want client to directly manipulate data type.
■ Operations ONLY permitted through interface.
Separate implementation from specification.
■ INTERFACE: specify the allowed operations
■ IMPLEMENTATION: provide code for operations
■ CLIENT: code that uses operations
1/27/00 Copyright © 2000, Kevin Wayne P5.1 1/27/00 Copyright © 2000, Kevin Wayne P5.2
Advantages of ADT’s Complex Number Data Type
Different clients can share the same ADT. Create data structure to represent complex numbers.
■ See Sedgewick 4.8. Can change ADT without changing clients. ■ Store in rectangular form: real and imaginary parts.
Client doesn’t (need to) know how implementation works.
typedef struct { Convenient way to organize large problems. double re; ■ Decompose into smaller problems. double im; ■ Substitute alternate solutions. } Complex;
■ Separation compilation.
■ Build libraries.
Powerful mechanism for building layers of abstraction.
■ Client works at a higher level of abstraction.
1/27/00 Copyright © 2000, Kevin Wayne P5.3 1/27/00 Copyright © 2000, Kevin Wayne P5.4 Complex Number Data Type: Interface Complex Number Data Type: Client
Interface lists allowable operations on complex data type. Client program uses interface operations to calculate something:
COMPLEX.h client.c
typedef struct { #include
Complex COMPLEXadd (Complex, Complex); . . . your favorite application Complex COMPLEXmult (Complex, Complex); . . . that uses complex numbers Complex COMPLEXpow (Complex, int); Complex COMPLEXconj (Complex); return 0; double COMPLEXmod (Complex); } double COMPLEXreal (Complex); double COMPLEXimag (Complex); Complex COMPLEXinit (double, double); void COMPLEXprint(Complex);
1/27/00 Copyright © 2000, Kevin Wayne P5.5 1/27/00 Copyright © 2000, Kevin Wayne P5.6
Complex Number Data Type: Implementation Complex Number Data Type: Implementation
Write code for interface functions. Write code for interface functions.
complex.c complex.c (cont)
#include “COMPLEX.h” implementation needs to double COMPLEXmod(Complex a) { know interface return sqrt(a.re * a.re + a.im * a.im); } Complex COMPLEXadd (Complex a, Complex b) { Complex t; void COMPLEXprint(Complex) { t.re = a.re + b.re; printf(“%f + %f i\n”, a.re, a.im); t.im = a.im + b.im; } return t; } Complex COMPLEXinit(double x, double y) { Complex t; Complex COMPLEXmult(Complex a, Complex b) { t.re = x; Complex t; t.im = y; t.re = a.re * b.re - a.im * b.im; return t; t.im = a.re * b.im + a.im * b.re; } return t; }
1/27/00 Copyright © 2000, Kevin Wayne P5.7 1/27/00 Copyright © 2000, Kevin Wayne P5.8 Separate Compilation Can Change Implementation
Client and implementation both include COMPLEX.h Can use alternate representation of complex numbers.
■ Store in polar form: modulus and angle. Can be compiled jointly. %gcc client.c complex.c z = x + i y = r ( cos θ + i sin θ ) = r ei θ Can be compiled separately. %gcc -c complex.c %gcc -c client.c %gcc client.o complex.o typedef struct { double r; double theta; } Complex;
1/27/00 Copyright © 2000, Kevin Wayne P5.9 1/27/00 Copyright © 2000, Kevin Wayne P5.10
Alternate Interface Alternate Implementation
Interface lists allowable operations on complex data type. Write code for interface functions.
COMPLEX.h complex.c
typedef struct { #include “COMPLEX.h” double r; double theta; Complex COMPLEXmod(Complex a) { } Complex; return a.r; } Complex COMPLEXadd (Complex, Complex); Complex COMPLEXmult (Complex, Complex); Complex COMPLEXmult(Complex a, Complex b) { Complex COMPLEXpow (Complex, int); Complex t; Complex COMPLEXconj (Complex); t.modulus = a.r * b.r; double COMPLEXmod (Complex); t.angle = a.theta + b.theta; double COMPLEXreal (Complex); } double COMPLEXimag (Complex); Complex COMPLEXinit (double, double); Some interface functions are void COMPLEXprint(Complex); now much easier to code up.
1/27/00 Copyright © 2000, Kevin Wayne P5.11 1/27/00 Copyright © 2000, Kevin Wayne P5.12 Alternate Implementation Multiple Implementations
Write code for interface functions. Usually, there are several ways to represent and implement a data type.
complex.c Which is better: rectangular or polar representation of Complex numbers?
■ Depends on application. #include
Others are more annoying.
1/27/00 Copyright © 2000, Kevin Wayne P5.13 1/27/00 Copyright © 2000, Kevin Wayne P5.14
Rational Number Data Type “Non ADT’s”
See Assignment 3. Is Complex data type an ABSTRACT data type?
■ You will create data type for Rational numbers. ■ NO: Representation in interface.
■ Add associated operations (add, multiply, reduce) to Rational number – Client can directly manipulate the data type: a.re = 5.0;
data type. ■ Difficult to hide representation with user-defined sets of values.
■ Possible to fix (see Sedgewick 4.8 or COS 217).
typedef struct { int p; /* numerator */ Are C built-in types like int ADT’s?
int q; /* denominator */ ■ ALMOST: we generally ignore representation. } Rational; ■ NO: set of values depends on representation. – might use (x & 1) to test if odd – works only if they’re stored as two’s complement integers
■ CONSEQUENCE: strive to write programs that function properly independent of representation. – (x % 2) is portable way to test if odd – also, use
1/27/00 Copyright © 2000, Kevin Wayne P5.15 1/27/00 Copyright © 2000, Kevin Wayne P5.16 ADT’s for Stacks and Queues Stack Interface and Client
Prototypical data type. void STACKinit(void); ■ Set of operations (insert, delete) on generic data. int STACKempty(void); STACK of integers void STACKpush(int); Stack (“last in first out” or LIFO) int STACKpop(void);
■ push: add info to the data structure
■ pop: remove the info MOST recently added STACK.h #include “STACK.h” ■ initialize, test if empty int main(void) { int a, b; Queue (“first in first out” or FIFO) . . .
■ put: add info to the data structure STACKinit(); client uses data type, without STACKpush(a); ■ get: remove the info LEAST recently added regard to how it is represented . . . ■ initialize, test if empty or implemented. b = STACKpop(); return 0; Could use EITHER array or linked list see Lecture P7 } to implement EITHER stack or queue. client.c
1/27/00 Copyright © 2000, Kevin Wayne P5.17 1/27/00 Copyright © 2000, Kevin Wayne P5.18
Stack Implementation with Arrays Compilation
Push and pop at the end of array. Client and implementation both include STACK.h #include
void STACKpush(int item) { s[N++] = item; }
int STACKpop(void) { return s[--N]; } stackarray.c
1/27/00 Copyright © 2000, Kevin Wayne P5.19 1/27/00 Copyright © 2000, Kevin Wayne P5.20 Balanced Parentheses Balanced Parentheses
parentheses.c parentheses.c (cont)
int balanced(char a[]) { #include
1/27/00 Copyright © 2000, Kevin Wayne P5.21 1/27/00 Copyright © 2000, Kevin Wayne P5.22
Balanced Parentheses ADT Review
Check if your C program has unbalanced parentheses. Client can access data type ONLY through implementation.
■ Example: STACK implementation. Unix % gcc parentheses.c stackarray.c Representation is HIDDEN in the implementation.
% a.out < myprog.c ■ Implementation uses arrays. % balanced ■ Client is completely unaware of this. % % a.out < parentheses.c % unbalanced Can change ADT without changing clients at all.
■ In Lecture P7 we implement stack using linked lists instead of arrays. How could valid C program have ■ Obtain different time / space tradeoffs. unbalanced parentheses?
Exercise: extend to handle square and curly braces.
■ Good: { ( [ ( [ ] ) ( ) ] ) }
■ Bad: ( ( [ ) ] )
1/27/00 Copyright © 2000, Kevin Wayne P5.23 1/27/00 Copyright © 2000, Kevin Wayne P5.24 First Class ADT Reverse Polish (Postfix) Notation
So far, only 1 stack or queue per program. STACKinit(); Practical example of use of stack abstraction. . . . STACKpush(a); Put operator after operands in expression. . . . ■ Use stack to evaluate. b = STACKpop(); – operand: push it onto stack. – operator: pop operands, push result.
First Class ADT: ■ Systematic way to save intermediate results.
■ ADT that is just like a built-in C type. Stack s1, s2;
■ Can declare multiple instances of them. Example 1. s1 = STACKinit(); ■ Pass specific instances of them to ■ 1 2 3 4 5 * + 6 * * 7 8 9 + + * + interface as inputs. s2 = STACKinit(); . . . ■ Details omitted in COS 126 - see STACKpush(s1, a); Sedgewick 4.8 or COS 226 if interested. STACKpush(s2, b); . . . c = STACKpop(s2);
1/27/00 Copyright © 2000, Kevin Wayne P5.25 1/27/00 Copyright © 2000, Kevin Wayne P5.26
Reverse Polish (Postfix) Notation
Practical example of use of stack abstraction.
Put operator after operands in expression.
■ Use stack to evaluate. – operand: push it onto stack. – operator: pop operands, push result.
■ Systematic way to save intermediate results.
Example 2a: convert 97531 from hex to decimal.
■ 9 16 16 16 16 * * * * 7 16 16 16 * * * 5 16 16 * * 3 16 * 1 + + + +
Example 2b: convert 97531 from hex to decimal.
■ 9 16 * 7 + 16 * 5 + 16 * 3 + 16 * 1 +
■ Stack never has more than two numbers on it!
■ Horner’s method (see lecture A3).
1/27/00 Copyright © 2000, Kevin Wayne P5.28