Sei sulla pagina 1di 21

Data Structures

Mugurel Ionu Andreica


Spring 2012

Grading
Activity during the Laboratory 10%
Homework Assignments 40%
4 homework assignments 10% each

Exam 50%
[optional] Course Tests (bonus: up to 10% of the
final grade; maybe less)
Must obtain at least 25% of the final grade (from
Lab Activity + Homework Assignments + Course
Tests) in order to be allowed to participate in the
exam

Course Topics

Introduction to C++ Programming


Abstract Data Type concept
Stack
Queue
Linked Lists
Graphs
Hash Tables
Trees (Binary Trees, Binary Search Trees, Balanced
Binary Search Trees)
Heaps
Disjoint Sets
Other Advanced Topics [ if time allows ] not for exam

Introduction to C++ Programming


Similar to C Programming

Inclusion of headers
Definition of types/classes
Declaration of global variables
Definition of functions
The main function

Extra C++ Concepts:


C++ classes
May contain both variables (fields) and functions with
public/private/protected access specifications
Inheritance (only very basic aspects the rest is handled in the
OOP course)

Templates (generalized classes, functions, variables, etc.)


Usually used for specifying data types

Common C/C++ Types

Basic types

Structured data types

struct s { int x; char y[2], z; double w };

Classes
Pointer types

int
char
float
double
void only for function return values

int*, int**, ...


char*, char**, ...
float*, float**, ...
double*, double**, ...
void*, void**, ...
Pointers to structs
Pointers to classes

Defining (multidimensional) arrays

int v[100] // a static array named v with 100 elements, indexed from 0 to 99
int u[100][150], v[10][20][30], w[10][20][30][40], ...
char u[100], v[10][20], w[10][20][30], ...
float u[100], v[10][20], w[10][20][30], ...
struct s u[100], v[10][20], w[10][20][30], ...
...

Classes in C++
class class_name {
access_specifier_1:
members;
methods;
access_specifier_2:
members;
methods;
...
constructor // same name as the class
destructor // ~class_name
}
Access specifier = public / private / protected
A class may contain variables and methods

Sample C++ Program with Classes


#include <stdio.h>
class MyClass {
private:
int x, cnt;
double v[100];
public:
int y;
void setX(int value) {
x = value; }
int getX() {
return x; }
void addToV(double value) {
v[cnt] = value;
cnt++; }
double getFromV(int pos) {
return v[pos]; }

MyClass(int value) {
printf("Calling the constructor\n");
x = value;
cnt = 0; }
~MyClass() {
printf("Calling the destructor\n");}
};
int main() {
int i;
MyClass c(7);
printf("%d\n", c.getX());
c.setX(19);
c.y = 17;
printf("%d\n", c.getX());
for (i = 0; i < 10; i++) c.addToV((double) i);
for (i = 9; i >= 0; i--)
printf("%.3lf\n", c.getFromV(i));
return 0;
}

Abstract Data Type


A collection of axioms + operations
Operations = what actions can be performed upon the
data type (implemented as functions in C/C++)
for each operation we know:
its name
its arguments (types and, possibly, names)
its return type

Axioms specify connections between operations (i.e. the


operations are related to one another)
Does not contain information regarding the
implementation of the operations
Similar to a Java interface (except that only the
operations are specified in an interface and no axioms)

Abstract Data Types - examples


Stack
Operations: push, pop, peek, isEmpty
Axioms: a pop() call returns the argument x of the most
recent push(x) operation called on the data type for
which no corresponding pop() has been called before
(or an error, otherwise)

Queue
Operations: enqueue, dequeue, peek, isEmpty
Axioms: a dequeue() call returns the argument x of the
oldest enqueue(x) call for which no corresponding
dequeue() was called (or an error, otherwise)

From Abstract Data Types to Data


Structures
Data structures will be initially handled as abstract data
types
First we will specify the operations and axioms (many
times, the axioms will be given implicitly)
Then we will discuss possible implementations
(occasionally more than just one)
Data structures store elements
Sometimes, the elements may have any type
Other times, the elements must obey some specific properties
(e.g. they must be comparable)

In order to store any type of elements => we will use


class templates (in C++)

Class Templates
template<typename T> class class_name { ... }
A normal class definition will be prefixed by
template<typename T>
The type T can now be used as a valid type within the
class
we can have variables, function arguments and function
return values of type T

The class class_name is parameterized with the


type T
Most of the times: T=the type of the elements
stored by the data structure
Similar to Java generics

Class Templates - Example


