CS 261 Winter 2009 Dynamic Array Introduction (aka Vector, ArrayList) Arrays, Pro and Con • Simple Arrays have nice feature that they are randomly accessible - can quickly get to any element • Dark side - size must be fixed when created. • Often you don’t know much much space you need until you are done Dynamic Array (Vector, ArrayList) • Dynamic Array (Java Vector, ArrayList, same thing, different API) get around this by encapsulating a partially filled array. • Hide memory management details behind a simple API • Is still randomly accessible, but now it grows as necessary Partially Filled Array Size vs Capacity • The size is the “logical” size - The number of elements. What the programmer thinks. Managed by an internal data value. • The capacity is the size of the physical array. Number of elements it can hold. Adding an element • Adding an element to end is sometimes easy. Just increase the (logical) size, and put new value at end. • But what happens when the size reaches the capacity? • Must reallocate new data array - but this detail is hidden from user. Reallocation and copy Adding to Middle • Adding an element to middle can also force reallocation (if the current size is equal to capacity) • But will ALWAYS require elements to moved up to make space • Is therefore O(n) worst case Picture of Adding to Middle Must use a loop to make space for new value. Careful! Loop from top down Removing an Element • Removing an Element will also require “sliding over” to delete the value • Therefore is O(n) worst case Picture of Remove Element Remove also requires loop. This time should it be from top or bottom? Element Types • How to make a general purpose container class? • We define element type as symbolic preprocessor constant. Default double. • Requires recompiling source for new element types. Not elegant, but workable. Interface file #ifndef DyArray_H #define DyArray_H # ifndef EleType # define EleType double # endif # ifndef LT # define LT(a, b) (a < b) # endif # ifndef EQ # define EQ(a, b) (a == b) # endif Interface, continued struct dyArray { EleType * data; int size; int capacity; }; /* prototypes */ void dyArrayInit (struct dyArray *v, int initCap); void dyArrayFree (struct dyArray *v); void dyArrayAdd (struct dyArray *v, EleType d); EleType dyArrayGet (struct dyArray *v, int index); EleType dyarraySet (struct dyArray *v, int index, EleType newValue); int dyArraySize (struct dyArray *v); dyArrayInit - initialization void dyArrayInit (struct dyArray * v, int initCap) { assert (initCap >= 0); v->capacity = initCap; v->size = 0; v->data = (double *) malloc(v->capacity * sizeof(EleType)); assert (v->data != 0); } dyArrayFree - clean up Void dyArrayFree (struct dyArray * v) { free (v->data); v->capacity = 0; v->size = 0; } Size int dyArraySize (struct dyArray * da) { return da->size; } Add a new Element void dyArrayAdd (struct dyArray * da, EleType newValue) { if (da->size >= da->capacity) _dyArrayDoubleCapacity(da); da->data[da->size] = newValue; da->size += 1; } Double the Capacity void _dyArrayDoubleCapacity (struct dyArray * da) { EleType * oldbuffer = da->data; int oldsize = da->size; int i; dyArrayInit (da, 2 * da->capacity); for (i = 0; i < oldsize; i++) da->data[i] = oldbuffer[i]; da->size = oldsize; free(oldbuffer); } Your chance • Anti-Quiz time. In class finish implementation of simple get and set, including reallocation. Next move on to remove to complete the Bag. Then do the stack. • Also your implementation will be used in programming assignment 2.