ds lab handouts

73
Data Structures CSC-206 Lab Manual Instructor Mr. Adeel M. Syed [email protected]

Upload: ayeshasaifbhatti

Post on 15-Jan-2015

2.190 views

Category:

Documents


6 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Ds lab handouts

Data StructuresCSC-206

Lab Manual

Instructor

Mr. Adeel M. Syed

[email protected]

Page 2: Ds lab handouts

Data Structures Lab Handouts 2

Contents

Lab 1: C++ Review

Lab 2: Implementation of Stack

Lab 3: Recursion

Lab 4: Implementation of Queue

Lab 5: Implementation of Priority Queue

Lab 6: Implementation of Linked List

Lab 7: Application of Linked List

Lab 8: Implementation of Binary Tree

Lab 9: Implementation of Binary Search Tree

Lab 10: Implementation of Graph

Lab 11: Application of Graph

Lab 12-13: Using Standard Template Library

Lab 14-15: Implementation of Sorting Techniques

Lab 16: Implementation of Searching Techniques

Page 3: Ds lab handouts

Data Structures Lab Handouts 3

Lab 1

C++ Review

Fundamental Data Types

Category Available data types

Boolean bool

Character char signed char unsigned char

Signed integer short int long

Unsigned integer unsigned short unsigned unsigned long

Floating point float double long double

Named Constants

Cannot be changed during program execution

C style constants:

#define zero 0

C++ style constants:

const int zero = 0;

const float PI = 3.14159;

Type Aliases

typedef float real;

“real” may now be used in place of “float”

If more precision (i.e. more digits) needed, can replace this one statement by

typedef double real;

Page 4: Ds lab handouts

Data Structures Lab Handouts 4

Arithmetic Expressions

Binary operators: !, ", *, /, %

Unary operators: +, ", ++, " "

Usual precedence rules apply

Unary operators are right-associative: ++ X " " means ++ (X " ")

Binary operators are left-associative: A / B * C means (A / B) * C

Relational & Logical Expressions

Relational operators: <, >, <=, >=

Equality operators: = =, !=

Logical operators:

Unary: !

Binary: &&, | |

Examples:

(5 = = 4) && (a < b) // false, since 5 != 4

(5 = = 5) | | (a < b) // true, since 5 = = 5

Conditional Expressions

expression ? expression : expression

Executed like if " else statement, but has a value

Example:

larger = (A > B) ? A : B;

Page 5: Ds lab handouts

Data Structures Lab Handouts 5

Functions

int max1( int X, int Y )

{

return (X > Y) ? X : Y; // result returned as function value

}

void max2( int X, int Y, int &Larger )

{

Larger = (X > Y) ? X : Y; // result returned by reference

}

void max3( int X, int Y, int *Larger )

{

*Larger = (X > Y) ? X : Y; // result returned by pointer

}

Structures

struct Student

{

char name[30];

int section;

float total_points;

};

Student class[30];

Student *ptr = class;

class[0].name is the same as ptr-> name

Initialization:

Student Ali = {“Ali Ahmed”, 8, 592.5};

Structures may be copied with “=”

Structures may be passed to functions by value

Structures may be returned from functions

Structures may be nested

Arrays of structures may be defined

Page 6: Ds lab handouts

Data Structures Lab Handouts 6

C++ Classes

The class is the capsule that is used to encapsulate an abstract data type.

# A class defines a new data type. You can create many objects of this type.

# A class is composed of one or more members.

# Members are:

o data items (members)

o functions (member functions)

# Class definition usually placed in an include (.h) file for ease of use.

A Complex Number Class

#include <iostream>

#include <math.h>

using namespace std;

class Complex

{ private:

float re;

float im;

public:

Complex(float r,float i) {re = r; im = i;}

Complex(float r) {re = r; im = 0.0;}

~Complex() {};

double Magnitude() // calculate magnitude

{

return sqrt(re*re + Imag()*Imag()); }

float Real() {return re;} // return real part

float Imag() {return im;} // return imaginary part

Complex operator+(Complex b)

{return Complex(re + b.re, im + b.im);}

Complex operator=(Complex b)

{re = b.re;im = b.im; return *this;}

};

Page 7: Ds lab handouts

Data Structures Lab Handouts 7

int main()

{

Complex a(1.0,1.0);

Complex *b = new Complex(5.0);

Complex c(0,0);

cout << "a real = " << a.Real() << “ a imaginary = “ << a.Imag() << endl;

cout << "b real = " << b->Real() << “ b imaginary = “ << b->Imag() << endl;

c = a + (*b);

cout << "c real = " << c.Real() << “ c imaginary = “ << c.Imag() << endl;

delete b;

return 0;

}

Exercise:

Add a function to multiply two complex numbers using operator overloading.

Page 8: Ds lab handouts

Data Structures Lab Handouts 8

Function Templates

Function templates are special functions that can operate with generic types. This allows

us to create a function template whose functionality can be adapted to more than one type

without repeating the entire code for each type.

In C++ this can be achieved using template parameters. A template parameter is a special

kind of parameter that can be used to pass a type as argument: just like regular function

parameters can be used to pass values to a function, template parameters allow to pass also

types to a function. These function templates can use these parameters as if they were any

other regular type.

The format for declaring function templates with type parameters is:

template <class identifier> function_declaration;

Example:

// function template

#include <iostream>

using namespace std;

template <class T>

T GetMax (T a, T b)

{

T result;

result = (a>b)? a : b;

return (result);

}

int main () {

int i=5, j=6, k;

long l=10, m=5, n;

k=GetMax<int>(i, j);

n=GetMax<long>(l, m);

cout << k << endl;

cout << n << endl;

return 0;

}

Page 9: Ds lab handouts

Data Structures Lab Handouts 9

Class Templates

We also have the possibility to write class templates, so that a class can have members that

use template parameters as types. For example:

template <class T>

class mypair

{

T values [2];

public:

mypair (T first, T second)

{

values[0]=first; values[1]=second;

}

};

This class serves to store two elements of any valid type. For example, if we wanted to

declare an object of this class to store two integer values of type int with the values 115

and 36 we would write:

mypair<int> myobject (115, 36);

this same class would also be used to create an object to store any other type:

mypair<double> myfloats (3.0, 2.18);

Page 10: Ds lab handouts

Data Structures Lab Handouts 10

Class Template Example 1

#include <iostream>

using namespace std;

template <class T>

class mypair

{

T a, b;

public:

mypair (T first, T second)

{a=first; b=second;}

T getmax ();

};

template <class T>

T mypair<T>::getmax ()

{

T retval;

retval = a>b? a : b;

return retval;

}

int main ()

{

mypair <int> myobject (100, 75);

cout << myobject.getmax();

return 0;

}

Exercise:

Add a function to compute minimum of two numbers in the above class.

Page 11: Ds lab handouts

Data Structures Lab Handouts 11

Class Template Example 2

#include <iostream>

using namespace std;

template <class T, int N>

class mysequence

{

T memblock [N];

public:

void setmember (int x, T value);

T getmember (int x);

};

template <class T, int N>

void mysequence<T,N>::setmember (int x, T value)

{

memblock[x]=value;

}

template <class T, int N>

T mysequence<T, N>::getmember (int x)

{

return memblock[x];

}

int main ()

{

mysequence <int,5> myints;

mysequence <double,5> myfloats;

myints.setmember (0,100);

myfloats.setmember (3, 3.1416);

cout << myints.getmember(0) << '\n';

cout << myfloats.getmember(3) << '\n';

return 0;

}

