# CISC 220 - Data Structures Ben Perry University of Delaware Summer 2011.

## Presentation on theme: "CISC 220 - Data Structures Ben Perry University of Delaware Summer 2011."— Presentation transcript:

CISC 220 - Data Structures Ben Perry University of Delaware Summer 2011

Quiz #1. Which method of parameter passing, pass-by-reference or pass- by-value, deals with the actual instance of the variable rather than a copy? #2. Fill in the blanks for this recursive method that computes x^y int power(int x, int y){ if (________) return ____; // base case. when do we quit? return ____ * power( ____, ____); // recursive call } Ex: power(5,3) = 5 * 5 * 5 = 125. Recall Anything^0 = 1. #3. Was lab 1 easy, somewhat challenging, or difficult?

Arrays Arrays are contiguous blocks of memory where each element is stored consecutively. int array[50]; This grabs 50 * sizeof(int) bytes of memory where we have access from the starting address all the way through 50*sizeof(int).

Arrays Think of it like an ice cube tray. – All ice cube slots are consecutive physically – Theyre all the same size – The entire set of ice cubes is all contained in the ice cube tray (contiguously) – You can quickly access the third ice cube by going over 3 * width (iceCube) centimeters.

Primitive Arrays In C++, there are a few different ways to declare primitive (int, double, char, etc.) arrays: int someArray[5]; Allocates but does not initialize 5 contiguous ints. int *someArray[5]; Allocates 5 pointers, does not allocate what they are pointing to

Primitive Arrays int someArray[] = {4, 3, 2, 1}; Creates an array of size 4 and instantiates each value. int someArray[] // only applicable as a parameter to a function.

Arrays C++ treats array variables as pointers. The following are semantically equivalent: – int someArray[]; – int *someArray; All pointers can be referenced like arrays Foo *foo = new Foo(); //single Foo Foo *foo = new Foo[12]; // array of Foo Objects foo->doStuff(); // if its a pointer to an object foo[10].doStuff() // if its an array of objects. Foo *foo2[]; // array of Foo Pointers (not objects) foo2[10]->doStuff(); // note arrow here vs dot earlier

Object arrays class Foo{ public: Foo(){cout << Constructed! << endl;} virtual ~Foo(){cout << Destroyed! << endl;} }; Foo localArray[20]; /* creates on stack, all objects destructed after scope. 20 Constructed on scope, 20 Destroyed after scope. */

Object arrays class Foo{ public: Foo(){cout << Constructed! << endl;} virtual ~Foo(){cout << Destroyed! << endl;} }; Foo *arrayOfPointers[2000]; /* creates an array of pointers, not instantiated. Destroyed after scope. No Constructed messages. Objects being pointed at are not destroyed after scope.*/

Object arrays class Foo{ public: Foo(){cout << Constructed! << endl;} virtual ~Foo(){cout << Destroyed! << endl;} }; Foo *pointerToAnArray = new Foo[20]; /* uses heap; array persists. developer must delete[] the array. 20 constructed messages, no destructed messages until array is destroyed. */

Object arrays class Foo{ public: Foo(){cout << Constructed! << endl;} virtual ~Foo(){cout << Destroyed! << endl;} }; Foo **pointerToArrayOfPointers = new Foo*[2000]; /* creates an array of pointers on heap. Array persists. Objects not instantiated. No Constructed. */

Recap: Object arrays Foo localArray[20]; /* creates on stack, all objects destructed after scope. 20 Constructed on scope, 20 Destroyed after scope. */ Foo *arrayOfPointers[2000]; /* creates an array of pointers, not instantiated. Destroyed after scope. No Constructed messages. Objects being pointed at are not destroyed after scope.*/ Foo *pointerToAnArray = new Foo[20]; /* uses heap; array persists. developer must delete[] the array. 20 constructed messages, no destructed messages until array is destroyed. */ Foo **pointerToArrayOfPointers = new Foo*[2000]; /* creates an array of pointers on heap. Array persists. Objects not instantiated. No Constructed. */

Multidimensional Arrays These two-dimensional arrays are semantically equivalent: – int some2DArray[][]; // array of arrays – int *some2DArray[]; // pointer that points to an array – int **some2DArray; // pointer that points to a pointer These arrays are accessed by: some2DArray[xCoordinate][yCoordinate] Foo foo[10][10]; // 100 constructed messages Foo foo[10][10][10]; // 1000 messages.

