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

Preview:

Citation preview

CISC 220 - Data Structures

Ben PerryUniversity of Delaware

Summer 2011

Syllabus Details

• Office hours: Smith hall 103 · Wednesdays 11:00 am - 2:30 pm · or by appointment

• Teaching assistant: Vincent Ly (ly@mail.eecis.udel.edu)

• Text: Data structures and algorithm analysis in c++ - Weiss, Mark Allen

Topics Covered

Data type abstraction, recursion, arrays, stacks, queues, multiple stacks and linked lists, dynamic storage management, garbage collection, trees, graphs, tables, sorting and searching.

Grading

Quizzes 10% - lowest 5 scores droppedMidterm 15%Final 25%Project 20%Labs 30%

Labs

- Lab every week except 4th of July week.- Collaboration is allowed, copying code is not.- Should be able to complete during lab- Later labs will be more challenging

Late Policy

• Each lab is due at 11:59 PM the Sunday after it was assigned.

• Five free late days• After late days, 50% penalty for late

assignments and must be turned in within 48 hours of the deadline.

Upkeep

• No quiz today. I’m not that mean.• There is lab today• 5 minute break at the top of the hour• Slides available online

Outline

• C++ Basics• C++• Memory Management

Comments

// This is a one-line comment

/* this is a multi-line comment.*/

Constants

• Integer– Keyword “int” 0, 24, -320

• Octal integer– Prefix with 0. 014

• Hexadecimal integers– Prefix with 0x

• Floating points: 3.141592, 2.7e14

Constants

• Characters – ’a’, ’\n’• Strings – ”abc”• Suffixes can be applied to integer constants (U

for unsigned, L for long)• Several escape codes.

Variables

• Variables are named locations that can hold values of certain types.

• Variables are not instantiated in C++• Variables are created using a declaration

statement, including the type of the variable.int a,b,c; // declares three int variablesint d = 50; // declarations can be instantiated.

Native Data Types

• Integer – int• Floating points – double, float• Character – char 'a' 'b' '\0‘• Native data types can be signed / unsigned

(positive or negative, or only positive), or short, long (different ranges of values)

Native Data Types

• Boolean (bool) – true or false.• Enumerations – custom data types that have

an explicit range of values.enum Day {monday, tuesday, wednesday,

thursday, friday, saturday, sunday};

Day currentDay = monday;

Assignments

Once declared, variables can be assigned using an expression:

int variable = 0;variable = 25;variable += 25;variable++;

Other operators

var++ gets the value of var and then increments the value, but the old value is still used in an expression.

int var = 0; cout << var++; // prints 0, but var=1

++var first increments value of var and then uses the new value.

int var = 0; cout << ++var; // prints 1.

Other operators

-var negates var~var uses bitwise negate+ / - * simple arithmetic operators % returns the remainder after dividing. For

example, 5 % 2 is equal to 1. Also called modulo.<< bit-shift left (overloaded as IO stream output)>> bit-shift right (overloaded as IO stream input)

Other operators

&& and|| or! logical negation< less than<= less than or equal>, >= greater, greater or equal== equals (not to be confused with =, assignment)condition ? true branch : false branch

Strings

• C-style strings are simply character arrays with the last character being 0. (Not to be confused with ‘0’, which is actually 48 in ascii).

• In C++, there is a rich string library#include <string>string myString = “Some text”;cout << myString << endl;

I/O Streams

• C++ has the notion of I/O streams, such as file IO, console io, network io, and etc.

• We’ll use console IO quite a bit at first• Output streams and input streams are two

different objects.• cout stands for console out• cin stands for console in

Using cout, cin

• #include <iostream>• cout, cin, and a host of other objects and

classes belong to the namespace “std”.• To access cout, you can either prepend each

use with std:: std::cout << “hi” << std::endl

• Or insert “using namespace std”

Writing and Reading Streams

• To write to any stream, use:– stream << data;

• For example, to write to the screen:cout << “Hello!” << endl;

• To read in, we use:– stream >> variableToHoldData;

• For example, to read from the keyboard:cin >> inputVariable;

If / then