Page 12: Ds lab handouts

Data Structures Lab Handouts 12

File Input/Output

#include <fstream> // C++ file I/O

Files are classified as containing either text (i.e. characters) or binary data

May read and write numbers from/to text files: C++ does the necessary translations

Character Input with fstream

#include <fstream>

ifstream infile; // define infile

infile.open( “MyData” ); // open “MyData” file

if( !infile )

cout << “Can’t open ” << “MyData” << endl;

infile >> chr; // read character from “MyData” file into chr

infile.close( ); // close “MyData” file

Useful Functions for Character Input

infile.ignore( n ); // skip next n input characters

chr = infile.get( ); // same as infile >> chr

while( infile.get( ) != ‘\n’ ) ... // loop until end of line

while( infile.get( ) != EOF ) ... // loop until end of file

while( infile >> chr ) ... // loop until end of file

Page 13: Ds lab handouts

Data Structures Lab Handouts 13

Character Output with fstream

#include <fstream>

ofstream outfile( “MyOut” ); // define & open outfile

outfile << chr; // write chr to “MyOut” file

outfile.put( chr ); // same as outfile << chr

outfile.close( ); // close “MyOut” file

Numeric I/O with Text File and fstream

If numeric data is read to/written from a variable of numeric type, then >> translates the

data into the appropriate numeric representation

Example:

If “MyData” file contains

5280 2.718 3.141592653

Then

int ftPerMile; float e; double pi;

infile >> ftPerMile >> e >> pi;

stores input as int, float, and double

Page 14: Ds lab handouts

Data Structures Lab Handouts 14

Example: To count number of characters in a text file.

#include <iostream>

#include <fstream>

using namespace std;

int main(void)

{

ofstream outFile;

outFile.open("fout.txt");

ifstream inFile("fin.txt");

char ch;

int count = 0;

while(inFile.get(ch))

{

outFile << ch;

count++;

}

outFile << "\n\n Character count = " << count << endl;

inFile.close();

outFile.close();

return 0;

}

Page 15: Ds lab handouts

Data Structures Lab Handouts 15

Lab Exercise 1.1

a) Declare a class named House for a real estate locator service. The following information

should be included:

Owner: (a string of up to 20 characters)

Address: (a string of up to 20 characters)

Bedrooms: (an integer)

Price (floating point)

b) Declare available to be an array of 100 objects of class House.

c) Write a function to read values into the members of an object of House.

d) Write a driver program to test the data structures and the functions you have developed.

The driver program should read in house entries into the available array. After the code

for entering the data, you should write code to output the data that you have entered to

verify that it is correct.

Your program should look like this:

Enter Owner : M. Khan

Enter Address : G-9, Islamabad

Number of Bedrooms ? : 4

Price : 4500000

Enter another house? N

The output should look like:

Owner Address Bedrooms Price

M. Khan G-9, Islamabad 4 4500000

Page 16: Ds lab handouts

Data Structures Lab Handouts 16

Extra Credit:

The real estate company is very happy with the program that was developed in the earlier

to track their listings. Now they want to add some features to the processing.

Additional features:

- Search for a house that meets a potential buyer's specifications for the following:

# The price is not more than a specified amount

# The size is not less than a specified number of bedrooms

# The house with lowest price

# The largest house (with maximum number of bedrooms)

# In a given city

# With best ratio price/size

# The user may enter a "?" to indicate no preference.

- Print all the entries that meet the buyer’s need.

Page 17: Ds lab handouts

Data Structures Lab Handouts 17

Lab Exercise 1.2

Assume that a file contains the midterm1, midterm2 and final exam scores and names of

students of a class. Write a C++ program to read the input file and produce an output file

containing the original and average scores for each student. Suppose that the weights of

the exams are as follows:

midterm1 – 25%

midterm2 – 25%

final – 50%.

The average score of a student is calculated using the formula:

FINMTMT 5.0225.0125.0 !!

Solution:

#include <iostream>

#include <fstream>

using namespace std;

int main ( )