#include <stdio.h>
template<typename T> class MyGenericContainer {
private:
T privateObject;
public:
void setPrivateObject(T value) {
privateObject = value;
}

int main() {
MyGenericContainer<int> c1(7);
printf("%d\n", c1.getPrivateObject());
c1.setPrivateObject(9);
printf("%d\n", c1.getPrivateObject());
MyGenericContainer<double> c2(7.9);
printf("%.3lf\n", c2.getPrivateObject());
c2.setPrivateObject(9.902);
printf("%.3lf\n", c2.getPrivateObject());

T getPrivateObject() {
return privateObject;
}

struct mystruct a;
a.x = 3; a.y[4] = 'z'; a.y[5] = 90;
a.z = 90.234;
MyGenericContainer<struct mystruct> c3(a);
printf("%.3lf\n", (c3.getPrivateObject()).z);
a.z++;
c3.setPrivateObject(a);
printf("%.3lf\n", (c3.getPrivateObject()).z);
return 0;

MyGenericContainer(T value) {
privateObject = value;
}
};
struct mystruct {
int x;
char y[32];
double z;
};

Recursion
Very important in the implementation of several
data structures (usually the tree-like ones)
E.g. in order to perform an operation on a tree node,
the same operation must first be called on the nodes
children

Simple functions:
Factorial
Fibonacci

Sorting functions (with good time complexities)


Merge sort
Quick sort

The Fibonacci Sequence

F(0)=F(1)=1
F(n2)=F(n-1)+F(n-2)
1, 1, 2, 3, 5, 8, 13, ...

#include <stdio.h>
int numCalls = 0;

V1

int fibo(int n) {
numCalls++;
if (n <= 1)
return 1;
else
return fibo(n-1) + fibo(n-2);
}
int main() {
int n;
scanf("%d", &n);
printf("Fibonacci(%d)=%d\n", n, fibo(n));
printf("Total number of calls=%d\n", numCalls);
return 0;
}

#include <stdio.h>
#define NMAX 50
int numCalls = 0;
int memoFib[NMAX];

V2

int fibo(int n) {
numCalls++;
if (memoFib[n] >= 0)
return memoFib[n];
if (n <= 1)
return (memoFib[n] = 1);
else
return (memoFib[n] = fibo(n-1) + fibo(n-2));
}
int main() {
int i, n;
scanf("%d", &n);
for (i = 0; i <= n; i++) memoFib[i] = -1;
printf("Fibonacci(%d)=%d\n", n, fibo(n));
printf("Total number of calls=%d\n", numCalls);
return 0;
}

The Fibonacci Sequence (cont.)

V1
Fibonacci(20) = 10946
numCalls = 21891
Tree of Calls for V1 (n=4) :

V2
Fibonacci(20) = 10946
numCalls = 39
Tree of Calls for V2 (n=4) :

The Fibonacci Sequence (cont.)


What if we change the
order of the calls
fibo(n-1) and fibo(n2) ?
We use: fibo(n-2) +
fibo(n-1)
Does the resut
change ? (V1, V2)
Does the total number
of calls change ? (V1,
V2)

A non-recursive
function on the right

#include <stdio.h>
int fibo(int n) {
int i, fminus1, fminus2, fcurr;
fminus1 = 1;
fcurr = 1;
i = 1;

V3

while (i < n) {
i++;
fminus2 = fminus1;
fminus1 = fcurr;
fcurr = fminus1 + fminus2;
}
return fcurr;
}
int main() {
int i, n;
scanf("%d", &n);
printf("Fibonacci(%d)=%d\n", n, fibo(n));
return 0;
}

Generic Merge Sort


Explanations on the blackboard
See source code afterwards

Generic QuickSort
Quicksort(int pstart, int pstop): sort all the
elements between pstart and pstop (inclusively)
from the array of elements
Choose a pivot among the elements between
pstart and pstop
The pivot should be smaller than the maximum
element within that range

Repeatedly swap the elements between pstart


and pstop until all the elements <= pivot are
located to the left of all the elements > pivot

Generic QuickSort (cont.)


Use two indices, i and j
Initially, i=pstart and j=pstop
During the swapping phase: all the elements to
the left of i are <= pivot and all the elements to
the right of j are > pivot
While (i<=j):
If (v[i] <= pivot) i++;
Else if (v[j] > pivot) j--;
Else:
Swap v[i] and v[j]
i++;
j--;

Generic QuickSort (cont.)


Then, recursively call:
Quicksort(pstart, i-1)
i.e. sort all the elements <= pivot

Quicksort(i, pstop)
i.e. sort all the elements > pivot

See source code

Generic QuickSort (cont.)

Example: 7 9 2 4 7 3 8 2 1
Choose pivot=3
i=0, j=8, 7 9 2 4 7 3 8 2 1
i=1, j=7, 1 9 2 4 7 3 8 2 7
i=2, j=6, 1 2 2 4 7 3 8 9 7
i=3, j=6, 1 2 2 4 7 3 8 9 7
i=3, j=5, 1 2 2 4 7 3 8 9 7
i=4, j=4, 1 2 2 3 7 4 8 9 7
i=4, j=3, 1 2 2 3 7 4 8 9 7

Potrebbero piacerti anche