This document provides an overview of the C++ Data Structures lab manual. It covers topics like C++ review, implementation of various data structures like stack, queue, linked list, binary tree, graph. It also discusses sorting and searching techniques, file input/output, functions, classes, templates and exercises for students to practice implementing different data structures and algorithms. The instructor's contact details are provided at the beginning.
1. Data Structures
CSC-206
Lab Manual
Instructor
Mr. Adeel M. Syed
adeelmuzaffar@gmail.com
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
Data Structures Lab Handouts 2
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;
Data Structures Lab Handouts 3
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;
Data Structures Lab Handouts 4
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
Data Structures Lab Handouts 5
6. C++ Classes
The class is the capsule that is used to encapsulate an abstract data type.
x A class defines a new data type. You can create many objects of this type.
x A class is composed of one or more members.
x Members are:
o data items (members)
o functions (member functions)
x 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;}
};
Data Structures Lab Handouts 6
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.
Data Structures Lab Handouts 7
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 = (ab)? a : b;
return (result);
}
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMaxint(i, j);
n=GetMaxlong(l, m);
cout k endl;
cout n endl;
return 0;
}
Data Structures Lab Handouts 8
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:
mypairint myobject (115, 36);
this same class would also be used to create an object to store any other type:
mypairdouble myfloats (3.0, 2.18);
Data Structures Lab Handouts 9
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 mypairT::getmax ()
{
T retval;
retval = ab? 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.
Data Structures Lab Handouts 10
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 mysequenceT,N::setmember (int x, T value)
{
memblock[x]=value;
}
template class T, int N
T mysequenceT, 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;
}
Data Structures Lab Handouts 11
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
Data Structures Lab Handouts 12
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
Data Structures Lab Handouts 13
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 nn Character count = count endl;
inFile.close();
outFile.close();
return 0;
}
Data Structures Lab Handouts 14
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
Data Structures Lab Handouts 15
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:
x The price is not more than a specified amount
x The size is not less than a specified number of bedrooms
x The house with lowest price
x The largest house (with maximum number of bedrooms)
x In a given city
x With best ratio price/size
x The user may enter a ? to indicate no preference.
- Print all the entries that meet the buyer’s need.
Data Structures Lab Handouts 16
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:
0.25 MT 1 0.25 MT 2 0.5 FIN
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
}
Data Structures Lab Handouts 17
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:
.
.
.
};
Data Structures Lab Handouts 18
19. Your program should work as follows:
x Ask the user for the filename and open the file.
x Read in the input from the file and store it in the student array.
x Compute and store an average for every student.
x 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.
x For option 1 the user doesn't have to give you any extra information.
x 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.
Data Structures Lab Handouts 19
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
};
Data Structures Lab Handouts 20
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;
}
Data Structures Lab Handouts 21
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;
}
Data Structures Lab Handouts 22
23. Dynamic Implementation of Stack
Stack Using Class Template and Dynamic Array
x The construct that allows us to create a class of undetermined type is called a template.
x A class template allows the compiler to generate multiple versions of a class type by
using type parameters.
x The formal parameter appears in the class template definition, and the actual parameter
appears in the client code. Both are enclosed in pointed brackets, .
templateclass 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
};
Data Structures Lab Handouts 23
24. //-----------------------------------------------------------------------------
// CLASS TEMPLATE IMPLEMENTATION FILE (stack.cpp)
//-------------------------------------------------------------------------------
#include “stack.h”
templateclass ItemType
StackItemType::Stack( ) //DEFAULT CONSTRUCTOR
{
maxStack = 500;
top = -1;
items = new ItemType[500]; // dynamically allocates array
}
templateclass ItemType
StackItemType::Stack( int max ) // PARAMETERIZED
{
maxStack = max;
top = -1;
items = new ItemType[max]; // dynamically allocates array
}
templateclass ItemType
StackItemType::~Stack( )
{
delete [ ] items; // deallocates array
}
templateclass ItemType
int StackItemType::IsEmpty( )
{
return (top == - 1);
}
templateclass ItemType
int StackItemType::IsFull( )
{
return (top == maxStack - 1);
}
Data Structures Lab Handouts 24
25. template class ItemType
void StackItemType::Push (ItemType newItem )
{
if (IsFull())
{ cout “Stack Overflow” endl;
exit(1);
}
top++;
items[top] = newItem;
}
templateclass ItemType
void StackItemType::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 ()
{
Stackint IntStack;
Stackfloat 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; }
Data Structures Lab Handouts 25
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.
Data Structures Lab Handouts 26
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:
x if n = 0, n! is equal to 1.
x 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;
}
Data Structures Lab Handouts 27
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;
}
Data Structures Lab Handouts 28
29. Example 4: Computing the Ackermann Function
int Ackermann(int m, int n)
{
if(m==0)
return n+1;
else if (m0 n==0)
return Ackermann(m-1,1);
else if (m0 n0)
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 (0kn) and n1
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)
Data Structures Lab Handouts 29
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
x an array Items[0:N-1] consisting of N items
x 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);
};
Data Structures Lab Handouts 30
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.
Data Structures Lab Handouts 31
32. Dynamic Implementation of Queue
Queue Using Template and Dynamic Array
//-----------------------------------------------------------------------
// CLASS TEMPLATE DEFINITION FOR QUEUE
//-----------------------------------------------------------------------
templateclass 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
//-----------------------------------------------------------------------
templateclass ItemType
QueItemType::Que() // Default Constructor
{
maxQue = 501;
front = 0;
rear = 0;
count = 0;
items = new ItemType[maxQue]; // dynamically allocates
}
Data Structures Lab Handouts 32
34. templateclass ItemType
void QueItemType::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.
Data Structures Lab Handouts 34
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.
Data Structures Lab Handouts 35
36. Lab 6
Implementation of Linked List
//-----------------------------------------------------------------------
// CLASS TEMPLATE DEFINITION FOR LINKED LIST
//---------------------------------------------------------------------
#include iostream
#includeconio.h
using namespace std;
templateclass 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();
};
Data Structures Lab Handouts 36
37. //--------------------------------------------------------
// CLASS TEMPLATE IMPLEMENTATION
//--------------------------------------------------------
// Default Constructor that initializes a newly created list to empty list.
templateclass ItemType
ListItemType::List()
{
listptr = 0;
}
// Destructor traverses the nodes of a list, freeing them one by one.
templateclass ItemType
ListItemType::~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.
templateclass ItemType
void ListItemType::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;
}
Data Structures Lab Handouts 37
38. // Determines if the list is empty.
templateclass ItemType
ItemType ListItemType::emptyList()
{
return (listptr == 0);
}
// push(newvalue) adds a new node with a given value to the front of the list.//
templateclass ItemType
void ListItemType::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.
templateclass ItemType
void ListItemType::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;
}
Data Structures Lab Handouts 38
39. // pop deletes the first node of the list and returns its contents. //
templateclass ItemType
ItemType ListItemType::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()
{
Listint 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.
Data Structures Lab Handouts 39
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.
Data Structures Lab Handouts 40
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:
x Read the polynomials from a file.
x Addition of two polynomials.
x Multiplication of two polynomials.
x 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
Data Structures Lab Handouts 41
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
};
Data Structures Lab Handouts 42
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];
Data Structures Lab Handouts 43
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 o info = x;
p o left = NULL;
p o 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 o left != NULL)
cout “Invalid Insertion”;
else
p o left = maketree (x);
}
Data Structures Lab Handouts 44
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 o info; /* visit the root */
pretrav (tree o left);
pretrav (tree o right);
}
}
void intrav (NODEPTR tree)
{
if (tree != NULL)
{
intrav (tree o left);
cout tree o info;
intrav (tree o right);
}
}
void posttrav (NODEPTR tree)
{
if (tree != NULL)
{
posttrav (tree o left);
posttrav (tree o right);
cout tree o info;
}
}
Data Structures Lab Handouts 45
46. Lab 9
Implementation of Binary Search Trees
#include fstream
using namespace std;
template class ItemType
struct TreeNode {
ItemType info; // Data member
TreeNodeItemType* left; // Pointer to left child
TreeNodeItemType* 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 ( TreeNodeItemType* ptr, ofstream outFile ) ;
void InsertHelper ( TreeNodeItemType* ptr, ItemType item ) ;
void RetrieveHelper ( TreeNodeItemType* ptr, ItemType item, bool found ) ;
void DestroyHelper ( TreeNodeItemType* ptr ) ;
private:
TreeNodeItemType* root;
};
Data Structures Lab Handouts 46
47. // BINARY SEARCH TREE IMPLEMENTATION
// OF MEMBER FUNCTIONS AND THEIR HELPER FUNCTIONS
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
template class ItemType
TreeTypeItemType :: TreeType ( ) // constructor
{
root = NULL ;
}
template class ItemType
bool TreeTypeItemType :: IsEmpty( ) const
{
return ( root == NULL ) ;
}
template class ItemType
void TreeTypeItemType :: RetrieveItem ( ItemType item, bool found )
{
RetrieveHelper ( root, item, found ) ;
}
template class ItemType
void TreeTypeItemType :: RetrieveHelper ( TreeNodeItemType* 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 TreeTypeItemType :: InsertItem ( ItemType item )
{
InsertHelper ( root, item ) ;
}
Data Structures Lab Handouts 47
48. template class ItemType
void TreeTypeItemType :: InsertHelper ( TreeNodeItemType* ptr, ItemType
item )
{ if ( ptr == NULL )
{ // INSERT item HERE AS LEAF
ptr = new TreeNodeItemType ;
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 TreeTypeItemType :: PrintTree ( ofstream outFile )
{
PrintHelper ( root, outFile ) ;
}
template class ItemType
void TreeTypeItemType :: PrintHelper ( TreeNodeItemType* 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
TreeTypeItemType :: ~TreeType ( ) // DESTRUCTOR
{
DestroyHelper ( root ) ;
}
Data Structures Lab Handouts 48
49. template class ItemType
void TreeTypeItemType :: DestroyHelper ( TreeNodeItemType* 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;
}
Data Structures Lab Handouts 49
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.
x 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;
Data Structures Lab Handouts 50
51. x 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.
x The array field edges is a two-dimensional array representing every possible ordered
pair of vertices.
x 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.
x 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.
x 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];
x 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);
}
Data Structures Lab Handouts 51
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];
x 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.
Data Structures Lab Handouts 52
53. Lab 11
Application of Graphs
Exercise 11: Implement Breadth-First and Depth-First search algorithms for a graph.
Depth-First Search
x 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.
x 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);
}
Data Structures Lab Handouts 53
54. Breadth-First Search
x In a breadth-first search, we begin by visiting the start vertex v. Next all unvisited
vertices adjacent to v are visited.
x 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.
Data Structures Lab Handouts 54
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.
Data Structures Lab Handouts 55
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()
{
vectorint 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
Data Structures Lab Handouts 56
57. 2 - VECTORS, LISTS, DEQUES, STACK
STL has different types of containers that are available for holding data, namely vectors,
lists, and deques.
x 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.
x 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.
x 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()
{
listint 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;
}
Data Structures Lab Handouts 57
58. Example 2.2:
#include algorithm
#include iostream
#include deque
#include conio.h
using namespace std;
int main()
{
dequeint 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;
}
Data Structures Lab Handouts 58
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()
{
stackint, listint 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 (listint).
Data Structures Lab Handouts 59
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()
{
bitset16 b1(1011011110001011);
bitset16 b2;
b2 = ~b1;
for (int i = b2.size() - 1; i = 0; i--)
cout b2[i];
cout endl;
getch();
return 0;
}
Data Structures Lab Handouts 60
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()
{
vectorint iv(N);
iv[50] = 37;
vectorint::iterator iter = find(iv.begin(), iv.end(), 37);
if (iter == iv.end())
cout not foundn;
else
cout found at iter - iv.begin() n;
getch();
return 0;
}
Data Structures Lab Handouts 61
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};
vectorint set3(10);
int main()
{
vectorint::iterator first = set3.begin();
vectorint::iterator last =
set_union(set1, set1 + 3, set2, set2 + 3, first);
while (first != last) {
cout *first ;
first++;
}
cout endl;
getch();
return 0;
}
Data Structures Lab Handouts 62
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
Data Structures Lab Handouts 63
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, timesint());
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.
Data Structures Lab Handouts 64
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
x 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
x Present your results in tabular and graphical (line graph) form. The tabulated output
should have the following form:
N Bubble Sort Selection Sort Insertion Sort Heap Sort
Comp. Exch. Comp. Comp Exch. Exch. Comp. Exch.
.
10
100
1000
5000
10000
20000
50000
Extra Credit Task:
Compute the actual execution time by reading the system clock.
Data Structures Lab Handouts 65
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
Data Structures Lab Handouts 66
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; kn; k++)
{
/* insert x[k] into sorted file */
y = x[k];
/* move down all elements greater than y */
for (j=k-1; j=0 yx[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.
Data Structures Lab Handouts 67
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;
}
};
Data Structures Lab Handouts 68
69. char* list[] = {epsilon, omega, theta, rho,
alpha, beta, phi, gamma, delta};
const int N = sizeof(list) / sizeof(char*);
int main()
{
int i, j;
vectorString 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
Data Structures Lab Handouts 69
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;
}
Data Structures Lab Handouts 70
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
N Sequential Search Binary Search
Successful Unsuccessful Successful Unsuccessful
10
100
1000
5000
10000
20000
50000
Sequential Search
int Sequential( int x[], n, key)
{
for (int i = 0; i n; i++)
if (key == x[i]) return (i);
return (-1);
}
Data Structures Lab Handouts 71
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;
}
Data Structures Lab Handouts 72
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 mapstring, long, lessstring 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;
}
Data Structures Lab Handouts 73