{ char name[10];

float mt1, mt2, final, avg;

ifstream fin ; //Create file input stream object

ofstream fout ; //Create file output stream object

fin.open ( "input.dat") ; //Open input file

fout.open ( "output.dat"); //Open output file

while (!fin.eof()) //Read data from input file

{

fin >> name >> mt1 >> mt2 >> final;

avg = 0.25*mt1 + 0.25*mt2 + 0.5*final ;

fout << name << '\t' << avg << endl ; //Write result to output file

}

fin.close ( ) ; //Close input file

fout.close ( ) ; //Close output file }

Page 18: Ds lab handouts

Data Structures Lab Handouts 18

Exercise 1.3

You will write a student grades "database" program. It will read data of students from a

file and will let the user perform various operations on the data. You will have to store the

student data in an array of objects.

Input:

The input file will look like:

4

3

Hassan Khan 99 87 90

Sara Nazir 90 98 99

Ali Zaidi 55 43 0

Raza Ahmad 100 100 100

That is:

number of students

number of grades (per student)

Student name grade grade ... grade

Student name grade grade ... grade

Data structure:

You will store all the information in an array of "student" objects. You may use the

following class definition:

class student {

private:

char name[30];

int lab[10];

float average;

public:

.

.

.

};

Page 19: Ds lab handouts

Data Structures Lab Handouts 19

Your program should work as follows:

# Ask the user for the filename and open the file.

# Read in the input from the file and store it in the student array.

# Compute and store an average for every student.

# Go into a menu loop giving the user the following options:

1. Print all user names, all grades, and averages.

2. Find a student and print his/her information.

3. Quit.

# For option 1 the user doesn't have to give you any extra information.

# For option 2, finding a student, your program must ask the user for the name of the

student he/she wishes to find; read in the name; perform a sequential search for that

name; and if found, print all that student's info.

Page 20: Ds lab handouts

Data Structures Lab Handouts 20

Lab 2

Implementation of Stack

Stack ADT Operations

Initialize -- Sets stack to an empty state.

IsEmpty -- Determines whether the stack is currently empty.

IsFull -- Determines whether the stack is currently full.

Push (ItemType newItem) -- Adds newItem to the top of the stack.

Pop (ItemType& item) -- Removes the item at the top of the stack and returns it in item.

Implementation of Stack Using Static Array

//----------------------------------------------------------

// SPECIFICATION FILE (stack.h)

//----------------------------------------------------------

#define MAX_ITEMS 100

typedef int ItemType;

class Stack {

public:

Stack ( ); // Default constructor.

int IsEmpty( ) const;

int IsFull( ) const;

void Push( ItemType newItem );

void Pop( ItemType& item ); // item is a copy of removed element.

private:

int top;

ItemType items[MAX_ITEMS]; // array of ItemType

};

Page 21: Ds lab handouts

Data Structures Lab Handouts 21

//-------------------------------------------------------

// IMPLEMENTATION FILE (stack.cpp)

//------------------------------------------------------

// Private data members of class:

// int top;

// ItemType items[MAX_ITEMS];

//-------------------------------------------------------

#include “stack.h”

Stack::Stack ( ) // Default Constructor

{

top = -1;

}

//----------------------------------------------------------

int Stack::IsEmpty( ) const

{

return ( top == -1 );

}

//----------------------------------------------------------

int Stack::IsFull( ) const

{

return ( top == MAX_ITEMS-1 );

}

//----------------------------------------------------------

void Stack::Push ( ItemType newItem )

{

if (IsFull())

{

cout << “Stack Overflow” << endl;

exit(1);

}

top++;

items[top] = newItem;

}

Page 22: Ds lab handouts

Data Structures Lab Handouts 22

//----------------------------------------------------------

void Stack::Pop ( ItemType& item )

{

if (IsEmpty())

{

cout << “Stack Underflow” << endl;

exit(1);

}

item = items[top];

top--;

}

//----------------------------------------------------------

// DRIVER FILE (driver.cpp)

//----------------------------------------------------------

#include <iostream>

#include <stdlib.h>

#include “stack.cpp”

using namespace std;

int main()

{

Stack s;

int item;

for (int i = 0; i < 20; i++)

s.Push(i);

for (i = 0; i < 20; i++)

{ s.Pop(item);

cout << item << endl;

}

return 0;

}

Page 23: Ds lab handouts

Data Structures Lab Handouts 23

Dynamic Implementation of Stack

Stack Using Class Template and Dynamic Array

# The construct that allows us to create a class of undetermined type is called a template.

# A class template allows the compiler to generate multiple versions of a class type by

using type parameters.

# The formal parameter appears in the class template definition, and the actual parameter

appears in the client code. Both are enclosed in pointed brackets, < >.

template<class ItemType>

class Stack {

public:

Stack ( );

Stack ( int max ); // PARAMETERIZED CONSTRUCTOR

~Stack ( ) ; // DESTRUCTOR . . .

int IsEmpty( ) const;

int IsFull( ) const;

void Push( ItemType newItem );

void Pop( ItemType& item );

private:

int top;

int maxStack;

ItemType* items; // DYNAMIC ARRAY IMPLEMENTATION

};

Page 24: Ds lab handouts

Data Structures Lab Handouts 24

//-----------------------------------------------------------------------------

// CLASS TEMPLATE IMPLEMENTATION FILE (stack.cpp)

//-------------------------------------------------------------------------------

#include “stack.h”

template<class ItemType>

Stack<ItemType>::Stack( ) //DEFAULT CONSTRUCTOR

{

maxStack = 500;

top = -1;

items = new ItemType[500]; // dynamically allocates array

}

template<class ItemType>

Stack<ItemType>::Stack( int max ) // PARAMETERIZED

{

maxStack = max;

top = -1;

items = new ItemType[max]; // dynamically allocates array

}

template<class ItemType>

Stack<ItemType>::~Stack( )

{

delete [ ] items; // deallocates array

}

template<class ItemType>

int Stack<ItemType>::IsEmpty( )

{

return (top == - 1);

}

template<class ItemType>

int Stack<ItemType>::IsFull( )

{

return (top == maxStack - 1);

}

Page 25: Ds lab handouts

Data Structures Lab Handouts 25

template <class ItemType>

void Stack<ItemType>::Push (ItemType newItem )

{

if (IsFull())

{ cout << “Stack Overflow” << endl;

exit(1);

}

top++;

items[top] = newItem;

}

template<class ItemType>

void Stack<ItemType>::Pop (ItemType& item )

{

if (IsEmpty())

{ cout << “Stack Underflow” << endl;

exit(1);

}

item = items[top];

top--;

}

//----------------Driver Program ------Using Class Template--------------------------------

#include <iostream>

#include “stack.cpp”

using namespace std;

int main ()

{

Stack<int> IntStack;

Stack<float> FloatStack;

int data;

float val;

IntStack.Push(35);

FloatStack.Push(3.1415927);

IntStack.Pop(data);

cout << data << endl;

FloatStack.Pop(val);

cout << val << endl;

return 0; }

Page 26: Ds lab handouts

Data Structures Lab Handouts 26

Exercise 2

Use the Stack class to solve the following problems:

Infix to Postfix Conversion

The input for this problem is an infix expression (with or without parenthesis). The

operand should be single letter digits and valid operators are +, -, * and /. The output

is the postfix version of the expression.

Postfix Evaluation

Evaluate a valid postfix expression and display the result.

Page 27: Ds lab handouts

Data Structures Lab Handouts 27

Lab 3

Recursion

Recursive Functions

A recursive function is one that calls itself.

Example 1: Calculating a Factorial

Factorials are often used in statistical calculations. The factorial of n, written as n! is equal

to the product of n(n-1)(n-2)...(1). For example 4! is equal to 4 × 3 × 2 × 1 = 24. There is

an obvious way to do this calculation using a loop, but we can also do it recursively.

Let's consider the definition of a factorial in a slightly different way:

# if n = 0, n! is equal to 1.

# if n > 0, n! is equal to n × ((n-1)!)

An implementation of recursive factorial function

#include <iostream>

#include <conio.h>

using namespace std;

int fact(int n)

{ if (n == 0)

return 1;

else

return n * fact(n - 1);

}

int main( )

{

cout << fact(5) << endl;

getch();

return 0;

}

Page 28: Ds lab handouts

Data Structures Lab Handouts 28

Example 2: Reversing the String

This function takes a series of characters and outputs them in reverse order.

#include <iostream>

#include <conio.h>

using namespace std;

void rev( )

{ char ch;

cin.get(ch);

if (ch != '\n')

{ rev();

cout.put(ch);

}

}

int main( )

{

rev();

getch();

return 0;

}

Example 3: Computing the Power

int Power(int X, int N)

{

if( N == 0 )

return 1;

else

return Power( X, N-1) * X;

}

Page 29: Ds lab handouts

Data Structures Lab Handouts 29

Example 4: Computing the Ackermann Function

int Ackermann(int m, int n)

{

if(m==0)

return n+1;

else if (m>0 && n==0)

return Ackermann(m-1,1);

else if (m>0 && n>0)

return Ackermann( m-1, Ackermann(m, n-1));

}

Exercise 3:

o Write a function in C++ using Recursion to print numbers from n to 0.

o Write a function in C++ using Recursion to compute binomial coefficients C(n, k)

using the recursive definition:

C(n,n) = 1

C(n,0) = 1

C(n,k) = C(n-1, k-1) + C(n-1,k) for (0<k<n) and n>1

o Write a function in C++ using Recursion to check if a number n is prime. (You have

to check whether n is divisible by any number below n)

Page 30: Ds lab handouts

Data Structures Lab Handouts 30

Lab 4

Implementation of Queue

Queue ADT Operations

- Initialize -- Sets queue to an empty state.

- IsEmpty -- Determines whether the queue is currently empty.

- IsFull -- Determines whether the queue is currently full.

- Insert (ItemType newItem) -- Adds newItem to the rear of the queue.

- Remove (ItemType& item) -- Removes the item at the front of the queue and returns it

in item.

Implementation of Queue Using Circular Arrays

Given

# an array Items[0:N-1] consisting of N items

# two indices Front and Rear, that designate positions in the Items array

We can use the following assignments to increment the indices so that they always wrap

around after falling off the high end of the array.

front = (front + 1) % N

rear = (rear + 1) % N

//--------------------------------------------------------

// CLASS DEFINITION FOR QUEUE

//--------------------------------------------------------

#define maxQue 100

typedef int ItemType;

class Queue

{

private:

ItemType items[maxQue];

int front, rear, count;

public:

Queue ();

int IsEmpty ();

int IsFull ();

void Insert (ItemType newItem);

void Remove (ItemType &item);

};

Page 31: Ds lab handouts

Data Structures Lab Handouts 31

Queue::Queue ()

{

count = 0;

front = 0;

rear = 0;

}

int Queue::IsEmpty ()

{

return (count == 0);

}

int Queue::IsFull ()

{

return (count == maxQue);

}

void Queue::Insert (ItemType newItem)

{

if (IsFull())

cout << "Over Flow";

else

{ items[rear] = newItem;

rear = (rear + 1) % maxQue;

++count;

}

}

void Queue::Remove (ItemType &item)

{

if (IsEmpty())

cout << "Under Flow";

else

{ item = Items[front];

front = (front + 1) % maxQue;

--count;

}

}

Exercise:

Write a driver program to insert 10 numbers in a queue and then remove and print the

numbers.

Page 32: Ds lab handouts

Data Structures Lab Handouts 32

Dynamic Implementation of Queue

Queue Using Template and Dynamic Array

//-----------------------------------------------------------------------

// CLASS TEMPLATE DEFINITION FOR QUEUE

//-----------------------------------------------------------------------

template<class ItemType>

class Que {

public:

Que( );

Que( int max ); // PARAMETERIZED CONSTRUCTOR

~Que( ) ; // DESTRUCTOR . . .

int IsFull( ) const;

int IsEmpty( ) const;

void Insert( ItemType newItem );

void Remove( ItemType& item );

privat

int front;

int rear;

int maxQue;

int count;

ItemType* items; // DYNAMIC ARRAY IMPLEMENTATION

};

//-----------------------------------------------------------------------

// CLASS TEMPLATE IMPLEMENTATION

//-----------------------------------------------------------------------

template<class ItemType>

Que<ItemType>::Que() // Default Constructor

{

maxQue = 501;

front = 0;

rear = 0;

count = 0;

items = new ItemType[maxQue]; // dynamically allocates

}

Page 33: Ds lab handouts

Data Structures Lab Handouts 33

template<class ItemType>

Que<ItemType>::Que( int max )

// PARAMETERIZED Constructor

{

maxQue = max + 1;

front = 0;

rear = 0;

count = 0;

items = new ItemType[maxQue]; // dynamically allocates

}

template<class ItemType>

Que<ItemType>::~Que( )

{

delete [ ] items; // deallocates array

}

template<class ItemType>

int Que<ItemType>::IsEmpty( ) const

{

return (count == 0);

}

template<class ItemType>

int Que<ItemType>::IsFull( ) const

{

return ( count == maxQue );

}

template<class ItemType>

void Que<ItemType>::Insert( ItemType newItem )

{

if (IsFull())

cout << "Over Flow";

else

{ items[rear] = newItem;

rear = (rear + 1) % maxQue;

++count;

}

}

Page 34: Ds lab handouts

Data Structures Lab Handouts 34

template<class ItemType>

void Que<ItemType>::Remove( ItemType& item )

{

if (IsEmpty())

cout << "Under Flow";

else

{ item = items[front];

front = (front + 1) % maxQue;

--count;

}

}

Write a driver program to insert 10 numbers in a queue and then remove and print the

numbers.

Exercise 4

Suppose a deque is represented by an array of N elements. The two ends of the deque are

denoted as left and right and elements always extend from left to right. Using this model of

a deque write four routines insertLeft, removeLeft, insertRight and removeRight to

insert/remove an element to/from the deque from left and right ends. Make sure to check

for overflow and underflow conditions.

Page 35: Ds lab handouts

Data Structures Lab Handouts 35

Lab 5

Implementation of Priority Queue

Sometimes it is not enough just do FIFO ordering. We may want to give some items a

higher priority than other items. These should be serviced before lower priority even if

they arrived later. Such a data structure is called a priority Queue.

Two major ways to implement a priority queue are:

–insert items in a sorted order and always remove the front

–insert in unordered order and search list on remove

–either way, time is same

•either adding data takes time and removing is quick, or

•adding data is quick and removing takes time

Use the Queue class to implement the following Priority Queue ADT to handle 10

different priority levels.

The Priority Queue ADT

A Priority Queue, PQ, is a finite collection of items of type T on which following

operations are defined:

1. Initialize the priority queue, PQ, to be the empty priority queue.

2. Determine whether or not the priority queue, PQ, is empty.

3. Determine whether or not the priority queue, PQ, is full.

4. If PQ is not full, insert a new item, X, into the priority queue, PQ, according to its

priority level.

5. If PQ is not empty, remove from the priority queue, PQ, an item, X, of highest priority

in PQ.

Page 36: Ds lab handouts

Data Structures Lab Handouts 36

Lab 6

Implementation of Linked List

//-----------------------------------------------------------------------

// CLASS TEMPLATE DEFINITION FOR LINKED LIST

//---------------------------------------------------------------------

#include <iostream>

#include<conio.h>

using namespace std;

template<class ItemType>

class List

{

protected:

struct node {

ItemType info;

struct node *next;

};

typedef struct node *NODEPTR;

NODEPTR listptr;

public:

List();

~List();

ItemType emptyList();

void insertafter(ItemType oldvalue, ItemType newvalue);

void deleteItem(ItemType oldvalue);

void push(ItemType newvalue);

ItemType pop();

};

Page 37: Ds lab handouts

Data Structures Lab Handouts 37

//--------------------------------------------------------

// CLASS TEMPLATE IMPLEMENTATION

//--------------------------------------------------------

// Default Constructor that initializes a newly created list to empty list.

template<class ItemType>

List<ItemType>::List()

{

listptr = 0;

}

// Destructor traverses the nodes of a list, freeing them one by one.

template<class ItemType>

List<ItemType>::~List()

{

NODEPTR p, q;

if (emptyList())

exit(0);

for (p = listptr, q = p->next; p!=0; p = q, q = p->next)

delete p;

}

// searches for the first occurance of oldvalue in the list and inserts a new node with value

newvalue following the node containing oldvalue.

template<class ItemType>

void List<ItemType>::insertafter(ItemType oldvalue, ItemType newvalue)

{

NODEPTR p, q;

for (p = listptr; p != 0 && p->info != oldvalue; p = p->next)

;

if (p == 0)

{ cout << " ERROR: value sought is not in the list.";

exit(1);

}

q = new node;

q->info = newvalue;

q->next = p->next;

p->next = q;

}

Page 38: Ds lab handouts

Data Structures Lab Handouts 38

// Determines if the list is empty.

template<class ItemType>

ItemType List<ItemType>::emptyList()

{

return (listptr == 0);

}

// push(newvalue) adds a new node with a given value to the front of the list.//

template<class ItemType>

void List<ItemType>::push(ItemType newvalue)

{

NODEPTR p;

p = new node;

p->info = newvalue;

p->next = listptr;

listptr = p;

}

// deletes the first node containing the value oldvalue from the list.

template<class ItemType>

void List<ItemType>::deleteItem(ItemType oldvalue)

{

NODEPTR p, q;

for (q = 0, p = listptr; p != 0 && p->info != oldvalue; q = p, p = p->next)

;

if (p == 0)

{ cout << " ERROR: value sought is not in the list.";

exit(1);

}

if (q == 0) listptr = p->next;

else q->next = p->next;

delete p;

}

Page 39: Ds lab handouts

Data Structures Lab Handouts 39

// pop deletes the first node of the list and returns its contents. //

template<class ItemType>

ItemType List<ItemType>::pop()

{

NODEPTR p;

ItemType x;

if (emptyList())

{ cout << " ERROR: the list is empty.";

exit(1);

}

p = listptr;

listptr = p->next;

x = p->info;

delete p;

return x;

}

int main()

{

List<int> l;

l.push(87);

cout << l.pop()<<endl;

getch();

return 0;

}

Exercise 6.1

Write a menu driven program to test the linked list class.

Page 40: Ds lab handouts

Data Structures Lab Handouts 40

Exercise 6.2

Assume the following specifications of a node of linked structure and the class

struct Node

{

int info; Node* next;

};

class LinkedStr

{

private:

Node* ptr;

public:

// Constructor. Initiallize ptr to NULL.

LinkedStr();

// Destructor. Remove all the nodes from dynamic memory

~LinkedStr();

// Create a linked structure of length len pointed to by ptr.

// The values of the info part are input from the keyboard

void makeStr(int len);

// Display all the elements of the linked structure pointed to by ptr on the screen.

void displayStr();

// Remove the first element of the linked structure pointed to by ptr.

// If the structure is empty, do nothing

void removeFirst();

// Remove the first element of the linked structure pointed to by ptr.

// If the structure is empty, do nothing

void removeLast();

// Remove the first element of the linked structure with an info field equal to k.

// If no such element or the list is empty, do nothing

void remove(int k); };

Write the implementation of the class LinkedStr. Write a driver program to test the

implementation.

Page 41: Ds lab handouts

Data Structures Lab Handouts 41

Lab 7

Application of Linked List

Polynomial may be represented as a linked list as follows: for every term in the

polynomial there is one entry in the linked list consisting of the term's coefficient and

degree. The entries are ordered according to ASCENDING values of degree; zero-

coefficient terms are not stored. For example, the following polynomial (the symbol '^' is

used to mean 'raised to the power'): 4x^5 - 2x^3 + 2x +3 can be represented as the linked

list of terms: (3,0) -> (2,1) -> (-2,3) -> (4,5) where each term is a (coefficient, degree)

pair. Write a C++ class called Polynomial with the following functionality:

# Read the polynomials from a file.

# Addition of two polynomials.

# Multiplication of two polynomials.

# Evaluation of a polynomial at a given point.

Sample Output:

Enter the name of the polynomial file => ptest1

4.0x^5 + -2.0x^3 + 2.0x + 3.0

1. ADD polynomial

2. MULTIPLY polynomial

3. EVALUATE polynomial

4. QUIT

Enter choice # => 1

Enter the file containing the polynomial to add => ptest2

8.0x^4 + 4.0x^3 + -3.0x + 9.0

Sum: 4.0x^5 + 8.0x^4 + 2.0x^3 + -1.0x + 12.0

1. ADD polynomial

2. MULTIPLY polynomial

3. EVALUATE polynomial

4. QUIT

Enter choice # => 2

Enter the file containing the polynomial to multiply => ptest2

8.0x^4 + 4.0x^3 + -3.0x + 9.0

Product: 32.0x^9 + 16.0x^8 + -16.0x^7 + -20.0x^6 + 52.0x^5 + 38.0x^4 + -6.0x^3 + -

6.0x^2 + 9.0x + 27.0

Page 42: Ds lab handouts

Data Structures Lab Handouts 42

Lab 8

Implementation of Binary Trees

ADT of Binary Tree

ADT BinaryTree

{

Objects:

A finite set of nodes either empty or consisting of a root node, left BinaryTree and

right BinaryTree.

Operations:

BinaryTree ();

// Creates an empty BinaryTree

BinaryTree (ElementType info);

// Creates a single node BinaryTree with information info

BinaryTree (BinaryTree lbt, ElementType info, BinaryTree rbt);

// Creates a Binarytree whose left subtree is lbt, whose right subtree is rbt,

// and whose root node contain info.

Boolean IsEmpty();

// If number of elements in the BinaryTree is 0 return TRUE,

// otherwise return FALSE.

BinaryTree LChild();

// If IsEmpty(), return error, else return left subtree of *this

ElementType Data();

// If IsEmpty(), return error, else return data in the root node of *this

BinaryTree RChild();

// If IsEmpty(), return error, else return right subtree of *this

};

Page 43: Ds lab handouts

Data Structures Lab Handouts 43

Implicit Static Array Representaion

The n nodes of an almost complete binary tree can be numbered from 1 to n, so that the

number assigned to a left son is twice the number assigned to its father, and number

assigned to a right son is one more than twice the number assigned to its father.

In C++, arrays start from 0; therefore we'll number the nodes from 0 to n-1. The left son of

node at position p is at position 2p+1 and right son is at 2p+2. The root of the tree is at

position 0.

Node Representation

# define NUMNODES 500

struct TreeNode

{

int info;

int left, right, father;

};

TreeNode BT[NUMNODES];

Page 44: Ds lab handouts

Data Structures Lab Handouts 44

Dynamic Representation

struct Tree Node

{

int info;

TeeNode *left, *right, *father;

};

typedef TreeNode *NODEPTR;

If a tree is always traversed from top to bottom, father field is unnecessary.

The maketree() function, which allocates a node and sets it as the root of a single-node

binary tree may be written as:

NODEPTR maketree (int x)

{

NODEPTR p =new TreeNode;

p $ info = x;

p $ left = NULL;

p $ right = NULL;

return (p); }

The function setleft (p,x) sets a node with contents x as the left son of node(p).

void setleft (NODEPTR p, int x)

{

if (p == NULL)

cout << “Void Insertion”;

else if (p $ left != NULL)

cout << “Invalid Insertion”;

else

p $ left = maketree (x);

}

Page 45: Ds lab handouts

Data Structures Lab Handouts 45

Binary Tree Traversals in C++

Three C++ routines pretrav, intrav, and posttrav are given below. The parameter to each

routine is the pointer to the root node of a binary tree.

void pretrav (NODEPTR tree)

{

if (tree != NULL)

{

cout << tree $ info; /* visit the root */

pretrav (tree $ left);

pretrav (tree $ right);

}}

void intrav (NODEPTR tree)

{

if (tree != NULL)

{

intrav (tree $ left);

cout << tree $ info;

intrav (tree $ right);

}

}

void posttrav (NODEPTR tree)

{

if (tree != NULL)

{

posttrav (tree $ left);

posttrav (tree $ right);

cout << tree $ info;

}}

Page 46: Ds lab handouts

Data Structures Lab Handouts 46

Lab 9

Implementation of Binary Search Trees

#include <fstream>

using namespace std;

template< class ItemType >

struct TreeNode {

ItemType info; // Data member

TreeNode<ItemType>* left; // Pointer to left child

TreeNode<ItemType>* right; // Pointer to right child

};

template< class ItemType >

// BINARY SEARCH TREE SPECIFICATION

class TreeType {

public:

TreeType ( ); // constructor

~TreeType ( ); // destructor

bool IsEmpty ( ) const;

bool IsFull ( ) const;

int NumberOfNodes ( ) const;

void InsertItem ( ItemType item );

void DeleteItem (ItemType item );

void RetrieveItem ( ItemType& item, bool& found );

void PrintTree (ofstream& outFile) ;

void PrintHelper ( TreeNode<ItemType>* ptr, ofstream& outFile ) ;

void InsertHelper ( TreeNode<ItemType>*& ptr, ItemType item ) ;

void RetrieveHelper ( TreeNode<ItemType>* ptr, ItemType& item, bool& found ) ;

void DestroyHelper ( TreeNode<ItemType>* ptr ) ;

private:

TreeNode<ItemType>* root;

};

Page 47: Ds lab handouts

Data Structures Lab Handouts 47

// BINARY SEARCH TREE IMPLEMENTATION

// OF MEMBER FUNCTIONS AND THEIR HELPER FUNCTIONS

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - template< class ItemType >

TreeType<ItemType> :: TreeType ( ) // constructor

{

root = NULL ;

}

template< class ItemType >

bool TreeType<ItemType> :: IsEmpty( ) const

{

return ( root == NULL ) ;

}

template< class ItemType >

void TreeType<ItemType> :: RetrieveItem ( ItemType& item, bool& found )

{

RetrieveHelper ( root, item, found ) ;

}

template< class ItemType >

void TreeType<ItemType> :: RetrieveHelper ( TreeNode<ItemType>* ptr,

ItemType& item, bool& found)

{ if ( ptr == NULL )

found = false ; else if ( item < ptr->info ) // GO LEFT

RetrieveHelper( ptr->left , item, found ) ;

else if ( item > ptr->info ) // GO RIGHT

RetrieveHelper( ptr->right , item, found ) ;

else

{ item = ptr->info ;

found = true ; }

}

template< class ItemType >

void TreeType<ItemType> :: InsertItem ( ItemType item )

{

InsertHelper ( root, item ) ;

}

Page 48: Ds lab handouts

Data Structures Lab Handouts 48

template< class ItemType >

void TreeType<ItemType> :: InsertHelper ( TreeNode<ItemType>*& ptr, ItemType

item )

{ if ( ptr == NULL )

{ // INSERT item HERE AS LEAF

ptr = new TreeNode<ItemType> ;

ptr->right = NULL ;

ptr->left = NULL ;

ptr->info = item ;

}

else if ( item < ptr->info ) // GO LEFT

InsertHelper( ptr->left , item ) ;

else if ( item > ptr->info ) // GO RIGHT

InsertHelper( ptr->right , item ) ;

}

template< class ItemType >

void TreeType<ItemType> :: PrintTree ( ofstream& outFile )

{

PrintHelper ( root, outFile ) ;

}

template< class ItemType >

void TreeType<ItemType> :: PrintHelper ( TreeNode<ItemType>* ptr, ofstream&

outFile )

{ if ( ptr != NULL )

{ PrintHelper( ptr->left , outFile ) ; // Print left subtree

outFile << ptr->info ;

PrintHelper( ptr->right, outFile ) ; // Print right subtree

}

}

template< class ItemType >

TreeType<ItemType> :: ~TreeType ( ) // DESTRUCTOR

{

DestroyHelper ( root ) ;

}

Page 49: Ds lab handouts

Data Structures Lab Handouts 49

template< class ItemType >

void TreeType<ItemType> :: DestroyHelper ( TreeNode<ItemType>* ptr )

// Post: All nodes of the tree pointed to by ptr are deallocated. { if ( ptr != NULL )

{

DestroyHelper ( ptr->left ) ;

DestroyHelper ( ptr->right ) ;

delete ptr ; }

}