Arrays pros/cons Very cheap random access. Nth element is: N * sizeof(arrayType) Deleting or inserting in the middle… a pain. – Shift every element over by one. Order N. At capacity, allocate new chunk and copy (usually double the original capacity) (amortized negligible cost, though) Potentially uses more space than needed

Vectors Wrap around arrays Simple list operations: – Add – Insert – Delete – Size – Iterator They manage the list for you. Theyll double the capacity as needed. Theyll shift elements over when you delete / insert.

C++ STL vector #include vector data; data.push_back(1); // adds to the end of the list data.push_back(2); data.push_back(3); data[0] = 5; // only allowed if something is already at 0. for (int i =0; I < 3; i++) cout << data[i] << endl; //vector overloads [] operator

C++ iterators Iterators iterate through data structure one at a time. In vectors, simply going from N to N+1. Most data structures have some notion of iterator C++ vector iterators allow random access, but not all data structure iterators allow this.

C++ vector with iterator #include vector data; data.push_back(1); // push_back adds to the end of the list. Why not add?!? data.push_back(2); data.push_back(3); data[0] = 5; // only allowed if something is already at location 0. for (vector ::iterator currentElement = data.begin(); currentElement != data.end(); currentElement++){ cout << *iterator << endl; } // operators ++ and * have been overloaded in the iterator class.

Linked List Exactly like a scavenger hunt game. Objects can be dispersed throughout memory Nodes are used to keep track of object addresses as well as next location.

Linked Lists Typical Node class: template Class Node{ Object object; Node *next; }; Lists usually have a head and tail pointer. Last element usually points to NULL.

Linked List Insertion / Deletion – Very inexpensive if you have the pointer to where it will be inserted / deleted. – Matter of updating siblings next pointer – Ex: List = {A, C}. We insert B. We set B to point to As next, which was C, and As new next is B. – Contrast to Vectors – have to shift half of the elements over by one on average case, vs just one pointer update in Linked Lists

Linked Lists Adding a new value is simple: – Create a node – Set lists tails next pointer to new node. – Set new node as lists tail pointer. Never have to reallocate memory or have predetermined size. Dynamically created.

Linked List Random Access Heres the bad news: – If you want the 17 th element, you have to play the scavenger hunt game 17 times. (Order N) – No problem if youre accessing sequentially, but if you jump around, its a big problem. – Vectors have instant access since the memory is contiguous and each element is consecutive.

Doubly-linked list Linked lists are good for going from start to finish But what if we want to go backwards? Same idea – just have a previous pointer.

Multiply-linked Lists Single list, multiple different orderings. For example, suppose we have a list of students class StudentNode{ StudentNode *nextAlphabetical; StudentNode *nextDateOfBirth; StudentNode *nextAcademicRanking; }; Doubly-linked are technically multiply-linked.

Example implementation template class List{ public: class Node{ public: Node *next; Object data; Node (const Object &data){this->data = data;} void insert(Object &data){ Node *node = new Node(data); Node *oldNext = next; next = node; node->next = oldNext; if (this == tail) tail = node; } }; void add(Object object){ Node *node = new Node(object); if (tail != NULL) tail->next = node; else head = node; tail = node; } List(){head = tail = NULL;} Node *head, *tail; };

C++ STL list #include list listOfInts; listOfInts.push_back(12); listOfInts.push_back(13); for (list ::iterator i = listOfInts.begin(); i != listOfInts.end; i++) cout << *I; // no random access allowed :(

Stacks Like a dog pile. The last guy on the pile is the first one off. (LIFO: last in first out) Three basic operations: push, pop, and peek Push adds an element to the top of the stack Pop removes whatever was on top. Peek (or top) returns what is currently on top.

Stack application Calculating a stream of postfix notation – 1 + 2 * 4 + 3 can be written in postfix as 1 2 4 * + 3 + – For each token: If it is an operand, push it on the stack If it is an operator, pop two operands and perform operand. Push the result.

Example token stream 1 2 4 * + 3 + (postfix for 1 + 2 * 4 + 3) InputOperationStack (after op) 1Push operand1 2 2, 1 4Push operand4, 2, 1 *Multiply8, 1 +Add9 3Push operand3, 9 +Add12

C++ STL stack #include stack stackOfInts; stackOfInts.push(10); stackOfInts.top(); stackOfInts.pop();

Similar presentations