data structure & abstract data type

48
Data Structure & Abstract Data Type C and Data Structures Baojian Hua [email protected]

Upload: tanisha-gilliam

Post on 03-Jan-2016

80 views

Category:

Documents


0 download

DESCRIPTION

Data Structure & Abstract Data Type. C and Data Structures Baojian Hua [email protected]. Data Types. A data type consists of: A collection of data elements (a type) A set of operations on these data elements Data types in languages: predefined: - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Data Structure & Abstract Data Type

Data Structure &Abstract Data Type

C and Data StructuresBaojian Hua

[email protected]

Page 2: Data Structure & Abstract Data Type

Data Types A data type consists of:

A collection of data elements (a type) A set of operations on these data elements

Data types in languages: predefined:

any language defines a group of predefined data types (In C) int, char, float, double, …

user-defined: allow programmers to define their own (new) data typ

es (In C) struct, union, …

Page 3: Data Structure & Abstract Data Type

Data Type Examples Predefined:

type: int elements: …, -2, -1, 0, 1, 2, … operations: +, -, *, /, %, …

User-defined: type: complex elements: 1+3i, -5+8i, … operations: newComplex, add, distance,

Page 4: Data Structure & Abstract Data Type

Abstract Data Types An abstract data type:

separates data type definition from representation

separates function declaration (prototypes) from implementation

Example of abstract data types in languages interfaces in Java signatures in ML (roughly) header files & typedef in C

Page 5: Data Structure & Abstract Data Type

Data Structures Data structure studies the organization of d

ata in computers, consisting of the (abstract) data types (definition and repr’) relationship between elements of this type operations on data types

Algorithms: methods to operate on data structures

tradeoff between efficiency and simplicity subtle interplay with data structure design

Slogan: program = data structures+algorithm

Page 6: Data Structure & Abstract Data Type

What will this course cover? Linear structure:

Linked list, stack, queue, extensible array, functional string

Tree & forest: binary tree, binary search tree

Graph Hash Searching

Page 7: Data Structure & Abstract Data Type

More on Modules and Abstract Data Types

Consider a data type to represent natural number n: a data type called “nat” elements: 0, 1, 2, 3, … operations: newNat, add, sub, …

How to represent this (abstract) data type in C?

Page 8: Data Structure & Abstract Data Type

“nat” ADT in C (Interface)// in file “nat.h”#ifndef NAT_H#define NAT_H

typedef struct nat *nat;

nat newNat (int i);nat natAdd (nat n1, nat n2);// other function prototypes are similar

#endif

Page 9: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “nat.h”

int main (){ nat n1, n2, n3; n1 = newNat (8); n2 = newNat (9); n3 = natAdd (n1, n2);

return 0;}

Page 10: Data Structure & Abstract Data Type

“nat” Implementation// in file “nat.c”#include <stdlib.h>#include “nat.h”