// Driver Program

int main ()

{

TreeType <int> tree;

ofstream out("tree.txt");

int item = 1;

bool flag = false;

for(int i = 0; i < 10; i++)

tree.InsertItem(i);

tree.PrintTree(out);

tree.RetrieveItem(item, flag);

cout << flag << endl;

return 0;

}

Page 50: Ds lab handouts

Data Structures Lab Handouts 50

Lab 10

Implementation of Graphs

C++ Representation of Graphs

Suppose that the number of vertices in the graph is constant: that is, edges may be

added or deleted but vertices may not.

# A graph with 50 vertices could then be declared as follows:

#define MAXVERTEXS 50

struct vertex

{

/* information associated with each vertex */

};

struct edge

{

int adj;

/* information associated with each edge */

};

class Graph

{

private:

struct vertex vertices[MAXVERTEXS];

struct edge edges[MAXVERTEXS][MAXVERTEXS];

……

…….

};

Graph g;

Page 51: Ds lab handouts

Data Structures Lab Handouts 51

# Each vertex of the graph is represented by an integer between 0 and MAXVERTEXS-1

and the array field vertices represents the appropriate information assigned to each

vertex.

# The array field edges is a two-dimensional array representing every possible ordered

pair of vertices.

# The value of g.edges[i][j].adj is either TRUE or FALSE depending on whether or not

