DataStructures Complete Manual
DataStructures Complete Manual
Session: FA20
COMSATS UNIVERSITY ISLAMABAD, ATTOCK CAMPUS
Course Details
Credit Hours 01
Core BS CE
Course Prerequisite(s)/Co-Requisite(s)
Pre-requisites: Programming Fundamentals
Co-requisites: Operating Systems
CLO Attainment
CSC211 LAB Related Level of Teaching Methods
Mechanism
CLOs PLOs Learning
CLO 1 PLO1 C2 Tutorials, Instructions, Lab Manuals and In Lab, Post Lab and Lab
Demos Exams
CLO 2 PLO2 C3 Tutorials, Instructions, Lab Manuals and In Lab, Post Lab and Lab
Demos Exams
CLO 3 PLO 3 C5 Tutorials, Instructions, Lab Manuals and In Lab, Post Lab and Lab
Demos Exams
COMSATS UNIVERSITY ISLAMABAD, ATTOCK CAMPUS
CLO 4 PLO 5 C3 Tutorials, Instructions, Lab Manuals and In Lab, Post Lab and Lab
Demos Exams
CLO 5 PLO 10 A4 Tutorials, Instructions, Lab Manuals and In Lab, Post Lab and Lab
Demos Exams
Overview
Recommended
Week Topics
Readings (if any)
1. Operations on Array Data
2. Sequential Search and Binary Search
3. Selection Sort and Bubble Sort
4. Recurse Functions
5. Insertion Sort and Merge Sort
6. Sessional I
7. Quick Sort
8. Structures and Classes
9. Array implementation of Stack
10. Array implementation of Queue
11. Sessional II
12. Linked-list Implementation
13. Binary Search Tree Implementation
14. Graphs
15. Terminal Exam
Important Note: Students will be required to submit their Lab work and Lab handout.
Textbook(s)/Supplementary Readings
[1]. A lab manual will be provided to the students at the beginning of the each lab that carries the details of the experiments and related
instructions to perform those experiments.
.
R1: Lab Safety Rules: While working in the lab, the While working in the lab, the While working in the lab, the While working in the lab, the
Ability to observe safety, be student demonstrates student is attentive to safety, student is mostly attentive to student is unattentive to safety,
courteous to others, attentive exemplary behavior in respectful to instructors and safety, respectful to instructors disrespectful to others, and
to safety, and tidy in the lab. courtesy and safety, and leaves peers, and neat, cleaning the and peers, and neat, Might messy, leaving the area untidy
the area spotless. area before leaving. need reminders to leave the even after being reminded.
area clean.
R2: Use of Engineering
Knowledge and follow The procedure is efficiently The procedure is well The procedure could be better The procedure is inadequately
Engineering Experiment Procedures: followed and student skillfully followed and student followed, but student controls followed, and student does not
Knowledge Ability to follow experimental controls all chosen variables. demonstrates control of all all chosen variables. Most control chosen variables. Many
procedures, control variables, Know all procedural steps, and chosen variables. All procedural steps are recorded procedural steps are not entered
and record procedural steps are clearly and concisely procedural steps are on the lab report. on the lab report.
on lab report. recorded on lab report recorded on the lab report.
R3: Interpretation of Demonstrates a skillful ability Demonstrates an ability to Demonstrates some ability Demonstrates minimal or no
Subject Knowledge: to provide rational provide rational to provide explanations of ability to provide explanation of
Ability to interpret and explanations, and on the basis explanations of mathematical and/or visual mathematical
explain mathematical and/or of that information, can make mathematical and/or forms, and makes occasional and/or visual forms. Frequently
visual forms, including fitting inferences. visual forms. mistakes. misinterprets
equations,
diagrams, graphics, figures
and tables.
Rubrics for PLO#2 (Problem Analysis)
Exceeds expectations [9-10] Meets expectations[7-9) Average [5-7) Unsatisfactory [1-5)
.
R4: Limitations and Point out all significant Point out many significant Point out some limitations Minimal or no ability to identify
Implications: limitations and limitations and implications. and implications. limitations or implications. Has
Ability to point out implications. Demonstrates Demonstrates recognition Demonstrates some no knowledge of hardware or
limitations and implications skillful recognition and and consideration of recognition and software implementation
of Hardware and software consideration of important important assumptions, Consideration of important requirements for the problem
Components. assumptions, hardware or hardware or software requirements of hardware or solution. Didn’t mention about
software requirements requirements when solving software. .Has mentioned assumption and constraints.
Problem when solving a problem. a problem. some of the assumptions.
Analysis
R5: Data/Evidence Raw data/evidence, as well as Raw data/evidence, as well Raw data/evidence, as well as Raw data/evidence, as well as
Measurements: units, are skillfully recorded. as units, are appropriately units, are recorded although units, are not recorded suitably.
Ability to record raw data / The data table is clearly and and clearly recorded. The not as clearly or suitably as The data table is not labeled
evidence. concisely, and/or creatively data table is appropriately they might be. The data table and/or formatted.
labeled and formatted. labeled and formatted. may lack appropriate labels
and/or format.
R6: Experimental Data Accurately analyze the Accurately analyze the Analyze the collected data and Analysis and interpretation of the
Analysis: collected data and interpret the collected data and interpret interpret the findings with findings is illogical, and the
Ability to interpret findings, findings insightfully, and the findings. Correlates minor errors. Correlates findings. No attempt to correlate
compare them to values in the skillfully. Correlates experimental results to experimental results to known experimental results with known
literature, identify weaknesses experimental results to known known theoretical values; theoretical values; accounts for theoretical values; incapable of
and limitations. theoretical values; accounts for accounts for measurement measurement errors and explaining measurement errors or
measurement errors and errors and parameters that parameters that affect parameters that affect the
parameters that affect affect experimental results. experimental results. experimental results.
experimental results.
R7: Implementing .
Design Strategy: Ability Demonstrates a skillful Demonstrates an ability Demonstrates some ability Demonstrates minimal or no
to execute a solution (thorough/insightful/creative) to execute a solution to execute a solution that ability to execute a solution.
taking into consideration ability to execute a solution taking into consideration attends to the problem, but Solution does not directly
design requirements and taking into consideration all design requirements and omits some design attend to the problem.
pertinent contextual design requirements and some contextual requirements and/or
elements. pertinent contextual elements. elements. pertinent contextual
[Block Diagram/Flow elements.
Engineering chart/Circuit Diagram]
Design R8: Best Coding Standards: Coding standards, best Coding standards, best Coding standards, best Coding standards, best
Ability to follow the coding programming practices are programming practices are programming practices are programming practices are not or
standards and programming followed extensively. followed appropriately not appropriately followed. rarely followed.
practices.
Lab #:
Lab Title:
Submitted by:
Name Registration #
In-Lab Post-Lab
Modern
Tools R9: Understand Tools: Ability to describe and explain the principles behind
Usage and applicability of engineering tools.
Rubrics to follow
Rubrics # R2 R3 R5 R6 R8 R9 R12
In –Lab
Post- Lab
LAB#1
Operations on Array Data
Objectives:
At the end of the lab, students are expected to be able to do the following
Introduction:
In C++, an array is a variable that can store multiple values of the same type. For example,
Suppose a class has 27 students, and we need to store the grades of all of them. Instead of creating 27
separate variables, we can simply create an array:
int array[27];
Here, grade is an array that can hold a maximum of 27 elements of double type.
In C++, the size and type of arrays cannot be changed after its declaration.
Array Declaration
dataType arrayName[arraySize];
For example,
int x[6];
Here,
• The array indices start with 0. Meaning x[0] is the first element stored at index 0.
• If the size of an array is n, the last element is stored at index (n-1). In this example, x[5] is the last
element.
• Elements of an array have consecutive addresses. For example, suppose the starting address
of x[0] is 2120d. Then, the address of the next element x[1] will be 2124d, the address
of x[2] will be 2128d and so on.
Here, the size of each element is increased by 4. This is because the size of int is 4 bytes.
Array Initialization
In C++, it's possible to initialize an array during declaration. For example,
// declare and initialize and array
int x[6] = {19, 10, 8, 17, 9, 15};
int main() {
int numbers[5] = {7, 5, 6, 12, 35};
Output:
The numbers are: 7 5 6 12 35
Here, we have used a for loop to iterate from i = 0 to i = 4. In each iteration, we have printed numbers[i].
int main() {
int numbers[5];
Output:
Enter 5 numbers:
11
12
13
14
15
The numbers are: 11 12 13 14 15
Example 3: Display Sum and Average of Array Elements Using for Loop
Code:
#include <iostream>
using namespace std;
int main() {
for (i=0;i<=5;i++) {
cout<<numbers[i]<<" ";
// calculate the sum
sum = sum+numbers[i];
count=count+1;
}
return 0;
}
Output:
The numbers are: 7 5 6 3 1 2
Their Sum = 24
Their Average = 4
Post-Lab Tasks
Task#1 Take an element of an array from the user to delete it and then display the new array.
Objectives:
At the end of the lab, students are expected to be able to do the following:
• Understand the searching technique concept and the purpose of searching operation
• Understand the implementation of basic searching algorithm such as sequential search and binary
search
Introduction:
Clifford A. Shaffer [1997] define searching as a process to determine whether an element is a member of
a certain data set. Sorting is the process of finding the location of an element with a specific value (key)
within a collection of elements. This process can also be seen as an attempt to search for a certain record in
a file. Each record contains data field and key field. Key field is a group of characters or numbers used as
an identifier for each record. Searching can done based on the key field.
Sequential search:
Sequential search is a very basic and simple search algorithm. In sequential search, we search an
element or value in a given array by traversing the array from the starting, till the desired element
or value is found.
It compares the element to be searched with all the elements present in the array and when the
element is matched successfully, it returns the index of the element in the array, else it returns -1.
Sequential Search is applied on unsorted or unordered lists, when there are fewer elements in a
list.
2. It has a time complexity of O(n), which means the time is linearly dependent on the number
of elements, which is not bad, but not that good too.
Code:
#include<iostream.h>
#include<conio.h>
main()
{
int arr1[5];
int req;
int location=-5;
cout<<"Enter 5 numbers to store in array: "<<endl;
for(int i=0; i<5; i++)
{
cin>>arr1[i];
}
cout<<endl;
cout<<"Enter the number you want to find :";
cin>>req;
cout<<endl;
for(int w=0;w<5;w++)
{
if(arr1[w] == req)
location=w;
}
if(location !=-5)
{
cout<<"Required number is found out at the location:"<<location+1;
cout<<endl;
}
else
cout<<"Number is not found ";
Output:
Enter 5 numbers to store in array:
3
15
6
4
3
Binary Search is used with sorted array or list. In binary search, we follow the following steps:
1. We start by comparing the element to be searched with the element in the middle of the
list/array.
3. If we do not get a match, we check whether the element to be searched is less or greater
than in value than the middle element.
4. If the element/number to be searched is greater in value than the middle number, then we
pick the elements on the right side of the middle element (as the list/array is sorted, hence
on the right, we will have all the numbers greater than the middle number), and start again
from the step 1.
5. If the element/number to be searched is lesser in value than the middle number, then we
pick the elements on the left side of the middle element, and start again from the step 1.
Binary Search is useful when there are large number of elements in an array and they are sorted.
So, a necessary condition for Binary search to work is that the list/array should be sorted.
2. It has a time complexity of O(log n) which is a very good time complexity. We will discuss
this in details in the Binary Search tutorial.
Binary search
Code:
#include <iostream>
using namespace std;
int main()
{
int num[10] = {10, 22, 37, 55, 92, 118};
int search_num, loc=-1;
if(loc != -1)
{
cout<<search_num<<" found in the array at the location: "<<loc;
}
else
{
cout<<"Element not found";
}
return 0;
}
}
return -1;
}
Output:
Enter the number that you want to search: 37
Task# 2 Take a sorted array of size 9 from the user and a search-key to find from that array. Then
using binary search, find that key from the array.
POST-LAB TASKS
Task# 1 Take a sorted array of size 10 from the user. Dry run the code of binary search for search
key that is not present in the array. Implement the code in compiler and display the values of
variables that control the ‘while loop’ for each iteration until the loop stops.
Objectives:
At the end of the lab, students are expected to be able to do the following:
• Understand the sorting technique concept and the purpose of sorting operation
• Understand the implementation of basic sorting algorithm such as selection sort and
binary sort
Introduction:
A sorting algorithm is used to arrange elements of an array/list in a specific order. For example,
There are various sorting algorithms that can be used to complete this operation. And, we can use
any algorithm based on the requirement.
• Bubble Sort
• Selection Sort
• Insertion Sort
• Merge Sort
• Quick sort
In the selection sort technique, the list is divided into two parts. In one part all elements are sorted
and in another part the items are unsorted. At first, we take the maximum or minimum data from
the array. After getting the data (say minimum) we place it at the beginning of the list by replacing
the data of first place with the minimum data. After performing the array is getting smaller. Thus,
this sorting technique is done.
2. Compare minimum with the second element. If the second element is smaller
than minimum, assign the second element as minimum.
Compare minimum with the third element. Again, if the third element is smaller, then
assign minimum to the third element otherwise do nothing. The process goes on until the
last element.
3. After each iteration, minimum is placed in the front of the unsorted list.
Code:
#include<iostream>
int main()
{
int i,j,n,loc,temp,min,a[30];
cout<<"Enter the number of elements:";
cin>>n;
cout<<"\nEnter the elements\n";
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n-1;i++)
{
min=a[i];
loc=i;
for(j=i+1;j<n;j++)
{
if(min>a[j])
{
min=a[j];
loc=j;
}
}
temp=a[i];
a[i]=a[loc];
a[loc]=temp;
return 0;
}
Output:
Enter the number of elements:5
1
5
3
7
2
Bubble sort
Bubble sort is a sorting algorithm that compares two adjacent elements and swaps them if they
are not in the intended order.
1. Starting from the first index, compare the first and the second elements.
2. If the first element is greater than the second element, they are swapped.
3. Now, compare the second and the third elements. Swap them if they are not in order.
Remaining Iterations
After each iteration, the largest element among the unsorted elements is placed at the end.
The array is sorted when all the unsorted elements are placed at their correct positions.
Bubble sort
Code:
#include<iostream>
int main()
{
int a[50],n,i,j,temp;
cout<<"Enter the size of array: ";
cin>>n;
cout<<"Enter the array elements: ";
Task# 2 Take an unsorted array of size 9. Sort the array in ascending order using Bubble Sort
technique. Use a condition to stop your program if the array is already sorted or it’s get sorted in
fewer steps than expected.
POST-LAB TASKS
Task# 1 Take an unsorted array of size 5. Sort the array in descending order using Selection Sort
technique. Dry run your code for each iteration. Implement the code in compiler and display the
values of variables.
Recursive Functions
Objectives:
At the end of the lab, students are expected to be able to do the following:
Introduction:
Recursion is a widely used phenomenon in computer science used to solve complex problems by
breaking them down into simpler ones. Recursion is a process by which a function
calls itself directly or indirectly. The corresponding function is called as recursive function.
Using recursive algorithms, certain complex problems can be solved quite easily.
Recursion performs repetition on the function calls, and it stops the execution when the base case
becomes true. A base case condition should be defined in the recursive function to avoid stack
overflow error message. If no base case is defined it leads to infinite recursion. When a function
is called it pushes them into a stack each time for the reserving resources for each repetition calls.
It gives the best at tree traversal.
Code:
// Factorial of n = 1*2*3*...*n
#include <iostream>
using namespace std;
int factorial(int);
int main() {
int n, result;
result = factorial(n);
cout << "Factorial of " << n << " = " << result;
return 0;
}
int factorial(int n) {
if (n > 1) {
return n * factorial(n - 1);
} else {
return 1;
}
}
Output:
Enter a non-negative number: 4
Factorial of 4 = 24
As we can see, the factorial() function is calling itself. However, during each call, we have
decreased the value of n by 1. When n is less than 1, the factorial() function ultimately returns the
output.
Code:
#include <iostream>
using namespace std;
int main() {
int n = 5;
int factorial = 1;
Factorial of 5 = 120
Task# 2 Write an algorithm for calculating factorial and implement the code in compiler using
both recursive functions and loop. And compare the execution time for both.
POST-LAB TASKS:
Task# 1 Fibonacci series is the sequence in which each number is the sum of the two numbers that
precede it. Write the code to find the next number of the Fibonacci series and also draw the flow
diagram to find the 5th number of the sequence.
Objectives:
At the end of the lab, students are expected to be able to do the following:
Introduction:
A sorting algorithm is used to arrange elements of an array/list in a specific order. For example,
There are various sorting algorithms that can be used to complete this operation. And, we can use
any algorithm based on the requirement.
• Bubble Sort
• Selection Sort
• Insertion Sort
• Merge Sort
• Quick sort
Insertion sort is a simple sorting algorithm that works similar to the way you sort playing cards
in your hands. The array is virtually split into a sorted and an unsorted part. Values from the
unsorted part are picked and placed at the correct position in the sorted part.
1. The first element in the array is assumed to be sorted. Take the second element and store
it separately in key.
Compare key with the first element. If the first element is greater than key, then key is
placed in front of the first element.
Code:
#include<iostream>
using namespace std;
int main()
{
int data[5]={7,8,3,1,6};
int item, n=5;
int pass, insertIndex;
for(pass=1; pass<n;pass++)
{
item = data[pass];
insertIndex = pass;
while((insertIndex >0) &&
(data[insertIndex -1]>item))
{
//insert the right item
data[insertIndex]=
data[insertIndex -1];
insertIndex --;
}
data[insertIndex] = item;
//insert item at the right place
1 3 6 7 8
Merge sort
The merge sort technique is based on divide and conquer technique. We divide the while data
set into smaller parts and merge them into a larger piece in sorted order. It is also very effective
for worst cases because this algorithm has lower time complexity for worst case also.
Using the Divide and Conquer technique, we divide a problem into subproblems. When the
solution to each subproblem is ready, we 'combine' the results from the subproblems to solve the
main problem.
Suppose we had to sort an array A. A subproblem would be to sort a sub-section of this array
starting at index p and ending at index r, denoted as A[p..r].
Divide
If q is the half-way point between p and r, then we can split the subarray A[p..r] into two
arrays A[p..q] and A[q+1, r].
In the conquer step, we try to sort both the subarrays A[p..q] and A[q+1, r]. If we haven't yet
reached the base case, we again divide both these subarrays and try to sort them.
Combine
When the conquer step reaches the base step and we get two sorted subarrays A[p..q] and A[q+1,
r] for array A[p..r], we combine the results by creating a sorted array A[p..r] from two sorted
subarrays A[p..q] and A[q+1, r].
Code:
#include<iostream>
using namespace std;
int main()
{
int arr[9] = {5, 15, 7, 2, 4, 1, 8, 10,3};
int n = 9 ,first=0, last=8;
//const int MAX_SIZE = maxNmbrItemInArry;
mergesort(arr, 0, n - 1);
Output:
The sorted array is =
1 2 3 4 5 7 8 10 15
• External sorting
• E-commerce applications
Task# 2 Take an unsorted array of size 7. Sort the array in ascending order using Merge Sort
technique. Show how the array will be divided to sub-arrays until each array consists of only one
element.
POST-LAB TASKS
Task# 1 Take an unsorted array of size 7. Sort the array in descending order using Merge Sort
technique. Dry run your code to merge the last sub-arrays together to make the final sorted array.
Quick Sort
Objectives:
At the end of the lab, students are expected to be able to do the following:
Introduction:
A sorting algorithm is used to arrange elements of an array/list in a specific order. For example,
There are various sorting algorithms that can be used to complete this operation. And, we can use
any algorithm based on the requirement.
• Bubble Sort
• Selection Sort
• Insertion Sort
• Merge Sort
• Quick sort
Quick sort is a highly efficient sorting algorithm and is based on partitioning of array of data into
smaller arrays. A large array is partitioned into two arrays one of which holds values smaller than
the specified value, say pivot, based on which the partition is made and another array holds values
greater than the pivot value.
Quicksort partitions an array and then calls itself recursively twice to sort the two resulting
subarrays. This algorithm is quite efficient for large-sized data sets as its average and worst-case
complexity are O(n2), respectively.
Quicksort is a sorting algorithm based on the divide and conquer approach where
1. An array is divided into subarrays by selecting a pivot element (element selected from the
array).
While dividing the array, the pivot element should be positioned in such a way that
elements less than pivot are kept on the left side and elements greater than pivot are on the
right side of the pivot.
2. The left and right subarrays are also divided using the same approach. This process
continues until each subarray contains a single element.
3. At this point, elements are already sorted. Finally, elements are combined to form a sorted
array.
1. A pointer is fixed at the pivot element. The pivot element is compared with the elements
beginning from the first index.
2. If the element is greater than the pivot element, a second pointer is set for that element.
3. Now, pivot is compared with other elements. If an element smaller than the pivot element is
reached, the smaller element is swapped with the greater element found earlier.
4. Again, the process is repeated to set the next greater element as the second pointer. And,
swap it with another smaller element.
3. Divide Subarrays
Pivot elements are again chosen for the left and the right sub-parts separately. And, step 2 is
repeated.
The subarrays are divided until each subarray is formed of a single element. At this point, the
array is already sorted.
Quick sort
Code:
#include<iostream>
using namespace std;
if (bottom<top) {
// change pivot place
temp=T[bottom];
T[bottom]=T[top];
T[top]=temp;
}
else {
loop=0; //loop false
cutPoint = top;
}//end if
}// end while
return cutPoint;
}//end function
int main()
{
int arr[9] = {5, 15, 7, 2, 4, 1, 8, 10,3};
int n = 9 ,first=0, last=8;
quickSort(arr, 0, n - 1);
1 2 3 4 5 7 8 10 15
Quicksort Applications
POST-LAB TASKS
Task# 1 Take an unsorted array of size 7. Sort the array in descending order using Quick Sort
technique. Take the first element as pivot element and dry run your code to find the right position
of that pivot element.
Introduction:
Structures
Many time we have to store the elements of the different data types. Structure is composition of
the different variables of different data types, grouped under same name.
Example
struct {
char name[64];
char course[128];
int age;
int year;
} student;
Definitions of Structures
char course[128];
int age;
int year;
Structure Initialization
When we declare a structure then memory won’t be allocated for the structure. i.e only writing
below declaration statement will never allocate memory
int mark1;
int mark2;
int mark3;
};
struct student
char name[20];
int roll;
float marks;
}std1 = { "Pritesh",67,78.3 };
In the above code snippet, the structure is declared and as soon as after declaration we have
initialized the structure variable.
std1 = {"Pritesh",67,78.3};
struct student
char name[20];
float marks;
std1 = {"Pritesh",67,78.3};
std2 = {"Don",62,71.3};
In this example, we have declared two structure variables in above code. After declaration of
variable we have initialized two variables.
std1 = {"Pritesh",67,78.3};
std2 = {"Don",62,71.3};
struct student
int mark1;
int mark2;
int mark3;
} sub1={67};
Though there are three members of structure, only one is initialized, and then remaining two
members are initialized with Zero. If there are variables of other data type then their initial values
will be
Integer 0
Float 0.00
Char NULL
struct student
int mark1;
int mark2;
int mark3;
};
void main()
- - - - --
};
Code:
#include<iostream>
using namespace std;
struct student
{
int id;
char name[20];
float percentage;
};
void func(student);
int main()
{
student record;
record.id=1;
cout<<"Enter the name= ";
cin>>record.name;
record.percentage = 86.5;
func(record);
return 0;
}
Id is: 1
Code:
#include<iostream>
using namespace std;
struct Date
{
int day;
int month;
int year;
};
int main( )
{
Date birthDate;
cout<<"Enter day of birth"; //enter day
cin>>birthDate.day; //display day
cout<<"Enter month of birth"; //enter month
cin>>birthDate.month; //display month
cout<<"Enter year of birth"; //enter year
cin>>birthDate.year; //display year
cout<<"your date of birth is: "
<<birthDate.day<<"/"<<birthDate.month<<"/"<<birthDate.year<<”\n”;
}
Output:
Enter day of birth: 12
The fundamental idea behind object-oriented languages is to combine into a single unit both data
and the functions that operate on that data. Such a unit is called an object. A class serves as a plan,
or blueprint. It specifies what data and what functions will be included in objects of that class. An
object is often called an “instance” of a class Syntax:
Classes are generally declared using the keyword class, with the following format:
Code:
Data Abstraction
• A doctor sees the person as patient. Thus he is interested in name, height, weight, age,
blood group, previous or existing diseases etc of a person
Member variables represent the characteristics of the object and member functions represent the
behavior of the object. For example length & width are the member variables of class Rectangle
and set_values(int,int), area() are the member functions.
Code:
#include <iostream>
using namespace std;
class Rectangle
{
private:
int length, width;
public:
void set_values(int,int); //set the values of length and width
int area ()
{
return (length*width);
}
};
void Rectangle : : set_values (int l, int w)
{
length = l;
width = w;
}
int main ()
{
Rectangle rect;
rect.set_values (3,4); //pass values to set length and width
cout<< "area =" <<rect.area( );
return 0;
}
Output:
area= 12
Constructors
It is a special function that is automatically executed when an object of that class is created. It has
no return type and has the same name as that of the class. It is normally defined in classes to
initialize data members.
// Constructor body
Destructors
It is a special function that is automatically executed when an object of that class is destroyed. It
has no return type and has the same name as that of the class preceded by tild (~) character. Unlike
constructors, destructors cannot take arguments.
Syntax
~ class_name ()
// Destructor body
Code:
class counter
{
private:
int count;
public:
counter()
{
count=0;
cout<<"I am a constructor"<<endl;
}
~counter()
{
cout<<"I am a destructor"<<endl;
}
};
int main( )
{
counter c;
}
Task# 2 Create a class named Cylinder. Write the necessary variables and functions to calculate
area (curved surface area) and volume of a cylinder. Create functions outside of the class using
scope resolution operator.
POST-LAB TASKS
Task# 1 Create a class named Time, the data members are hours, minutes and seconds. Write a
function to read the data members supplied by the user, write a function to display the data
members in standard (24) hour and also in (12) hour format.
Introduction:
Stacks are the most important in data structures. The notation of a stack in computer science is the
same as the notion of the Stack to which you are accustomed in everyday life. For example, a
recursion program on which function call itself, but what happen when a function which is calling
itself call another function. Such as a function ‘A’ call function ‘B’ as a recursion. So the firstly
function ‘B’ is call in ‘A’ and then function ‘A’ is work. So this is a Stack. This is a Stack is First
In Last Out data structure.
In programming terms, putting an item on top of the stack is called push and removing an item is
called pop.
In Stacks, we know the array work, sometimes we need to modified it or add some element in it.
For that purpose we use insertion scheme. By the use of this scheme we insert any element in
Stacks using array. In Stack we maintain only one node which is called TOP. And Push
terminology is used as insertions.
Code:
void push(int val)
{
if(isFull())
{
cout<<"Stack overflow"<<endl;
}
else
{
top++;
arr[top]=val;
}
}
Display of Stack
In displaying section, the elements of Stacks are been display by using loops and variables as a
reverse order. Such that, last element is display at on first and first element enters display at on
last.
Code:
void display()
{
cout<<"All value in the Stack are "<<endl;
for(int i=5; i>=0; i--)
{
cout<<arr[i]<<endl;
}
}
In the deletion process, the element of the Stack is deleted on the same node which is called TOP.
In stacks, it’s just deleting the index of the TOP element which is added at last. In Stacks Pop
terminology is used as deletion.
Code:
int pop()
{
if(isEmpty())
{
cout<<"Stack underflow"<<endl;
return 0;
}
else
{
int popvalue=arr[top];
arr[top]=0;
top--;
return popvalue;
}
}
Code:
#include<iostream>
using namespace std;
class Stack
{
private:
int top;
int arr[6];
public:
Stack()
{
top=-1;
for(int i=0; i<6; i++)
{
arr[i]=0;
}
}
bool isEmpty()
{
if(top==-1)
bool isFull()
{
if(top==5)
return true;
else
return false;
}
int pop()
{
if(isEmpty())
{
cout<<"Stack underflow"<<endl;
return 0;
}
else
{
int popvalue=arr[top];
arr[top]=0;
top--;
return popvalue;
}
}
int count()
{
return(top+1);
}
void display()
{
cout<<"All value in the Stack are "<<endl;
for(int i=5; i>=0; i--)
{
cout<<arr[i]<<endl;
}
}
};
int main()
{
Stack s1;
int option,position,value;
do
{
cout<<"What operation do you want to perform? Select option
number accordingly. Enter 0 to exit. "<<endl;
cout<<"1. Push"<<endl;
cout<<"2. Pop"<<endl;
cout<<"3. isEmpty()"<<endl;
cout<<"4. isFull()"<<endl;
cout<<"5. peek()"<<endl;
cout<<"6. count()"<<endl;
cout<<"7. change()"<<endl;
cout<<"8. display()"<<endl;
//cout<<"9. Clear Screen"<<endl<<endl;
cin>>option;
switch(option)
{
case 1:
cout<<"Enter an item to push in the stack"<<endl;
cin>>value;
s1.push(value);
break;
case 2:
cout<<"Pop Function called - poped value:
"<<s1.pop()<<endl;
break;
case 3:
if(s1.isEmpty())
cout<<"Stack is Empty"<<endl;
case 4:
if(s1.isFull())
cout<<"Stack is Full"<<endl;
else
cout<<"Stack is not Full"<<endl;
break;
case 5:
cout<<"Enter position of item you want to peek:
"<<endl;
cin>>position;
cout<<"Peek function called - Value at position
"<<position<<"is "<<s1.peek(position)<<endl;
break;
case 6:
cout<<"Count Function called - Number of items in
the Stack are: "<<s1.count()<<endl;
break;
case 7:
cout<<"Change function called - "<<endl;
cout<<"Enter position of item you want to change :
";
cin>>position;
cout<<endl;
cout<<"Enter value of item you want to change : ";
cin>>value;
s1.change(position,value);
break;
case 8:
cout<<"Display Function Called - "<<endl;
s1.display();
break;
case 9:
system("cls");
break;
default:
cout<<"Enter proper option number "<<endl;
}while(option!=0);
1. Push
2. Pop
3. isEmpty()
4. isFull()
5. peek()
6. count()
7. change()
8. display()
Although stack is a simple data structure to implement, it is very powerful. The most common uses
of a stack are:
• To reverse a word - Put all the letters in a stack and pop them out. Because of the LIFO
order of stack, you will get the letters in reverse order.
• In compilers - Compilers use the stack to calculate the value of expressions like 2 + 4 / 5
* (7 - 9) by converting the expression to prefix or postfix form.
• In browsers - The back button in a browser saves all the URLs you have visited previously
in a stack. Each time you visit a new page, it is added on top of the stack. When you press
the back button, the current URL is removed from the stack, and the previous URL is
accessed.
POST-LAB TASKS
Task# 1 Implement all the functions related to stack (createStack(), push(), pull(), isEmpty(),
isFull(), stackTop()) in compiler. Make a menu to be displayed in console window so the user
can select the operations he wants to perform on stack.
Objectives:
At the end of the lab, students are expected to be able to do the following:
Introduction:
Queues using Arrays
This manual discusses an important data structure, called a queue. The notion of a queue in
computer science is the same as the notion of the queues to which you are accustomed in everyday
life. There are queues of customers in a bank or in a grocery store and queues of cars waiting to
pass through a tollbooth. Similarly, because a computer can send a print request faster than a printer
can print, a queue of documents is often waiting to be printed at a printer. The general rule to
process elements in a queue is that the customer at the front of the queue is served next and that
when a new customer arrives, he or she stands at the end of the queue. That is, a queue is a First
In First Out data structure.
A queue is a set of elements of the same type in which the elements are added at one end, called
the back or rear, and deleted from the other end, called the front. For example, consider a line of
customers in a bank, wherein the customers are waiting to withdraw/deposit money or to conduct
some other business. Each new customer gets in the line at the rear. Whenever a teller is ready for
a new customer, the customer at the front of the line is served.
The rear of the queue is accessed whenever a new element is added to the queue, and the front of
the queue is accessed whenever an element is deleted from the queue. As in a stack, the middle
elements of the queue are inaccessible, even if the queue elements are stored in an array.
Queue: A data structure in which the elements are added at one end, called the rear, and deleted
from the other end, called the front; a First In First Out (FIFO) data structure.
Queues may be represented in the computer in various ways, usually by means at one way list or
linear arrays. Unless otherwise stated or implied each of our queues will be maintained by a linear
array QUEUE and two pointer variable FRONT containing the location of the front element of the
queue and REAR containing the location of the rear element of the queue. The condition FRONT
= NULL will indicate that the queue is empty.
Queue follows the First In First Out (FIFO) rule - the item that goes in first is the item that
comes out first.
A queue is an object (an abstract data structure - ADT) that allows the following operations:
• Peek: Get the value of the front of the queue without removing it
Working of Queue
Enqueue Operation
Dequeue Operation
• for the last element, reset the values of FRONT and REAR to -1
Code:
int deQueue()
{
int x;
if(isEmpty())
{
cout<<"Queue is empty"<<endl;
return 0;
}
else if(front==rear)
{
x=array[front];
array[front]=0;
rear=front=-1;
return x;
}
else
{
x=array[front];
Working of Queue:
• When data is transferred asynchronously between two processes. The queue is used for
synchronization. For example: IO Buffers, pipes, file IO, etc.
• Call Center phone systems use Queues to hold people calling them in order.
Circular Queue
A circular queue is the extended version of a regular queue where the last element is connected
to the first element. Thus, forming a circle-like structure.
The circular queue solves the major limitation of the normal queue. In a normal queue, after a bit
of insertion and deletion, there will be non-usable empty space.
Here, indexes 0 and 1 can only be used after resetting the queue (deletion of all elements). This
reduces the actual size of the queue.
Circular Queue works by the process of circular increment i.e., when we try to increment the
pointer and we reach the end of the queue, we start from the beginning of the queue.
POST-LAB TASKS:
Task# 1 Write a function to create a circular Queue of size 5. Initialize it with zero values. Write
functions for entering and deleting a value from the Queue using enQueue() and deQueue()
functions. With the help of dry run, justify how circular Queue overcomes the issues related to
simple Queue.
Linked-list Implementation
Objectives:
At the end of the lab, students are expected to be able to do the following:
Introduction:
A linked list is a collection of components, called nodes. Every node (except the last node) contains
the address of the next node. Thus, every node in a linked list has two components: one to store
the relevant information (that is, data) and one to store the address, called the link, of the next node
in the list. The address of the first node in the list is stored in a separate location, called the head
or first. Figure 1 is a pictorial representation of a node.
1. One or more members that represent data (e.g. inventory records, customer names, addresses,
telephone numbers, etc).
A linked list is a linear data structure that includes a series of connected nodes. Here, each node
stores the data and the address of the next node. For example,
You have to start somewhere, so we give the address of the first node a special name called HEAD.
Also, the last node in the linked list can be identified because its next portion points to NULL.
Linked lists can be of multiple types: singly, doubly, and circular linked list. In this article, we
will focus on the singly linked list.
Let's see how each node of the linked list is represented. Each node consists:
• A data item
We wrap both the data item and the next node reference in a class as:
Linked-list class:
Code:
class Node
{
public:
double data; // data
Node* next; // pointer to next node
};
Understanding the class of a linked list node is the key to having a grasp on it.
Each class node has a data item and a pointer to another class node. The following code explains
it clearly.
Code:
class List
{
private:
Node* head;
int length;
public:
// constructor
List()
{
head = NULL;
length =0;
}
bool IsEmpty()
{
return head == NULL;
}
~List();
};
Displaying the contents of a linked list is very simple. We keep moving the currNode to the next
one and display its contents.
When currNode is NULL, we know that we have reached the end of the linked list so we get out
of the while loop.
Linked-list traversal:
Code:
void List::DisplayList()
{
int num = 0;
Node* currNode = head;
while (currNode != NULL)
{
cout << currNode->data << endl;
currNode = currNode->next;
num++;
}
cout<<"Number of nodes in the list: " << num << endl;
}
Insert a Node
• Store data
Code:
Node* List::InsertNode(double x)
{
Node* currNode = head;
Node* prevNode = NULL;
// while (currNode!=NULL && x > currNode->data)
// {
// prevNode = currNode;
// currNode = currNode->next;
// }
Node* newNode = new Node;
newNode->data = x;
if (prevNode == NULL)
{
newNode->next = head;
head = newNode;
}
else
{
newNode->next = prevNode->next;
prevNode->next = newNode;
}
length++;
return newNode;
}
Delete a Node:
Code:
void List::DeleteNode(double x)
{
Node* prevNode = NULL;
Node* currNode = head;
int currIndex = 1;
You can search an element on a linked list using a loop using the following steps. We are
finding item on a linked list.
• Run a loop until the current node is NULL because the last element points to NULL.
• In each iteration, check if the key of the node is equal to item. If it the key matches the
item, return true otherwise return false.
Code:
int List::FindNode(double x)
{
Node* currNode = head;
int currIndex = 1;
while (currNode!=NULL && currNode->data != x)
{
currNode = currNode->next;
currIndex++;
}
if (currNode!=NULL)
return currIndex;
else
return 0;
}
POST-LAB TASKS
Task# 1 Implement enQueue and deQueue functions of Queue data structure using linked-list.
• Understand the concept of tree, binary tree and binary search tree in C++
• Learn to apply different operations such as insertion, deletion of a Node etc., on Binary
Search Tree
Introduction:
A tree is a nonlinear hierarchical data structure that consists of nodes connected by edges.
Other data structures such as arrays, linked list, stack, and queue are linear data structures that
store data sequentially. In order to perform any operation in a linear data structure, the time
complexity increases with the increase in the data size. But, it is not acceptable in today's
computational world.
Different tree data structures allow quicker and easier access to the data as it is a non-linear data
structure.
Tree Terminologies
Node
A node is an entity that contains a key or value and pointers to its child nodes.
The last nodes of each path are called leaf nodes or external nodes that do not contain a
link/pointer to child nodes.
Edge
Root
Height of a Node
The height of a node is the number of edges from the node to the deepest leaf (ie. the longest
path from the node to a leaf node).
Depth of a Node
The depth of a node is the number of edges from the root to the node.
Height of a Tree
The height of a Tree is the height of the root node or the depth of the deepest node.
The depth of a node is the number of edges from the root to the node.
Height of a Tree
The height of a Tree is the height of the root node or the depth of the deepest node.
A binary tree is a tree data structure in which each parent node can have at most two children.
Each node of a binary tree consists of three items:
• data item
A node of a binary tree is represented by a structure containing a data part and two pointers to
other structures of the same type.
Binary search tree is a data structure that quickly allows us to maintain a sorted list of numbers.
• It is called a binary tree because each tree node has a maximum of two children.
• It is called a search tree because it can be used to search for the presence of a number
in O(log(n)) time.
The properties that separate a binary search tree from a regular binary tree is
1. All nodes of left subtree are less than the root node
3. Both subtrees of each node are also BSTs i.e., they have the above two properties
The binary tree on the right isn't a binary search tree because the right subtree of the node "3"
contains a value smaller than it.
TreeNode class
Code:
class TreeNode
{
public:
int value;
TreeNode *left;
TreeNode *right;
TreeNode()
{
value=0;
right=NULL;
left =NULL;
}
TreeNode(int v)
{
value=v;
right=NULL;
left =NULL;
}
};
Inserting a value in the correct position is similar to searching because we try to maintain the rule
that the left subtree is lesser than root and the right subtree is larger than root.
Node Insertion
Code:
void insertNode(TreeNode * new_node)
{
if (root == NULL)
{
root = new_node;
cout << "Value Inserted as root node!" << endl;
}
else
{
TreeNode * temp = root;
while (temp != NULL) {
if (new_node -> value == temp -> value)
{
cout << "Value Already exist," <<
"Insert another value!" << endl;
return;
}
else if ((new_node -> value < temp -> value) && (temp ->
left == NULL))
{
temp -> left = new_node;
cout << "Value Inserted to the left!" << endl;
break;
}
else if (new_node -> value < temp -> value)
{
temp = temp -> left;
}
else if ((new_node -> value > temp -> value) && (temp ->
right == NULL))
{
temp -> right = new_node;
cout << "Value Inserted to the right!" << endl;
break;
}
else
{
temp = temp -> right;
}
}
}
}
There are three cases for deleting a node from a binary search tree.
Case I
In the first case, the node to be deleted is the leaf node. In such a case, simply delete the node
from the tree.
Case II
In the second case, the node to be deleted lies has a single child node. In such a case follow the
steps below:
Case III
In the third case, the node to be deleted has two children. In such a case follow the steps below:
Node Deletion
Code:
void insertNode(TreeNode * new_node)
{
if (root == NULL)
{
root = new_node;
cout << "Value Inserted as root node!" << endl;
}
else
{
TreeNode * temp = root;
while (temp != NULL) {
if (new_node -> value == temp -> value)
{
cout << "Value Already exist," <<
"Insert another value!" << endl;
return;
}
else if ((new_node -> value < temp -> value) && (temp ->
left == NULL))
POST-LAB TASKS
Task# 1 Create a binary search tree by entering values in given order as [8, 9, 12, 6]. Your Binary
Search Tree should look like this.
Now dry run your code for inserting 8 first, then inserting 9 and after that inserting 12.
Graphs
Objectives:
At the end of the lab, students are expected to be able to do the following:
Introduction:
A graph data structure is a collection of nodes that have data and are connected to other nodes.
Graphs are used to solve many real-life problems. Graphs are used to represent networks. The
networks may include paths in a city or telephone network or circuit network. Graphs are also used
in social networks like linkedIn, Facebook. On facebook, everything is a node. That includes User,
Photo, Album, Event, Group, Page, Comment, Story, Video, Link, Note, anything that has data is
a node.
Every relationship is an edge from one node to another. Whether you post a photo, join a group,
like a page, etc., a new edge is created for that relationship.
All of facebook is then a collection of these nodes and edges. This is because facebook uses a
graph data structure to store its data.
• A collection of vertices V
In the above Graph, the set of vertices V = {0,1,2,3,4} and the set of edges E = {01, 12, 23, 34,
04, 14, 13}.
Graph Terminology
• Path: A sequence of edges that allows you to go from vertex A to vertex B is called a path.
0-1, 1-2 and 0-2 are paths from vertex 0 to vertex 2.
• Directed Graph: A graph in which an edge (u,v) doesn't necessarily mean that there is an
edge (v, u) as well. The edges in such a graph are represented by arrows to show the
direction of the edge.
Graph Representation
1. Adjacency Matrix
An adjacency matrix is a 2D array of V x V vertices. Each row and column represent a vertex.
If the value of any element a[i][j] is 1, it represents that there is an edge connecting vertex i and
vertex j.
Edge lookup (checking if an edge exists between vertex A and vertex B) is extremely fast in
adjacency matrix representation but we have to reserve space for every possible link between all
vertices (V x V), so it requires more space.
2. Adjacency List
The index of the array represents a vertex and each element in its linked list represents the other
vertices that form an edge with the vertex.
The adjacency list for the graph made in the first example is as follows:
An adjacency list is efficient in terms of storage because we only need to store the values for the
edges. For a graph with millions of vertices, this can mean a lot of saved space.
• Graph Traversal
Graph Implementation:
Code:
#include <iostream>
using namespace std;
// stores adjacency list items
struct adjNode {
int val, cost;
adjNode* next;
};
// structure to store edges
struct graphEdge {
int start_ver, end_ver, weight;
};
class DiaGraph{
// insert new nodes into adjacency list from given graph
adjNode* getAdjListNode(int value, int weight, adjNode* head) {
adjNode* newNode = new adjNode;
newNode->val = value;
newNode->cost = weight;
• Graphs are used extensively in computer science to depict network graphs, or semantic
graphs or even to depict the flow of computation.
• Graphs are also used for query optimization in database languages in some specialized
compilers.
• In social networking sites, graphs are main the structures to depict the network of people.
• Graphs are extensively used to build the transportation system especially the road network.
A popular example is Google maps that extensively uses graphs to indicate directions all
over the world.
POST-LAB TASKS
Task# 1 Write a program for the following graph and write a function to find its adjacency matrix.