struct nat{ int i; // the concrete internal representation};

nat newNat (int i){ nat n = malloc (sizeof (*n)); n->i = i; return n;}

i

n

Page 11: Data Structure & Abstract Data Type

“nat” Implementation// in file “nat.c”#include <stdlib.h>#include “nat.h”

struct nat{ int i; // the concrete internal representation};nat newNat (int i){ if (i<0) error (“invalid arg\n”); nat n = malloc (sizeof (*n)); n->i = i; return n;}

i

n

Page 12: Data Structure & Abstract Data Type

“nat” Implementation// in file “nat.c”#include <stdlib.h>#include “nat.h”

struct nat{ int i; // the concrete internal representation};nat natAdd (nat n1, nat n2){ nat n = malloc (sizeof (*n)); n->i = n1->i + n2->i; return n;}

i

n1

i

n2

n1->i +n2->i

n

Page 13: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “nat.h”

int main (){ nat n1, n2, n3; n1 = newNat (8); n2 = newNat (9); n3 = natAdd (n1, n2);

// but what if we want to print nat? Is it: // printf (“”, n3) ????

return 0;}

Page 14: Data Structure & Abstract Data Type

Change to the Interface// in file “nat.h”#ifndef NAT_H#define NAT_H

typedef struct nat *nat;

nat newNat (int i);nat natAdd (nat n1, nat n2);void natPrint (nat n);// other function prototypes are similar

#endif

Page 15: Data Structure & Abstract Data Type

Change to the Implementation// in file “nat.c”#include <stdlib.h>#include <stdio.h>#include “nat.h”

struct nat{ int i; // the concrete internal representation};

void natPrint (nat n){ printf (“%d”, n->i); return;}

Page 16: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “nat.h”

int main (){ nat n1, n2, n3; n1 = newNat (8); n2 = newNat (9); n3 = natAdd (n1, n2);

// but what if we want to print nat? Is it: natPrint (n3);

return 0;}

Page 17: Data Structure & Abstract Data Type

More on Modules and Abstract Data Types A tuple type has the form: (x, y)

x and y may have different types Tx, Ty Tx, Ty unknown in advance and may be differen

t operations:

newTuple (x, y); // create a new tuple with x and y equals (t1, t2); // equality testing first (t); // get the first element second (t); // get the second element …

How to represent this abstract data type in computers (using C)?

Page 18: Data Structure & Abstract Data Type

The Tuple ADT Next, we first consider a monomorphic tuple type c

alled “natTuple”: both the first and second components are of “nat” type (2, 3), (8, 9), …

The natTuple ADT: type: natTuple elements: (2, 3), (8, 9), … Operations:

tuple newNatTuple (nat x, nat y); nat first (nat t); Ty second (tuple t); bool equals (tuple t1, tuple t2); …

Page 19: Data Structure & Abstract Data Type

“natTuple” Interface// in file “natTuple.h”#ifndef NAT_TUPLE_H#define NAT_TUPLE_H

#include “nat.h”

typedef struct natTuple *natTuple;

natTuple newNatTuple (nat n1, nat n2);nat first (natTuple t);nat second (natTuple t);int equals (natTuple t1, natTuple t2);

#endif

Page 20: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “nat.h”#include “natTuple.h”

int main (){ nat n1 = newNat (3); nat n2 = newNat (5);

natTuple t1 = newNatTuple (n1, n2);

return 0;}

Page 21: Data Structure & Abstract Data Type

“natTuple” Implementation// in file “natTuple.c”#include “natTuple.h”

struct natTuple{ nat n1; nat n2;};

natTuple newNatTuple (nat x, nat y){ natTuple t = malloc (sizeof (*t)); t->n1 = x; t->n2 = y; return t;}

n1

n2

t

Page 22: Data Structure & Abstract Data Type

“natTuple” Implementation// in file “natTuple.c”#include “natTuple.h”

struct natTuple{ nat n1; nat n2;};

nat first (natTuple t){ return t->n1;}

n1

n2

t

Page 23: Data Structure & Abstract Data Type

“natTuple” Implementation// in file “natTuple.c”#include “natTuple.h”

struct natTuple{ nat n1; nat n2;};

int equals (natTuple t1, natTuple t2){ // the first try (it’s wrong!!): return (t1->n1 == t2->n1 && t1->n2 == t2->n2);}

n1

n2

t1n1

n2

t2

Page 24: Data Structure & Abstract Data Type

“natTuple” Implementation// in file “natTuple.c”#include “natTuple.h”

struct natTuple{ nat n1; nat n2;};

int equals (natTuple t1, natTuple t2){ // the second try: return (natEquals (t1->n1, t2->n1) && natEquals (t1->n2, t2->n2));}

n1

n2

t1n1

n2

t2

Page 25: Data Structure & Abstract Data Type

Change to the “nat” Interface// in file “nat.h”#ifndef NAT_H#define NAT_H

typedef struct nat *nat;

nat newNat (int i);nat natAdd (nat n1, nat n2);void natPrint (nat n);int natEquals (nat n1, nat n2);// other function prototypes are similar

#endif

Page 26: Data Structure & Abstract Data Type

Change to the “nat” Implementation// in file “nat.c”#include <stdlib.h>#include <stdio.h>#include “nat.h”

struct nat{ int i;};

int natEquals (nat n1, nat n2){ return (n1->i == n2->i);}

i

n1

i

n2

Page 27: Data Structure & Abstract Data Type

“natTuple” Implementation// in file “natTuple.c”#include “natTuple.h”

struct natTuple{ nat n1; nat n2;};

int equals (natTuple t1, natTuple t2){ // the second try: return (natEquals (t1->n1, t2->n1) && natEquals (t1->n2, t2->n2));}

n1

n2

t1n1

n2

t2

Page 28: Data Structure & Abstract Data Type

The Tuple ADT Finally, we consider a polymorphic tuple

type called “tuple”: “poly”: may take various forms Every components of tuple may be of

different types (2, 3.14), (“8”, ‘a’), (‘\0’, 99), …

The “tuple” ADT: type: tuple elements: (2, 3.14), (“8”, ‘a’), (‘\0’, 99), …

Page 29: Data Structure & Abstract Data Type

The Tuple ADT

What about operations? tuple newTuple (??? x, ??? y); ??? first (tuple t); ??? second (tuple t); int equals (tuple t1, tuple t2); …

Page 30: Data Structure & Abstract Data Type

Polymorphic Type To cure this, C offer a polymorphic

type “void *” “void *” is a pointer which can point

to “any” concrete types (i.e., it’s compatible with any pointer type)

think a box or a mask can not be used directly, use ugly cast similar to constructs in others

language, such as “Object”

Page 31: Data Structure & Abstract Data Type

The Tuple ADT

What about operations? tuple newTuple (void *x, void *y); void *first (tuple t); void *second (tuple t); int equals (tuple t1, tuple t2); …

Page 32: Data Structure & Abstract Data Type

“tuple” Interface// in file “tuple.h”#ifndef TUPLE_H#define TUPLE_H

typedef void *poly;typedef struct tuple *tuple;

tuple newTuple (poly x, poly y);poly first (tuple t);poly second (tuple t);int equals (tuple t1, tuple t2);

#endif TUPLE_H

Page 33: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “complex.h”#include “nat.h”#include “tuple.h”int main (){ complex c = newComplex (1.0, 2.0); nat n1 = newNat (8); nat n2 = newNat (6);

tuple t1 = newTuple (n1, c); tuple t2 = newTuple (n2, c); return 0;}

Page 34: Data Structure & Abstract Data Type

“tuple” ADT Implementation// in file “tuple.c”#include <stdlib.h>#include “tuple.h”

struct tuple{ poly x; poly y;};tuple newTuple (poly x, poly y){ tuple t = malloc (sizeof (*t)); t->x = x; t->y = y; return t;}

x

y

t

Page 35: Data Structure & Abstract Data Type

“tuple” ADT Implementation// in file “tuple.c”#include <stdlib.h>#include “tuple.h”

struct tuple{ poly x; poly y;};

poly first (tuple t){ return t->x;}

x

y

t

Page 36: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “complex.h”#include “nat.h”#include “tuple.h”int main (){ complex c = newComplex (1.0, 2.0); nat n1 = newNat (8); nat n2 = newNat (6); tuple t1 = newTuple (n1, c); tuple t2 = newTuple (n2, c); nat temp = (nat)first (t1); // type cast return 0;}

Page 37: Data Structure & Abstract Data Type

“equals”?struct tuple{ poly x; poly y;};

// The first try:int equals (tuple t1, tuple t2){ return ((t1->x) == (t2->x) && (t1->y) == (t2->y)) // Wrong!!}

Page 38: Data Structure & Abstract Data Type

“equals”?struct tuple{ poly x; poly y;};

// The second try:int equals (tuple t1, tuple t2){ return (equalsXXX (t1->x, t2->x) && equalsYYY (t1->y, t2->y)) // but what are “equalsXXX” and “equalsYYY”?}

Page 39: Data Structure & Abstract Data Type

Function as Arguments// So instead of guessing the types of t->x and // t->y in the body of “equals” function, we // require the callers of “equals” supply the // necessary equality testing functions. // The second try:// typedef int (*fun)(poly, poly);

int equals (tuple t1, tuple t2, fun eqx, fun eqy){ return (eqx (t1->x, t2->x) && eqy (t1->y, t2->y));}

Page 40: Data Structure & Abstract Data Type

Change to “tuple” Interface// in file “tuple.h”#ifndef TUPLE_H#define TUPLE_H

typedef void *poly;typedef int (*fun)(poly, poly);typedef struct tuple *tuple;

tuple newTuple (poly x, poly y);poly first (tuple t);poly second (tuple t);int equals (tuple t1, tuple t2, fun eqx, fun eqy);

#endif TUPLE_H

Page 41: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “complex.h”#include “nat.h”#include “tuple.h”int main (){ complex c = newComplex (1.0, 2.0); nat n1 = newNat (8); nat n2 = newNat (6); tuple t1 = newTuple (n1, c); tuple t2 = newTuple (n2, c); equals (t1, t2, natEquals, complexEquals); return 0;}

Page 42: Data Structure & Abstract Data Type

Moral void* serves as polymorphic type in C

mask all pointer types (think Object type in Java) Pros:

code reuse: write once, used in arbitrary context we’d see more examples later in this course

Cons: Polymorphism doesn’t come for free

boxed data: data heap-allocated (to cope with void *) no static or runtime checking (at least in C) clumsy code

extra function pointer arguments

Page 43: Data Structure & Abstract Data Type

Function Pointer in Datatypedef int (*fun)(poly, poly);int equals (tuple t1, tuple t2){ // note that if t1->x or t1->y has carried the // equality testing functions, then the code // could just be written: return (t1->x->equals (t1->x, t2->x) && t1->y->equals (t1->y,t2->y)); }

……

equals

x

y

t1

t1->x

Page 44: Data Structure & Abstract Data Type

Function Pointer in Data// To cope with this, we should modify other // modules. For instance, the “nat” ADT:struct nat{ int (*equals) (poly, poly); int i;};

nat newNat (int i){ nat n = malloc (sizeof (*n)); n->equals = natEquals; n->i = i; return n;}

i

n

equals

Page 45: Data Structure & Abstract Data Type

The Calltypedef int (*fun)(poly, poly);int equals (tuple t1, tuple t2){ return (t1->x->equals (t1->x, t2->x) && t1->y->equals (t1->y,t2->y));}

i

t1->x

equals

i

t2->x

Page 46: Data Structure & Abstract Data Type

Client Code// in file “main.c”#include “complex.h”#include “nat.h”#include “tuple.h”int main (){ complex c = newComplex (1.0, 2.0); nat n1 = newNat (8); nat n2 = newNat (6); tuple t1 = newTuple (n1, c); tuple t2 = newTuple (n2, c); equals (t1, t2); // dirty simple! :-P return 0;}

Page 47: Data Structure & Abstract Data Type

Function Pointers in Data

Data elements with function pointers is the simplest form of objects object = virtual functions + private data

With such facilities, we can in principal model object programming In fact, early C++ compilers compiles to C That’s partly why I don’t love object-o

riented languages

Page 48: Data Structure & Abstract Data Type

Summary Data structure studies data representation and

operations direct interplay with algorithm design

Abstract data types enable modular programming

clear separation between interface and implementation

interface and implementation should design and evolve together

Polymorphism enables code reuse See the course web page for programming

assignments