vertex j is adjacent to vertex i.

# The two-dimensional array g.edges[][].adj is called an adjacency matrix. In the case of

a weighted graph, each edge can also be assigned information.

# Frequently the vertices of a graph are numbered from 0 to MAXVERTEXS-1 and no

information is assigned to them. Also, we may be interested in the existence of edges

but not in any weights or other information about them. In such cases the graph could

be declared simply by

int adj[MAXVERTEXS][MAXVERTEXS];

# In effect, the graph is totally described by its adjacency matrix. We present the code for

the primitive operations just described in the case where a graph is described by its

adjacency matrix.

join (int adj[][MAXVERTEXS], int vertex1, int vertex2)

{

/* add an edge from vertex1 to vertex2 */

adj[vertex1][vertex2] = TRUE;

}

remv (int adj[][MAXVERTEXS], int vertex1, int vertex2)

{

/* delete edge from vertex1 to vertex2 if one exists */

adj[vertex1][vertex2] = FALSE;

}

adjacent (int adj[][MAXVERTEXS], int vertex1, int vertex2)

{

return ((adj[vertex1][vertex2]==TRUE) ? TRUE : FALSE);

}

Page 52: Ds lab handouts

Data Structures Lab Handouts 52

C++ Representation of Weighted Graphs

A weighted graph with a fixed number of vertices may be declared by

