You are on page 1of 42

Data Structures

Abstract Data Types (ADTs)


Class Templates
C++ Review
Data Abstraction
An abstract data type (ADT) is a set
of objects together with a set of
operations

 The ADT’s definition does not


mention how the set of operations
are implemented
ADTs vs Data Structures
 ADT: Specification of a set of data
and the set of operations that can
be performed on that data

 Data structure: Representation of


data and the operations allowed on
that data
Abstract Data Types
 In Object Oriented Programming,
data and the operations that
manipulate that data are grouped
together in classes
Abstract Data Types
 An ADT is composed of
 A collection of data
 A set of operations on that data

 Specifications of an ADT indicate:


 What the ADT operations do, not how
to implement them
 Implementation of an ADT
 Includes choosing a particular data
structure
The Core Operations
 Every Collection ADT should provide a way to:
 add an item
 remove/delete an item
 find, retrieve, or access an item
 Many, many more possibilities
 is the collection empty
 make the collection empty
 give me a sub set of the collection, …, etc.
 Many different ways to implement these
operations each with associated costs and
benefits
ADT FORMAT
The format includes:
A header with the name of the ADT

 Description of the types of data

A list of operations
ADT FORMAT
For each operation we specify:
 The input values that are
provided by the client
 Preconditions that must apply to
the data before the operation can
be performed
 The process that is performed by
the operation
ADT FORMAT
After execution the operation, we
specify:
 The output values that are
returned to the client
 The post conditions that indicate
any changes in the data
NOTE:
Most ADTs have an initializer operation that
assigns initial values to the data (constructor in
C++)
ADT FORMAT
Example

A circle is defined as a set of points equally


distant from a point called the center. For
graphical display,
An ADT for a circle includes both the radius
and the center point. For measurement
applications, an ADT requires only the radius.
We design the circle ADT for measurement
and include operations to compute the area
and circumference.
C++ Classes and ADT
 C++ provides the user-defined class types to
represent ADTs

 Every C++ class consists of members that


represent either variables or functions:
- Members represent variables called
data members
- Members represent functions called
methods or member functions

 Clients ( user program ) with access to a particular


class, can declare and manipulate objects of that class
C++ Classes and ADT
 While writing a client program, we can
use a C++ class as long as we know the
specifications of each of its methods.
 We do not need to know how the
objects are actually stored or how the
methods are actually programmed.
 This is an important programming
feature that OOP provides and is known
as information hiding.
C++ Templates
Overview of C++ Templates
 Templates are used to parameterize classes
and functions with different types
 Function templates do not require explicit
declaration of the parameterized types when
called
 Classes require explicit declaration of
parameterized types when instantiated
Function Templates
 Function template
template <typename T> swap takes a single
void swapIt(T &lhs, T &rhs) type parameter, T
{  Definition
T temp = lhs; interchanges values
lhs = rhs; of two passed
rhs = temp; arguments of the
} parameterized type
int main () {  Note that compiler
int i = 3, j = 7; infers the
swapIt (i,j); parameterized type
return 0; when swap is called
}
Class Templates
 Class templates
 Allow type-specific versions of generic classes
 Format:
template <class T>
class ClassName{
definition
}
 Need not use "T", any identifier will work
 To create an object of the class, type
ClassName< type > myObject;
Example: Stack< double > doubleStack;
Class Templates (II)
 Template class functions
 Declared normally, but preceded by template<class T>
• Generic data in class listed as type T
 Binary scope resolution operator (::) used

 Template class function definition:

template<class T>
MyClass< T >::MyClass(int size)
{
myArray = new T[size];
}
• Constructor definition - creates an array of type T
Class Templates
template <typename T>
 Notice that parameterized
class Array {
type T must be specified
public:
repeatedly in class template
Array(const int size);
~Array();  When an instance is
private: declared, must also explicitly
T *m_values; specify the concrete type
const int m_size; parameter
};  E.g., int in function main()

int main() {
Array <int> a(10);
return 0;
}
Functions
“FindMax” Example
int FindMax(int x, int y)
{
int maximum;

if(x>=y)
maximum = x;
else
maximum = y;

return maximum;
}
“FindMax” Example (cont.)
#include <iostream.h>
int FindMax(int, int); // function prototype

int main()
{
int firstnum, secnum, max;
cout << "\nEnter two numbers: ";
cin >> firstnum >> secnum;
max=FindMax( firstnum, secnum); // the function is called here
cout << "The maximum is " << max << endl;
return 0;
}
Formal Parameters
• The argument names in the function header are
referred to as formal parameters.

int FindMax(int x, int y)


{
int maximum;

if(x>=y)
x, y are called
maximum = x;
else “formal parameters”
maximum = y;

return maximum;
}
Calling a function by “value”

• The formal parameters receive a copy of the


actual parameter values.

• The function cannot change the values of


the actual parameters.
Actual Parameters
• The argument names in the function call are referred
to as actual parameters

