cs261 data structures
play

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:


  1. CS261 Data Structures Dynamic Arrays Part 2: Implementation

  2. 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: – Maximum number of elements must be specified when created

  3. Element Types - TYPE • 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.

  4. Interface File: dynarr.h #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

  5. Interface (cont.) struct DynArr { Not ideal TYPE *data; /* Pointer to data array. */ to have in int size; /* Number of elements in collection. */ header file 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);

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

  7. Clean Up: freeDynArr void freeDynArr(struct DynArr *v) { assert(v != 0); assert(v->data != 0); free(v->data); v->data = 0; v->cap = 0; struct DynArr { v->size = 0; TYPE *data; } int size; int cap };

  8. Concretely, in C…using the dynArray struct DynArr d; _initDynArr(&d, 8); addDynArr(&d, 1); ... freeDynArr(&d);

  9. Better Solution 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

  10. Modified Interface struct DynArr { TYPE *data; /* Pointer to data array. */ Moved to .c int size; /* Number of elements in collection. */ implementation file 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);

  11. Create Dynamic Array Usage of createDynArr: struct DynArr *d; d = createDynArr(20); createDynArr must: 1) allocate space for DynArr struct ? data = size = ? cap = ?

  12. Create Dynamic Array Usage of createDynArr: struct DynArr *d; d = createDynArr(20); createDynArr must: 1) allocate space for DynArr struct 2) initialize dynamic array 3) return pointer to dynamic array Return pointer data = size = 0 cap = 20 . . . .

  13. Create Dynamic Array struct DynArr* createDynArr(int cap) Allocate space for struct { DynArr itself! struct DynArr *r; assert(cap > 0); r = malloc(sizeof( struct DynArr)); assert(r != 0); _initDynArr(r,cap); return r; struct DynArr { } TYPE *data; int size; int cap };

  14. Using ‘encapsulated’ DynArray struct DynArr *d; d = createDynArr(20); addDynArr(d, 1); ... freeDynArr(d);

  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

  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.

  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 };

  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 };

  19. Double the Capacity After reallocation: Before reallocation: data = data = size = 8 size = 8 cap = 8 cap = 16 Must: allocate space copy data free old space

  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; struct DynArr { free(oldbuffer); TYPE *data; int size; } int cap };

Recommend


More recommend