struct edge

{

int adj;

int weight; };

struct edge g[MAXVERTEXS][MAXVERTEXS];

# The routine joinwt, which adds an edge from vertex1 to vertex2 with a given weight

wt, may be coded as follows:

void joinwt (struct edge g[] [MAXVERTEXS], int vertex1, int vertex2, int wt)

{

g[vertex1][vertex2].adj = TRUE;

g[vertex1][vertex2].weight = wt;

}

Exercise 10:Implement in C++ a class for a Weighted Graph using adjacency matrix representation.

Page 53: Ds lab handouts

Data Structures Lab Handouts 53

Lab 11

Application of Graphs

Exercise 11: Implement Breadth-First and Depth-First search algorithms for a graph.

Depth-First Search

# We begin by visiting the start vertex v. Next an unvisited vertex w adjacent to v is

selected, and a depth-first search from w is initiated.

# When a vertex u is reached such that all its adjacent vertices have been visited, we back

up to the last vertex visited that has an unvisited w adjacent to it and initiates a depth-

first search from w.

Depth-First-Search

{

Boolean visited[n];

// initially, no vertex has been visited

for (i = 0; i < n; i++)

visited[i] = FALSE;

// start search at vertex 0

DFS (0);

}

DFS (v)

// Visit all previously unvisited vertices that are reachable from vertex v

{

visited[v] = TRUE;

for (each vertex w adjacent to v)

if ( !visited[w])

DFS(w);

}

Page 54: Ds lab handouts

Data Structures Lab Handouts 54

Breadth-First Search

# In a breadth-first search, we begin by visiting the start vertex v. Next all unvisited

vertices adjacent to v are visited.

# Unvisited vertices adjacent to these newly visited vertices are then visited, and so on.

BFS(v)

// A BFS of the graph is carried out starting at vertex v.