#include <iostream.h>
int FindMax(int, int); // function prototype
int main()
{ firstnum, secnum are called
int firstnum, secnum, max; “actual parameters”
cout << "\nEnter two numbers: ";
cin >> firstnum >> secnum;
max=FindMax( firstnum, secnum); // the function is called here
cout << "The maximum is " << max << endl;
return 0;
}
Calling a function by value (cont.)

#include <iostream.h>
void newval(float, float); // function prototype
int main()
{
float firstnum, secnum;
cout << "Enter two numbers: ";
cin >> firstnum >> secnum;
newval(firstnum, secnum);
cout << firstnum << secnum << endl;
return 0;
}

void newval(float xnum, float ynum)


{
xnum = 89.5;
ynum = 99.5;
}
Calling a function by “reference”
• The formal parameters become an alias
for the actual parameters.
• The function can change the values of the
actual parameters.

Note: formal parameters must be declared


as “reference” variables.
Calling a function by reference
#include <iostream.h>
void newval(float&, float&); // function prototype
int main()
{
float firstnum, secnum;
cout << "Enter two numbers: ";
cin >> firstnum >> secnum;
newval(firstnum, secnum);
cout << firstnum << secnum << endl;
return 0;
}

void newval(float& xnum, float& ynum)


{
xnum = 89.5;
ynum = 99.5; reference variables!
}
Calling a function by reference
#include <iostream.h>
void newval(float&, float&); // function prototype
int main()
{
float firstnum, secnum;
cout << "Enter two numbers: ";
cin >> firstnum >> secnum;
newval(firstnum, secnum);
cout << firstnum << secnum << endl;
return 0;
}

void newval(float& xnum, float& ynum)


{
xnum = 89.5; Formal parameters
ynum = 99.5; become an “alias” of the
}
actual parameters!
Call by Ref. and "const" modifier
• Call by reference is the preferred way to pass
a large structure or class instances to
functions, since the entire structure need not
be copied each time it is used!
• C++ provides us with protection against
accidentally changing the values of variables
passed by reference with the const operator

int FindMax(const int& x, const int& y);


Pointers and Reference
Variables
Reference variables
• A reference variable stores the address of another
variable.
• Reference variables must be initialized during
declaration.
#include <iostream.h>

void main()
{
int x = 3;
int& y = x;

cout << "x= " << x << "y = " << y << endl;

y = 7;
cout << "x= " << x << "y = " << y << endl;
}
Reference variables and pointers

• A reference variable is a constant pointer


(after initializing a reference variable, we
cannot change it again).

• Reference variables are dereferenced


automatically (no need to use the
dereferencing operator *).
Reference variables and pointers
(cont.)
int b; // using reference variables
int& a = b;
a = 10;

int b; // using pointers


int *a = &b; Note: dereferencing operator *
*a = 10;
“Call by reference” - revisited
#include <iostream.h>
void newval(float&, float&); // function prototype
int main()
{
float firstnum, secnum;
cout << "Enter two numbers: ";
cin >> firstnum >> secnum;
newval(firstnum, secnum);
cout << firstnum << secnum << endl;
return 0;
}
void newval(float& xnum, float& ynum)
{
xnum = 89.5;
ynum = 99.5; no
} dereferencing !
Same example, using pointers …
#include <iostream.h>
void newval(float *, float *); // function prototype
int main()
{
float firstnum, secnum;
cout << "Enter two numbers: ";
cin >> firstnum >> secnum;
newval(&firstnum, &secnum); pass address explicitly
cout << firstnum << secnum << endl;
return 0;
}
void newval(float *xnum, float *ynum)
{
*xnum = 89.5; dereferencing is
*ynum = 99.5;
} required !
Static / Dynamic
Array Allocation
1D Static Array Allocation
short arr[6];

&arr[i] := &arr[0] + (i * sizeof(short))


offset
Static 1D arrays as function arguments

float find_average(int [], int);

void main()
{
const numElems = 5;
int arr[numElems] = {2, 18, 1, 27, 16};

cout << "The average is " << find_average(arr, numElems) <<


endl;
}
Static 1D arrays as
function arguments

float find_average(int vals[], int n)


{
int i;
float avg;

avg=0.0;
for(i=0; i<n; i++)
avg += vals[i];

avg = avg/n;

return avg;
}
Dynamic 1D Array
Allocation/ Deallocation

int *arr;

arr = new int[N];

delete [] arr;
Dynamic 1D arrays
as function arguments
float find_average(int *, int);

void main()
{
int *arr, numElems;
float average;

cin << numElems;

arr = new int[numElems];


// initialize array

average = find_average(arr, numElems);

cout << "The average is " << average << endl;


}
Dynamic 1D arrays
as function arguments

float find_average(int *vals, int n)


{
int i;
float avg;

avg=0.0;
for(i=0; i<n; i++)
avg += vals[i];

avg = avg/n;

return avg;
}

You might also like