CS261 Data Structures Dynamic Arrays Part 2: Implementation - - PowerPoint PPT Presentation

cs261 data structures
SMART_READER_LITE
LIVE PREVIEW

CS261 Data Structures Dynamic Arrays Part 2: Implementation - - PowerPoint PPT Presentation

CS261 Data Structures Dynamic Arrays Part 2: Implementation Arrays: Pros and Cons Pro: only core data structure designed to hold a collection of elements Pro: random access: can quickly get to any element O(1) Con: fixed size:


slide-1
SLIDE 1

CS261 Data Structures

Dynamic Arrays Part 2: Implementation

slide-2
SLIDE 2
  • Pro: only core data structure designed to hold a

collection of elements

  • Pro: random access: can quickly get to any

element  O(1)

  • Con: fixed size:

– Maximum number of elements must be specified when created

Arrays: Pros and Cons

slide-3
SLIDE 3
  • How to make a general purpose container

class?

  • We define TYPE as symbolic preprocessor

constant

  • Requires recompiling source for new element

types

– Not elegant, but workable.

Element Types - TYPE

slide-4
SLIDE 4

#ifndef __DYNARR_H #define __DYNARR_H # define TYPE int # define LT(a, b) ((a) < (b) # define EQ(a, b) ((a) == (b)) ... /* Rest of dynarr.h (on next slide). */ #endif

Interface File: dynarr.h

slide-5
SLIDE 5

struct DynArr { TYPE *data; /* Pointer to data array. */ int size; /* Number of elements in collection. */ int cap; /* Capacity of array. */ }; /* Dynamic Array Functions */ void _initDynArr(struct DynArr *v, int cap); void freeDynArr(struct DynArr *v); int sizeDynArr(struct DynArr *v); void addDynArr(struct DynArr *v, TYPE e) TYPE getDynArr(struct DynArr *v, int pos); void putDynArr(struct DynArr *v, int pos, TYPE val);

Interface (cont.)

Not ideal to have in header file

slide-6
SLIDE 6

void _initDynArr(struct DynArr *v, int cap) { v->data = malloc(cap * sizeof(TYPE)); assert(v->data != 0); v->size = 0; v->cap = cap; }

Initialization: initDynArr

struct DynArr { TYPE *data; int size; int cap };

slide-7
SLIDE 7

void freeDynArr(struct DynArr *v) { assert(v != 0); assert(v->data != 0); free(v->data); v->data = 0; v->cap = 0; v->size = 0; }

Clean Up: freeDynArr

struct DynArr { TYPE *data; int size; int cap };

slide-8
SLIDE 8

struct DynArr d; _initDynArr(&d, 8); addDynArr(&d, 1);

...

freeDynArr(&d);

Concretely, in C…using the dynArray

slide-9
SLIDE 9

To use a struct dynArr, the user must declare one in main.c (see previous slide). To declare it, the compiler must know its size when compiling that file (ie. it must be in the header!) If it’s in the header, it is ‘exposed’ to the end user and this can be dangerous and violates ‘encapsulation’ (C can’t declare “private” struct elements) Better Solution: Provide create() and delete() functions for your data

  • structure. Create will returns a ‘pointer’ to allocated space

User can always declare pointers and compiler always knows the size of a pointer! Now you can hide your Struct in the .c file or a library

Better Solution

slide-10
SLIDE 10

struct DynArr { TYPE *data; /* Pointer to data array. */ int size; /* Number of elements in collection. */ int cap; /* Capacity of array. */ }; struct DynArr; /* developer can still declare pointer to DynArr */ /* Dynamic Array Functions */ void _initDynArr(struct DynArr *v, int cap); void freeDynArr(struct DynArr *v); int sizeDynArr(struct DynArr *v); void addDynArr(struct DynArr *v, TYPE e) TYPE getDynArr(struct DynArr *v, int pos); void putDynArr(struct DynArr *v, int pos, TYPE val); struct DynArr *createDynArr(int cap);

Modified Interface

Moved to .c implementation file

slide-11
SLIDE 11

Create Dynamic Array

? size = data = ? cap =

createDynArr must: 1) allocate space for DynArr struct

Usage of createDynArr: struct DynArr *d; d = createDynArr(20); ?

slide-12
SLIDE 12

Create Dynamic Array

size = data = 20 cap =

Return pointer createDynArr must: 1) allocate space for DynArr struct 2) initialize dynamic array 3) return pointer to dynamic array

Usage of createDynArr: struct DynArr *d; d = createDynArr(20); . . . .

slide-13
SLIDE 13

struct DynArr* createDynArr(int cap) { struct DynArr *r; assert(cap > 0); r = malloc(sizeof( struct DynArr)); assert(r != 0); _initDynArr(r,cap); return r; }

Create Dynamic Array

Allocate space for struct DynArr itself!

struct DynArr { TYPE *data; int size; int cap };

slide-14
SLIDE 14

struct DynArr *d; d = createDynArr(20); addDynArr(d, 1);

...

freeDynArr(d);

Using ‘encapsulated’ DynArray

slide-15
SLIDE 15

When to use Dynamic Arrays

  • Need random access
  • Low memory footprint
  • Don’t know size of array at compile time
  • See Examples in Java and C++ STL

– Vector (C++ STL) – Vector and ArrayList (Java)

  • When should/should not use a dynamic array!

– When O(N) resize is NEVER acceptable

slide-16
SLIDE 16

Dynamic Array Stack/Bag

  • First: Worksheet 14 – Dynamic Array Basics

– _setCapacity – Get, Put – Swap , RemoveAt

  • Worksheets 16, 21 (start for next assignment)

– Implement the stack/bag interfaces – keep and reuse functionality from WS#14 where appropriate.

slide-17
SLIDE 17

Get the Value at a Given Position

/* Returns data value at index position pos */ TYPE getDynArr (struct DynArr *da, int pos); { assert((sizeDynArr(da) > pos) && (pos >= 0)); return da->data[pos]; }

struct DynArr { TYPE *data; int size; int cap };

slide-18
SLIDE 18

Add a New Element

/* Insert new data value val at end of array */ void addDynArr (struct DynArr * da, TYPE val){ if (da->size >= da->cap) _dyArrDoubleCapacity(da); da->data[da->size] = val; da->size++; }

struct DynArr { TYPE *data; int size; int cap };

slide-19
SLIDE 19

Double the Capacity

8 size = data = 8 cap = 8 size = data = 16 cap =

Before reallocation: After reallocation:

Must: allocate space copy data free old space

slide-20
SLIDE 20

Double the Capacity

void _dyArrDoubleCapacity (struct DynArray * da) { TYPE * oldbuffer = da->data; int oldsize = da->size; int i; _initDynArr (da, 2 * da->cap); for (i = 0; i < oldsize; i++) da->data[i] = oldbuffer[i]; da->size = oldsize; free(oldbuffer); }

struct DynArr { TYPE *data; int size; int cap };