// visited[i] is set to TRUE when v is visited. The algorithm uses a queue.

{

Boolean visited[n];

Queue q;

// initially, no vertex has been visited

for (i = 0; i < n; i++)

visited[i] = FALSE;

visited[v] = TRUE;

q.insert(v); // add vertex v to the queue

while (!q.IsEmpty())

{

v = q.delete();

for (all vertex w adjacent to v)

{ if ( !visited[w])

{ q.insert(w);

visited[w] = TRUE;

}

}

}

}

Exercise 11:

Implement the Dijkstra’s Shortest Path Algorithm to generate shortest paths for a given

directed graph.

Page 55: Ds lab handouts

Data Structures Lab Handouts 55

Lab 12-13

Using Standard Template Library (STL)

Overview

The Standard Library is a fundamental part of the C++ Standard. It provides C++

programmers with a comprehensive set of efficiently implemented tools and facilities that

can be used for most types of applications.

The Standard Template Library, or STL, is a C++ library of container classes, algorithms,

and iterators; it provides many of the basic algorithms and data structures of computer

science.

The STL is a generic library, meaning that its components are heavily parameterized:

almost every component in the STL is a template.

1 - GETTING STARTED

There are three components that make up STL. These are containers, algorithms, and

iterators. Each will be discussed below.

1. Containers. Containers embody the data structures supported by STL. It

accomplishes this by defining a template class for each of these data structures

There are functions in the classes that allow the efficient manipulation of its

elements. The following is a list of the containers.

1. vector - allows us to define dynamic arrays.

2. deque - doubly ended queues.

3. queue - supports a queue. Officially not a container - it is an adapter, but we

can think of it as a container.

4. list - allows us to create linked lists.

5. stack - implements a pushdown stack.

6. maps and multimaps - allows us to create sorted tree structures. This gives us

quick access to data stored in table form. The data may be accessed using a

key.

Page 56: Ds lab handouts

Data Structures Lab Handouts 56

7. set and multi-set - allows us to organize a set of data in a tree structure.

Note: Most often used are vectors and maps.

2. Algorithms. There are a set of algorithms supplied to manipulate data in

containers. Sort, lower bound (a binary search) and replace are examples of

algorithms. A good rule: if the container contains a function that does the same

thing as a function in the algorithms, use the function in the container class.

3. Iterators. Iterators are a fancy word for pointers. They are pointers relative to

containers. Because of the structure of the various containers they are not always as

powerful as the standard C++ pointers.

Example 1:

Let's consider a simple example, one where we wish to create a set of integers and then

shuffle them into random order:

#include <vector>

#include <algorithm>

#include <iostream>

#include <conio.h>

using namespace std;

int main()

{

vector<int> v;

for (int i = 0; i < 25; i++)

v.push_back(i);

random_shuffle(v.begin(), v.end());

for (int j = 0; j < 25; j++)

cout << v[j] << " ";

cout << endl;

getch();

return 0;

}

When run, this program produces output like:

6 11 9 23 18 12 17 24 20 15 4 22 10 5 1 19 13 3 14 16 0 8 21 2 7

Page 57: Ds lab handouts

Data Structures Lab Handouts 57

2 - VECTORS, LISTS, DEQUES, STACK

STL has different types of containers that are available for holding data, namely vectors,

lists, and deques.

# A vector is like a smart array. You can use [] to efficiently access any element in the

vector, and the vector grows on demand. But inserting into the middle of a vector is

expensive, because elements must be moved down, and growing the vector is costly

because it must be copied to another vector internally.

# A list is like a doubly-linked list that you've used before. Insertion or splicing of

subsequences is very efficient at any point in the list, and the list doesn't have to be

copied out. But looking up an arbitrary element is slow.

# A deque classically stands for "double-ended queue", but in STL means a combination

of a vector and a list. Indexing of arbitrary elements is supported, as are list operations

like efficiently popping the front item off a list.

Example 2.1:

#include <list>

#include <algorithm>

#include <iostream>

#include <conio.h>

using namespace std;

int main()

{

list<int> v;

for (int i = 0; i < 25; i++)

v.push_back(i);

for (int j = 0; j < 25; j++) {

cout << v.front() << " ";

v.pop_front();

}

cout << endl;

getch();

return 0;

}

Page 58: Ds lab handouts

Data Structures Lab Handouts 58

Example 2.2:

#include <algorithm>

#include <iostream>

#include <deque>

#include <conio.h>

using namespace std;

int main()

{

deque<int> v;

for (int i = 0; i < 25; i++)

v.push_back(i);

random_shuffle(v.begin(), v.end());

for (int j = 0; j < 25; j++) {

cout << v.front() << " ";

v.pop_front();

}

cout << endl;

getch();

return 0;

}

Page 59: Ds lab handouts

Data Structures Lab Handouts 59

Example 2.3:

One more worth mentioning data structure is stack. In STL a stack is based on a vector,

deque, or list. An example of stack usage is:

#include <iostream>

#include <stack>

#include <list>

#include <conio.h>

using namespace std;

int main()

{

stack<int, list<int> > stk;

for (int i = 1; i <= 10; i++)

stk.push(i);

while (!stk.empty()) {

cout << stk.top() << endl;

stk.pop();

}

getch();

return 0;

}

We declare the stack, specifying the underlying type (int), and the sort of list used to

represent the stack (list<int>).

Page 60: Ds lab handouts

Data Structures Lab Handouts 60

3 - BIT SETS

Another STL data structure is bit sets, offering space-efficient support for sets of bits.

Example 3:

#include <iostream>

#include <bitset>

#include <conio.h>

using namespace std;

int main()

{

bitset<16> b1("1011011110001011");

bitset<16> b2;

b2 = ~b1;

for (int i = b2.size() - 1; i >= 0; i--)

cout << b2[i];

cout << endl;

getch();

return 0;

}

Page 61: Ds lab handouts

Data Structures Lab Handouts 61

4 – ITERATORS

Iterators in STL are mechanisms for accessing data elements in containers and for cycling

through lists of elements.

Example 4:

#include <algorithm>

#include <vector>

#include <iostream>

#include <conio.h>

using namespace std;

const int N = 100;

int main()

{

vector<int> iv(N);

iv[50] = 37;

vector<int>::iterator iter = find(iv.begin(), iv.end(), 37);

if (iter == iv.end())

cout << "not found\n";

else

cout << "found at " << iter - iv.begin() << "\n";

getch();

return 0;

}

Page 62: Ds lab handouts

Data Structures Lab Handouts 62

5 - OPERATING ON SETS

STL also contains some algorithms for operating on ordered sets of data, illustrated by a

simple example:

Example 5:

#include <iostream>

#include <algorithm>

#include <vector>

#include <conio.h>

using namespace std;

int set1[] = {1, 2, 3};

int set2[] = {2, 3, 4};

vector<int> set3(10);

int main()

{

vector<int>::iterator first = set3.begin();

vector<int>::iterator last =

set_union(set1, set1 + 3, set2, set2 + 3, first);

while (first != last) {

cout << *first << " ";

first++;

}

cout << endl;

getch();

return 0;

}

Page 63: Ds lab handouts

Data Structures Lab Handouts 63

6 – FILLING

The fill() function fills a data structure with a specified value:

Example 6:

#include <algorithm>

#include <iostream>

#include <conio.h>

using namespace std;

int vec1[10];

int vec2[10];

int main()