if (variable == value) { // true branch

}else{ // false branch, optional}

Switch

switch(currentDay){case Monday:

break;case Tuesday:

break;case Wednesday:case Thursday:

dostuff();break;

default:};

For loop

for (initialize, condition, increment){

}

Example:for (int i = 0; i < 10; i++){ cout << i << endl;}

While loop

while (condition){// dostuff

}

Example:while (i < 200){

i*=2; cout << i << endl;}

Arrays

• Arrays are a contiguous block in memory partitioned into individual units of the given type.

• Example:int interestingDays[3]; // declares an array of size 3interestingDays[0] = Friday;interestingDays[1] = Saturday;interestingDays[2] = Sunday;int badDays[2] = {Monday, Tuesday};

Pointers

Pointers are variables that hold addresses of places in memory that contain the actual information.

Declared with an asterisk (*)

int *someInteger;double *someDouble;

More on Pointers

• Pointers can be subscripted like an array - arrays are technically pointers.

• The value that pointers point to can be “dereferenced” by using the * operator.

• Pointers are typically used to represent memory persistent beyond the local scope.

More on Pointers

• Pointers must point to legal addresses, which may mean allocating memory (more on that later)

• Fields can be accessed using the pointer operator ->

Functions

Functions have a return type, a method name, and a formals list (parameters list).

int performCalc(int number1, int number2){return number1 * number2 + (number1 / 50);

}

Return types can be void, as can be parameters.void doStuff(void){}

Function Prototype

Before you can use a method, it must first be prototyped or defined.

Declare return type, name, and parameter list. Implement it elsewhere.

int foo(); // prototypeint foo(){ // implementation

// do stuff here}

Local Variables

• Variables defined in a function are called local.• When you declare non-pointer variables,

memory is allocated using the method’s stack frame.

• When the method is finished, the stack frame is destroyed, losing whatever value was in those local variables.

• Recursive methods have unique values for each stack instance.

Classes

Classes are a collection of fields (variables local to a class) and methods.

Classes can inherit from other classes (yes, multiple inheritance)

Classes can have constructors for different parameter sets, and destructors for when they are destroyed.

Classes often have a “copy constructor”, which clones an instance of the class into a new instance.

Classes// Foo.hclass Foo{

int a, b; // a and b are private;public:

Foo(int someValue, int someOtherValue);int add();

};

Default access is private. Three accesses: public (everyone can use), protected (only children classes can use), and private (only class methods can use).

Access is specified with a the modifier and a colon.Classes are usually declared in a .h file, defined in a .cpp file.

Defining the class methods

The following is typically in a .cpp file:

// Foo.cpp#include “Foo.h”Foo::Foo(int someValue, int someOtherValue){

a = someValue; b = someOtherValue;}

int Foo::add(){return someValue + someOtherValue;

};

Declaring an instance of a classFoo foo(1,2); // creates an instance of Foo,

// calling its constructorcout << foo.add(); // reference methods and fields with .

Foo *fooPointer ; // creates a pointer of type // Foo. DOES NOT create an

// instance;

fooPointer = new Foo(1, 2); // creates the // instance, invoking constructor,

// storing the address in fooPointerfooPointer->add(); //references members with ->delete fooPointer; // releases memory, calling destructor.

Executable programs

Needs exactly one main method in global scope.

int main(int argCount, char * args[]){cout << “Hello world!” << endl;

}

Argument passing by value

int doStuff(Foo foo){// pass by value

}

A new instance of foo is created, calling the copy constructor if present.

When the method exits, the destructor is called.

Might be expensive.

Argument passing by reference

int doStuff(Foo &foo){// the & denotes pass by referencefoo = bar;

}

Foo foo;doStuff(foo);// foo is now bar

foo is not copied, no destructor or constructor is invoked.However, changes to foo are persistent beyond the scope.

Const reference

Using the keyword const makes it so that you cannot make any assignments to the variable.

int foo(int a, int &b, const int &c){a = 5; // okay, but change is only for scopeb = 5; // okay, changes persist beyond scopec = 5; // will not compile.

}int x, y, z;x = 0, y = 0, z = 0;foo(x, y, z);cout << “x = “ << x << “, y = “ << y << “, z = “ << z << endl;

Recursion

To understand recursion, you must first understand recursion.

A function that calls itself, usually using slightly adjusted parameters.

Usually terminated when a base case is met.

Good alternative to loops.

Recursion

void recurse(){recurse();

}

This will never terminate, though.

Recursion

void russianDoll(int size){if (size == 0)

return;cout << “I am a Russian doll of size “ << size <<

endl;russionDoll(size – 1);

}

Factorial

4! = 4 * 3 * 2 * 1

int factorial(int number){if (number <= 1) return 1; // base casereturn number * factorial(number – 1);

}

Fibonacci

• Fib0 = 0 base case

• Fib1 = 1 base case

• Fibn = Fibn-1 + Fibn-2 for n > 1 recursive case

int Fib(int n) { if (n <= 1) { can handle both

return n; base cases together } // {n > 0} an assertion return Fib(n-1) + Fib(n-2); recursive case}

Recursion

• Define your base case• Adjust your parameters in your method call by

working towards the base case.

Recommended