+ All Categories
Home > Documents > CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Date post: 18-Jan-2016
Category:
Upload: percival-stevens
View: 217 times
Download: 0 times
Share this document with a friend
41
CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)
Transcript
Page 1: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

CS 261 Fall 2009

Dynamic Array Introduction

(aka Vector, ArrayList)

Page 2: CS 261 Fall 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

Page 3: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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

Page 4: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Partially Filled Array

Page 5: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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.

Page 6: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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.

Page 7: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Reallocation and copy

Page 8: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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

Page 9: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Picture of Adding to Middle

Must use a loop to make space for new value. Careful! Loop from top down

Page 10: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Removing an Element

• Removing an Element will also require “sliding over” to delete the value

• Therefore is O(n) worst case

Page 11: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Picture of Remove Element

Remove also requires loop. This time should it be from top or bottom?

Page 12: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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.

Page 13: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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

Page 14: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Interface, continuedstruct dyArray { EleType * data; int size; int capacity;};

/* prototypes */void dyArrayInit (struct dyArray *da, int initCap);void dyArrayFree (struct dyArray *da);void dyArrayAdd (struct dyArray *da, EleType d);EleType dyArrayGet (struct dyArray *da, int index);EleType dyarraySet (struct dyArray *da, int index, EleType

newValue);int dyArraySize (struct dyArray *da);

Page 15: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

dyArrayInit - initialization

void dyArrayInit (struct dyArray * da, int initCap){ assert (initCap >= 0); da->capacity = initCap; da->size = 0; da->data = (double *) malloc(da->capacity * sizeof(EleType)); assert (da->data != 0);}

Page 16: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

dyArrayFree - clean up

Void dyArrayFree (struct dyArray * da)

{

free (da->data);

da->capacity = 0;

da->size = 0;

}

Page 17: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Size

int dyArraySize (struct dyArray * da)

{ return da->size; }

Even though one line, still a good idea to hide behind function call abstraction

Page 18: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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

Page 19: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

How to Double the Capacity

• Think it through. What are the steps? Need to make a new data buffer array that is twice the size. Need to copy elements from old buffer to new one.

• Next thought - can we REUSE anything we have done already. We have an init function that creates new buffer. What can we wrap around it?

Page 20: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Outline of operations

• Double the capacity, can do this by

• Calling Init the new buffer size

• Copy elements from old buffer

• (opps, need to keep reference to old buffer)

Page 21: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

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

Page 22: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Whats with the underscore?

• Underscore is just another character for the C compiler

• Common convention, function names beginning with underscore should not be called directly by user, but are “internal” functions.

Page 23: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Reuse, or not

• Notice how we reused the init function. • Should always look for places where

you can reuse code• But… Should we have reused add

instead of just placing elements into the new buffer

• Judgement call on very simple operations. (arguments pro and con)

Page 24: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

What is O( ) for double

• What is the O( ) of doubleCapacity?

• What is therefore the worst case O( ) of add?

• But do you expect it to be this bad most of the time?

• Subtle issue, will leave for next class

Page 25: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

get and Set, easy operationsEleType dyArrayGet (struct dyArray *da,

int index) {

assert(index >= 0 && index < da->size);

return da->data[index];

}

Set is similar

Page 26: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Adding to middle, a bit harder

Think about the steps

• Make sure index is legal

• Make sure you have enough space

• Slide the remaining elements over

• Move into the new location

• Increase size by 1

Page 27: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Do the easy parts first

Void dyArrayInsert(struct dyArray * da, int index, EleType newValue) {

assert(index >= 0 and index <= da->size); if (da->size >= da->capacity) _dyArrayDoubleCapacity(da); /* slide things over - need to do this */ da->data[index] = newValue; da->size++}

Page 28: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Then do the slide part

• Well, I need to leave SOMETHING for you to do

• Hint. It’s a loop.

Page 29: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

If we have insert, do we really need add?

• How are add and insert similar?

• How are they different?

• What are some arguments for keeping add, for getting rid of it?

• In any design, there are tradeoffs. You should think about the alternatives.

Page 30: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Remove - lots of variations

• There are lots of ways to think about remove.

• Remove last element. Remove first element. Remove element at given index. Remove a given value.

• Think reuse - what is the most general function?

Page 31: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Steps in doing removeAt

• Check that the index is legal

• Remove by sliding values over

• Decrement the size

Page 32: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Implement removeAt

Void dyArray removeAt(struct dyArray *da, int index) {

assert(index >= 0 && index < da->size);

/* remove by sliding things over */

/* you get to do this */

da->size--;

}

Page 33: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Now we have a nice general purpose tool

/* prototypes */void dyArrayInit (struct dyArray *da, int initCap);void dyArrayFree (struct dyArray *da);void dyArrayAdd (struct dyArray *da, EleType d);EleType dyArrayGet (struct dyArray *da, int index);EleType dyArraySet (struct dyArray *da, int index, EleType

newValue);int dyArraySize (struct dyArray *da);Void dyArrayInsert (struct dyArray *da, int index, EleType

newValue);Void dyArrayRemoveAt (struct dyArray *da, int index);

Page 34: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Now lets look at making some ADTS

• How would we make a Bag? (Add, test, remove by value, size)

• How would we make a Stack (add to top, remove from top, test if empty)

• We are building these abstractions on top of the implementations we have done already

Page 35: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Stack API

Void dyArrayPush (struct dyArray * stk, EleType newValue)

{ … /* all one or two liners */ }EleType dyArrayTop (struct dyArray * stk) { assert(! dyArrayIsEmpty(stk)); … }Void dyArrayPop (struct dyArray * stk) { … }Int dyArrayIsEmpty (struct dyArray * stk) { … }

Page 36: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Design Decisions

• This is not the only way to do things - lots of possible design decisions

• Could have used the dyArray API directly, instead of making the stack wrappers

• Could have hidden the dynamic array inside a different structure.

• Think about some of the implications of these choices.

Page 37: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Implementing a Bag

• What about the Bag API?

• Bag operations - add, test, remove, size

• Some of these are already done (which?)

• Some require more than one line

Page 38: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

How to do a test

Int dyArrayContains (struct dyArray *da, EleType testValue)

{

/* loop over all values, checking each */

/* if found, return 1 (true) */

/* if you get to end, return 0 (false) */

} /* you get to write this */

Page 39: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Remove

• This version of remove takes a value, and removes the FIRST instance of something equal to this

• What are some of the alternative versions of remove you could think of

• Can we reduce the problem to the remove we have written already?

Page 40: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Remove

void remove (struct dyArray *da, EleType testValue)

{ int i;

for (i = 0; i < da->size; i++) {

if (EQ(testValue, da->data[i])) {

dyArrayRemoveAt(da, i); return; }

}

}

Page 41: CS 261 Fall 2009 Dynamic Array Introduction (aka Vector, ArrayList)

Your chance

• At home finish implementation of all the operations we have left unspecific. Next move on to remove to complete the Bag. Then do the stack.

• Also your implementation will be used in programming assignment 2.


Recommended