{

fill(vec1, vec1 + 10, -1);

for (int i = 0; i < 10; i++)

cout << vec1[i] << " ";

cout << endl;

fill_n(vec2, 5, -1);

for (int j = 0; j < 10; j++)

cout << vec2[j] << " ";

cout << endl;

getch();

return 0;

}

fill() fills according to the specified iterator range, while fill_n() fills a specified number of

locations based on a starting iterator and a count. The results of running this program are:

-1 -1 -1 -1 -1 -1 -1 -1 -1 -1

-1 -1 -1 -1 -1 0 0 0 0 0

Page 64: Ds lab handouts

Data Structures Lab Handouts 64

7 – ACCUMULATING

Another simple algorithm that STL makes available is accumulation, for example

summing a set of numeric values. An example of this would be:

Example 7:

#include <iostream>

#include <numeric>

#include <conio.h>

using namespace std;

int vec[] = {1, 2, 3, 4, 5};

int main()

{

int sum = accumulate(vec, vec + 5, 0);

cout << sum << endl;

int prod = accumulate(vec, vec + 5, 1, times<int>());

cout << prod << endl;

getch();

return 0;

}

In this example, we specify iterators for a vector of integers, along with an initial value (0)

for doing the summation.

By default, the "+" operator is applied to the values in turn. Other operators can be used,

for example "*" in the second example. In this case the starting value is 1 rather than 0.

Page 65: Ds lab handouts

Data Structures Lab Handouts 65

Lab 14-15

Implementation of Sorting Techniques

The main objective of this lab is to compare the efficiency of different sorting

techniques we have studied in the course.

Implement the following sorting techniques and count number of comparisons and

exchanges.

1) Bubble Sort

2) Selection Sort

3) Insertion Sort

4) Heap Sort

# Run all the above techniques for the following values of N. Generate input data

randomly and vary the input size N as below:

N = 10, 100, 1000, 5000, 10000, 20000, 50000

# Present your results in tabular and graphical (line graph) form. The tabulated output

should have the following form:

Extra Credit Task:

Compute the actual execution time by reading the system clock.

N Bubble Sort Selection Sort Insertion Sort Heap Sort

Comp. Exch. Comp. Comp

.

Exch. Exch. Comp. Exch.

10

100

1000

5000

10000

20000

50000

Page 66: Ds lab handouts

Data Structures Lab Handouts 66

Bubble Sort

void Bubble( int x[], int n)

{

int hold, j, pass;

int switched = TRUE;

for (pass = 0; pass < n-1 && switched == TRUE; pass++)

{ // outer loop controls the number of passes

switched = FALSE;

for ( j = 0; j < n-pass-1; j++)

{

// inner loop controls each individual pass

if (x[j] > x [j+1]) // elements out of order

{

switched = TRUE;

hold = x[j]; // interchange j and j+1

x[j] = x [j+1];

x[j+1] = hold;

} // end if

} // end inner for loop

} // end outer for loop

} // end Bubble

Page 67: Ds lab handouts

Data Structures Lab Handouts 67

Insertion Sort

insertionsort (int x[], int n)

{

int j, k, y;

/* initially x[0] may be thought of as a sorted file of one element. After each

repetition of the following loop, the elements x[0] through x[k] are in order */

for (k=1; k<n; k++)

{

/* insert x[k] into sorted file */

y = x[k];

/* move down all elements greater than y */

for (j=k-1; j>=0 && y<x[j]; j++)

x[j+1] = x[j];

/* insert y at proper position */

x[j+1] = y;

}

}

Selection Sort

void Selectionsort(int x[], int n)

{

int key;

for(int a=0; a < n; a++)

{ key=a;

for(int b=a+1; b < n; b++)

{

if(x[b] < x[key]) key=b;

}

if (key > a)

{ int temp = x[a];

x[a] = x[key];

x[key] = temp;

}

}

}

Heap Sort Use STL to implement Heap sort.

Page 68: Ds lab handouts

Data Structures Lab Handouts 68

Sorting using STL

We will now start discussing some of the actual STL algorithms that can be applied to data

structures. One of these is sorting.

Example:

Consider a simple example of a String class, and a vector of Strings:

#include <vector>

#include <algorithm>

#include <iostream>

#include <assert>

#include <string>

#include <conio.h>

using namespace std;

class String {

char* str;

public:

String()

{

str = 0;

}

String(char* s)

{

str = strdup(s);

assert(str);

}

int operator<(const String& s) const

{

return strcmp(str, s.str) < 0;

}

operator char*()

{

return str;

}

};

Page 69: Ds lab handouts

Data Structures Lab Handouts 69

char* list[] = {"epsilon", "omega", "theta", "rho",

"alpha", "beta", "phi", "gamma", "delta"};

const int N = sizeof(list) / sizeof(char*);

int main()

{

int i, j;

vector<String> v;

for (i = 0; i < N; i++)

v.push_back(String(list[i]));

random_shuffle(v.begin(), v.end());

for (j = 0; j < N; j++)

cout << v[j] << " ";

cout << endl;

sort(v.begin(), v.end());

for (j = 0; j < N; j++)

cout << v[j] << " ";

cout << endl;

getch();

return 0;

}

Output looks like:

phi delta beta theta omega alpha rho gamma epsilon

alpha beta delta epsilon gamma omega phi rho theta

Page 70: Ds lab handouts

Data Structures Lab Handouts 70

Computing Execution Time

#include <iostream>

#include <time.h>

#include <conio.h>

using namespace std;

int main ()

{

time_t start,end;

char szInput [25];

double dif;

time (&start);

cout << "Please, enter your name: ";

cin>> szInput;

time (&end);

dif = difftime (end,start);

cout <<"Hi "<< szInput ;

cout << " It took you "<< dif<< " seconds to type your name."<< endl;

getch();

return 0;

}

Page 71: Ds lab handouts

Data Structures Lab Handouts 71

Lab 16

Implementation of Searching Techniques

The main objective of this lab is to compare the efficiency of different searching

techniques we have studied in the course.

Implement the following searching techniques and count number of comparisons for

successful and unsuccessful search.

1. Sequential Search

2. Binary Search

Sequential Search

int Sequential( int x[], n, key)

{

for (int i = 0; i< n; i++)

if (key == x[i]) return (i);

return (-1);

}

N Sequential Search Binary Search

Successful Unsuccessful Successful Unsuccessful

10

100

1000

5000

10000

20000

50000

Page 72: Ds lab handouts

Data Structures Lab Handouts 72

Binary Search

int Binary( int x[], n, key)

{

int low = 0;

int hi = n-1;

while (low <= hi)

{

int mid = (low + hi) / 2;

if (key == x[mid])

return (mid);

if (key < x[mid])

hi = mid – 1;

else

low = mid + 1;

}

return –1;

}

Page 73: Ds lab handouts

Data Structures Lab Handouts 73

Searching using STL: MAPS

A map is something like an associative array or hash table, in that each element consists of

a key and an associated value. A map must have unique keys, whereas with a multimap

keys may be duplicated.

Example:

To see how maps work, let's look at a simple application that counts word frequency.

Words are input one per line and the total count of each is output.

#include <iostream>

#include <string>

#include <map>

#include conio.h>

using namespace std;

int main()

{

typedef map<string, long, less<string> > MAP;

MAP counter;

char buf[256];

while (cin >> buf)

counter[buf]++;

MAP::iterator it = counter.begin();

while (it != counter.end()) {

cout << (*it).first << " " << (*it).second << endl;

it++;

}

getch();

return 0;

}