DataStructureAlgorithm Manual
DataStructureAlgorithm Manual
Lab Manual
Data Structures and Algorithms (CS-212L)
Sir Syed University of University of Engineering and Technology Page 1│ Page (Department of
Computer Science and Information Technology)
Sir Syed University of Engineering & Technology
Department of Computer Science and Information Technology
Lab Manual
Data Structures and Algorithms (CS-212)
Fall Semester 2021
I. Lab Objectives
In the laboratory, Visual Studio 2017 will be used to implement the concepts of Data Structures
(including arrays, stacks, queues and linked lists), advanced data structures (including trees and
graphs). Simple searching and sorting algorithms (linear and binary search, selection and
insertion sort).
II.Lab Outcomes
Upon the completion of Data Structures practical, Student will be able to describe the usage of
various data structures and operations for maintaining data structures. Design and implement
various data structures and algorithms.
III.TEXT BOOK:
• Drozdek, Adam. Data Structures and Algorithms in C++, 4th edition, USA,
Published by Cengage Learning 2013.
IV.REFERENCE BOOKS:
• Weiss, Mark. Data Structures and Algorithm Analysis in C++, 4th edition, USA,
Published by Pearson 2014.
Table of Contents
Lab No. Topic
1 An overview of Data Structures and their Operations: Brief Revision of Array
Implementation of Array operations One Dimensional Array Multidimensional
Array Abstract data types.
2 Algorithm Analysis: Implementation of Pseudo coding, Control Structures
Programming examples for Analysis of Algorithms, Efficiency of Algorithms,
Complexity of Algorithms
3 Pointers: Implementation of Null pointer, Void Pointer, Invalid Pointer, Dangling
Pointer Reference Variable
7 Linked Lists: Implementation of linked list with the help of algorithms for Insertion,
Deletion and Search an element Implementation of Doubly Link List Implementation
of Circular Link List.
8 Stacks: An array and link list based implementation of Stack
9 Queues: An array and link list based implementation of Queue
Lab # 1
Getting Started (Revision of C++)
I. Introduction
to:
1. Recall all programming techniques
2. Use of Array, Structures, Functions & Pointers
• If else statements
• Switch statements
• Goto statements
if ( <condition> ) {
// Execute these statements if <condition> is TRUE
}
else if ( <another condition> ) {
// Execute these statements if <another condition> is TRUE and
// <condition> is FALSE
}
Example:
include<iostream>
using namespace std;
int main ()
{
Int firstarray[] = {5, 10, 15};
Int secondarray[] = {2, 4, 6, 8, 10};
printarray (firstarray,3);
printarray(secondarray,5);
}
III. Structures
A data structure is a group of data elements grouped together under one name. These data
elements, known as members, can have different types and different lengths
Definition Of Structure
struct<struct-type>{
<type><identifier_list>;
<type><identifier_list>;
...
};
Example
#include <iostream>
using namespace std;
struct person {
char name[50];
int age; float
salary;
};
int main() {
person p1;
cout<< "Enter Full name: ";
cin.get(p1.name, 50);
cout<< "Enter age: ";
cin>>p1.age;
cout<<"Enter salary: ";
cin>> p1.salary;
cout<< "\nDisplaying Information:" <<endl;
cout<< "Name: " << p1.name <<endl;
cout<<"Age: " << p1.age <<endl;
cout<< "Salary: "<< p1.salary;
return 0;
}
OUT PUT
Displaying Information:
Name: Ali Khan
Age: 27
Salary: 10000
struct Distance
{ int feet;
float inch;
};
int main() {
Distance *ptr, d;
ptr = &d;
cout<< "Enter feet: ";
cin>>(*ptr).feet;
cout<< "Enter inch:";
cin>> (*ptr).inch;
cout<< "Displaying information." <<endl;
cout<< "Distance = " << (*ptr).feet << " feet " << (*ptr).inch << " inches";
return 0;
}
OUTPUT
Enter feet: 4
Enter inch: 3.5
Displaying information.
Distance = 4 feet 3.5 inches
In this program, a pointer variable ptr and normal variable d of type structure Distance is defined.
The address of variable d is stored to pointer variable, that is, ptr is pointing to variable d. Then
the member function of variable d is accessed using pointer.
Note: Since pointer ptr is pointing to variable d in this program, (*ptr).inch and d.inch is exact
same cell. Similarly, (*ptr).feet and d.feet is exact same cell.
The syntax to access member function using pointer is ugly and there is alternative notation ->
which is more common.
V. Lab Tasks
Algorithm Tasks:
1. You are given an array of integers A; you need to calculate the maximum sum that can be
obtained using array elements. Write a step by step algorithm to achieve maximum sum.
2. Write an algorithm for finding any user defined value from an array of elements.
Coding Tasks:
3. Refer to the algorithms you have written for task 1 and task 2, Write C++ programs to
implement the above scenarios.
4. Write a Program to enter three integers and output the smallest integer using if-else
statements.
5. Write a program that asks the user for a number n and gives them the possibility to
choose between computing the sum and computing the product of numbers from 1,…, n.
6. Write a Program to enter 10 integers in a single-dimensional array and then print out the
highest value of the array.
7. Write a program to create structure named student. Take information of student from user
as input (StdID, StdName, StdAge etc.) Display the output.
Lab # 2
Measurement of Time Complexity of an algorithm
Sometimes, there are more than one ways to solve a problem. We need to learn how to compare
the performance of different algorithms and choose the best one to solve a particular problem.
While analyzing an algorithm, we mostly consider time complexity and space complexity. Time
complexity of an algorithm quantifies the amount of time taken by an algorithm to run as a
function of the length of the input. Similarly, Space complexity of an algorithm quantifies the
amount of space or memory taken by an algorithm to run as a function of the length of the input.
Time and space complexity depends on lots of things like hardware, operating system, processors,
etc. However, we don't consider any of these factors while analyzing the algorithm. We will only
consider the execution time of an algorithm.
Let’s start with a simple example. Suppose you are given an array A and an integer x and you
have to find if x exists in array A.
Simple solution to this problem is traverse the whole array A and check if the any element is equal
to x.
for i : 1 to length of A
if A[i] is equal to x
return TRUE
return FALSE
Each of the operation in computer takes approximately constant time. Let each operation takes c
time. The number of lines of code executed is actually depends on the value of x. During
analyses of algorithm, mostly we will consider worst case scenario, i.e., when x is not present in
the array A. In the worst case, the if condition will run N times where N is the length of the array
A. So in the worst case, total execution time will be (N*c+c). N*c for the if condition and c for
the return statement (ignoring some operations like assignment of i ).
As we can see that the total time depends on the length of the array A. If the length of the array
increases, the time of execution will also increase.
I. Order of growth is how the time of execution depends on the length of the input. In the
above example, we can clearly see that the time of execution is linearly depends on the length of
the array. Order of growth will help us to compute the running time with ease. We will ignore the
lower order terms, since the lower order terms are relatively insignificant for large input. We use
different notation to describe limiting behavior of a function.
a) O-notation:
Sir Syed University of University of Engineering and Technology Page 9│ Page (Department of
Computer Science and Information Technology)
To denote asymptotic upper bound, we use O-notation. For a given function g(n), we denote by
O(g(n)) (pronounced “big-oh of g of n”) the set of functions:
O(g(n))= { f(n) : there exist positive constants c and n0 such that 0≤f(n)≤c g(n) for all n≥n0 }
b) Ω-notation:
To denote asymptotic lower bound, we use Ω-notation. For a given function g(n), we denote
by Ω(g(n)) (pronounced “big-omega of g of n”) the set of functions:
Ω(g(n))= { f(n) : there exist positive constants c and n0 such that 0≤c g(n)≤f(n) for all n≥n0 }
c) Θ-notation:
To denote asymptotic tight bound, we use Θ-notation. For a given function g(n), we denote by
Θ(g(n)) (pronounced “big-theta of g of n”) the set of functions:
Θ(g(n))= { f(n) : there exist positive constants c1,c2 and n0 such that 0≤c1 g(n)≤f(n)≤c2 g(n) for
all n>n0 }
To compute O-notation we will ignore the lower order terms, since the lower order terms are
relatively insignificant for large input.
Let f(N) = 2*N2 + 3*N + 5
O(f(N)) = O(2*N2 + 3*N + 5) = O(N2)
1.
int count = 0;
for (int i= 0; i < N; i++)
for (int j = 0; j < i; j++)
count++;
Total number of times count++ will run is 0+1+2+...+(N−1)=N (N−1)2. So the time complexity
will be O(N2).
2.
int count = 0;
for (int i = N; i > 0; i /= 2)
for (int j =
0; j < i; j++)
count++;
case. In the first look, it seems like O(N∗ for j′s loop
loop. But its wrong. Lets see why. logN). N the
and logN for i′s
Think about how many times count++ will run.
Total number of times count++ will run is N+N/2+N/4+...+1=2 N. So the time complexity will be
O(N).
Lab Tasks
1. Searching an element in array has constant time O(1) keeping that in mind insert an
element in an array and also delete the last element now calculate big O for both case.
Data Structures and Algorithms (CS-212) Lab # 5
Lab # 3
Implementation for Elementary Sorting Algorithms
I. Objectives
a) Algorithm
1. Compare each pair of adjacent elements from the beginning of an array and, if they are in
reversed order, swap them.
You can imagine that on every step big bubbles float to the surface and stay there. At the step,
when no bubble moves, sorting stops. Let us see an example of sorting an array to make the idea
of bubble sort clearer.
Example: Sort the data {5, 1, 12, -5, 16} using bubble sort.
b) Complexity analysis
Average and worst case complexity of bubble sort is O(n2). Also, it makes O(n2) swaps in the
worst case. Bubble sort is adaptive. It means that for almost sorted array it gives O(n) estimation.
Avoid implementations, which don't check if the array is already sorted on every step (any swaps
made). This check is necessary, in order to preserve adaptive property.
Sir Syed University of University of Engineering and Technology Page 17│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
a) Algorithm
The idea of algorithm is quite simple. Array is imaginary divided into two parts - sorted one and
unsorted one. At the beginning, sorted part is empty, while unsorted one contains whole array. At
every step, algorithm finds minimal element in the unsorted part and adds it to the end of the
sorted one. When unsorted part becomes empty, algorithm stops.
When algorithm sorts an array, it swaps first element of unsorted part with minimal element and
then it is included to the sorted part. This implementation of selection sort in not stable. In case of
linked list is sorted, and, instead of swaps, minimal element is linked to the unsorted part,
selection sort is stable.
Let us see an example of sorting an array to make the idea of selection sort
clearer. Example: Sort the data{5, 1, 12, -5, 16, 2, 12, 14} using selection sort
technique.
b) Complexity analysis
Selection sort stops, when unsorted part becomes empty. As we know, on every step number of
unsorted elements decreased by one. Therefore, selection sort makes n steps (n is number of
elements in array) of outer loop, before stop. Every step of outer loop requires finding minimum
in unsorted part. Summing up, n + (n - 1) + (n - 2) + ... + 1, results in O(n2) number of
comparisons. Number of swaps may vary from zero (in case of sorted array) to n - 1 (in case
array was sorted in reversed order), which results in O(n) number of swaps. Overall algorithm
complexity is O(n2).
Fact, that selection sort requires n - 1 number of swaps at most, makes it very efficient in
situations, when write operation is significantly more expensive, than read operation.
a) Algorithm
Insertion sort algorithm somewhat resembles selection sort. Array is imaginary divided into two
parts - sorted one and unsorted one. At the beginning, sorted part contains first element of the
array and unsorted one contains the rest. At every step, algorithm takes first element in the
unsorted part and inserts it to the right place of the sorted one. When unsorted part becomes
empty, algorithm stops. Sketchy, insertion sort algorithm step looks like this:
Becomes
Let’s see an example of insertion sort routine to make the idea of algorithm clearer. Example.
Sort the data {7, -5, 2, 16, 4} using insertion sort technique.
The main operation of the algorithm is insertion. The task is to insert a value into the sorted part
of the array. Let us see the variants of how we can do it.
V. Lab Tasks
Create a program that take an array of 10 inputs from the user and generate the sorted out put
using the following Algorithms;
• Bubble Sort
• Insertion Sort
• Selection Sort
Sir Syed University of University of Engineering and Technology Page 18│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
Lab # 4
Contd. Implementation for Elementary Sorting Algorithms
I. Introduction:
V. Merge Sort:
Merge sort is one of the most efficient sorting algorithms. It works on the principle of Divide and
Conquer. Merge sort repeatedly breaks down a list into several sub lists until each sub list consists
of a single element and merging those sub lists in a manner that results into a sorted list.
Top-down Merge Sort Implementation:
The top-down merge sort approach is the methodology which uses recursion mechanism. It starts
at the Top and proceeds downwards, with each recursive turn asking the same question such as
“What is required to be done to sort the array?” and having the answer as, “split the array into
two, make a recursive call, and merge the results.”, until one gets to the bottom of the array-tree.
Sir Syed University of University of Engineering and Technology Page 19│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
2. Repeatedly merge sub lists to produce newly sorted sub lists until there is only 1 sub list
remaining. This will be the sorted list.
a. Algorithm :
Merge sort keeps on dividing the list into equal halves until it can no more be divided. By
definition, if it is only one element in the list, it is sorted. Then, merge sort combines the
smaller sorted lists keeping the new list sorted too.
Step 1 − if it is only one element in the list it is already sorted, return.
Step 2 − divide the list recursively into two halves until it can no more be divided.
Step 3 − merge the smaller lists into new list in sorted order.
b. Complexity :
The list of size N is divided into a max of logN parts, and the merging of all sublists into a
single list takes O(N) time, the worst case run time of this algorithm is O(NLogN)
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.
Based on our understanding of partitioning in quick sort, we will now try to write an algorithm
for it, which is as follows.
Step 1 − Choose the highest index value has pivot
Step 2 − Take two variables to point left and right of the list excluding pivot
Step 3 − left points to the low index
Step 4 − right points to the high
Step 5 − while value at left is less than pivot move right
Step 6 − while value at right is greater than pivot move left
Step 7 − if both step 5 and step 6 does not match swap left and right
Step 8 − if left ≥ right, the point where they met is new pivot.
Using pivot algorithm recursively, we end up with smaller possible partitions. Each partition is
then processed for quick sort. We define recursive algorithm for quicksort as follows −
Step 1 − Make the right-most index value pivot
Step 2 − partition the array using pivot value
Step 3 − quicksort left partition recursively
Step 4 − quicksort right partition recursively.
Sir Syed University of University of Engineering and Technology Page 21│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
b. Complexity
Quicksort partitions an array and then calls itself recursively twice to sort the two resulting sub
arrays. This algorithm is quite efficient for large-sized data sets as its average and worst-case
complexity are O(n2), respectively.
Lab Tasks
Create a program that take an array of 10 inputs from the user and generate the sorted out put using
the following Algorithms;
Merge Sort
Quick Sort
Make a 10 digit array, sort by using merge and quick sort algorithm.
Sir Syed University of University of Engineering and Technology Page 22│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
Lab # 6
Implementation of searching algorithms over an Array based List
I. Objectives:
Different searching techniques using static Data Structure i.e. Array
target
Step 3: If the current value matches the target then we declare victory and stop
Step 4: If the current value is less than the target then set the current item to be the next item and
repeat from Step 2
Sir Syed University of University of Engineering and Technology Page 12│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
Step 2: Find the middle value of the list
Step 3: If the middle value is equal to the target then we declare victory and stop
Step 4: If the middle item is less than the target, then we set the new list to be the upper half of
the old list and we repeat from Step 2 using the new list
Step 5: If the middle value is greater than the target, then we set the new list to be the bottom half
of the list, and we repeat from Step 2 with the new list.
1 .Translate the linear search algorithm into a program which either find the location LOC where
ITEM appears in ARRAY or return LOC=0
2. Translate binary search and insertion algorithm into a program which finds either the location
LOC where ITEM appears in ARRAY or the location LOC where ITEM should be inserted
into ARRAY. (For object 3, 4, and 5 take an array of 10 elements given below)
3. Write a program which uses Binary Search to search the elements 52, and 33 and print it.
Write a program which uses Binary Search to search the elements 45, and 78 and delete it.
NUMBERS=[11,22,33,36,45,52,57,60,64,78].
Sir Syed University of University of Engineering and Technology Page 13│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
Lab # 6
Pointers: Implementation of Null pointer, Void Pointer,
Invalid Pointer, Dangling Pointer Reference Variable
A pointer is a variable whose value is the address of another variable. Like any variable or
constant, you must declare a pointer before you can work with it. The general form of a pointer
variable declaration is −
type *var-name;
Here, type is the pointer's base type; it must be a valid C++ type and var-name is the name of the
pointer variable. The asterisk you used to declare a pointer is the same asterisk that you use for
multiplication. However, in this statement the asterisk is being used to designate a variable as a
pointer. Following are the valid pointer declaration −
int *ip; // pointer to an integer
double *dp; // pointer to a
double float *fp; // pointer to a
float char *ch // pointer to
character
The actual data type of the value of all pointers, whether integer, float, character, or otherwise, is
the same, a long hexadecimal number that represents a memory address. The only difference
between pointers of different data types is the data type of the variable or constant that the pointer
points to.
I. Null Pointers
The NULL pointer is a constant with a value of zero defined in several standard libraries,
including iostream. Consider the following program
#include<iostream>
usingnamespace std;int
main (){int*ptr= NULL;
cout<<"The value of ptr is "<<ptr;
return0;
}
When the above code is compiled and executed, it produces the following result −
On most of the operating systems, programs are not permitted to access memory at address 0
because that memory is reserved by the operating system. However, the memory address 0 has
special significance; it signals that the pointer is not intended to point to an accessible memory
location. But by convention, if a pointer contains the null (zero) value, it is assumed to point to
nothing.
Thus, if all unused pointers are given the null value and you avoid the use of a null pointer, you
can avoid the accidental misuse of an uninitialized pointer. Many times, uninitialized variables
hold some junk values and it becomes difficult to debug the program.
#include<iostream>
int main () {
ptr = var;
cout<<ptr<<endl;
Sir Syed University of University of Engineering and Technology Page 14│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 6
return 0;
When the above code is compiled and executed, it produces result something as follows −
Value of var[0] = 10
A variable that is a pointer to a pointer must be declared as such. This is done by placing an
additional asterisk in front of its name. For example, following is the declaration to declare a
pointer to a pointer of type int − int **var;
When a target value is indirectly pointed to by a pointer to a pointer, accessing that value requires
that the asterisk operator be applied twice, as is shown below in the example −
Sir Syed University of University of Engineering and Technology Page 15│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
#include<iostream>
int main () {
int var;
int *ptr;
int **pptr;
When the above code is compiled and executed, it produces the following result −
Sir Syed University of University of Engineering and Technology Page 15│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 5
Lab # 7
I. Introduction to:
• LINKED LIST
Each cell is called a node of a singly-linked list. First node is called head and it's a dedicated
node. By knowing it, we can access every other node in the list. Sometimes, last node, called tail,
is also stored in order to speed up add operation.
• Adding a node
Sir Syed University of University of Engineering and Technology Page 25│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 6
• Removing a node
Traversal algorithm
2. do some actions with the current node, which is specific for particular algorithm;
3. Current node becomes previous and next node becomes current. Go to the step 1.
Example
For some algorithms tracking the previous node is essential, but for some, like an example, it's
unnecessary. We show a common case here and concrete algorithm can be adjusted to meet its
individual requirements.
Insertion into a singly-linked list has two special cases. It's insertion a new node before the head
(to the very beginning of the list) and after the tail (to the very end of the list). In any other case,
new node is inserted in the middle of the list and so, has a predecessor and successor in the list.
There is a description of all these cases below.
When list is empty, which is indicated by (head == NULL)condition, the insertion is quite
simple. Algorithm sets both head and tail to point to the new node.
Add first
In this case, new node is inserted right before the current head node.
Sir Syed University of University of Engineering and Technology Page 26│ Page (Department of
Computer Science and Information Technology)
It can be done in two steps:
1. Update the next link of a new node, to point to the current head node.
2. Update head link to point to the new node.
Add last
In this case, new node is inserted right after the current tail node.
1. Update the next link of the current tail node, to point to the new node.
General case
In general case, new node is always inserted between two nodes, which are already in the list.
Head and tail links are not updated in this case.
There are four cases, which can occur while removing the node. These cases are similar to the
cases in add operation. We have the same four situations, but the order of algorithm actions is
opposite. Notice, that removal algorithm includes the disposal of the deleted node, which may be
unnecessary in languages with automatic garbage collection (i.e., Java).
When list has only one node, which is indicated by the condition, that the head points to the same
node as the tail, the removal is quite simple. Algorithm disposes the node, pointed by head (or
tail) and sets both head and tail to NULL.
Remove first
In this case, first node (current head node) is removed from the list.
It can be done in two steps:
Remove last
In this case, last node (current tail node) is removed from the list. This operation is a bit more
tricky, than removing the first node, because algorithm should find a node, which is previous to
the tail first.
1. Update tail link to point to the node, before the tail. In order to find it, list should be
traversed first, beginning from the head.
General case
In general case, node to be removed is always located between two list nodes. Head and tail links
are not updated in this case.
1. Update next link of the previous node, to point to the next node, relative to the removed
node.
First node called head and no other node points to it. Link to the head is usually stored it the
class, which provides an interface to the resulting data structure. For empty list, head is set to
NULL. Also, it makes sense to store a link to the last node, called tail. Though no node in the
list can be accessed from the tail (because we can move forward only), it can accelerate an add
operation, when adding to the end of the list. When list is big, it reduces add operation
complexity essentially, while memory overhead is insignificant.
Doubly linked list with the help of algorithms for Insertion, Deletion an element
In singly linked list, we can move/traverse only in one single direction because each node has the
address of the next node only. Suppose we are in the middle of the linked list and we want the
address of previous node then we don‟t have any option other than repeating the traversing from
the beginning node.
To overcome this drawback, a doubly linked list can be used. In this, there are two pointers. One
of these pointers points to the next node and the other points to the previous node.
The structure for a doubly linked list node can be declared as:
struct node
{ struct node
*prev_node;
int info;
};
prev_node would contain a pointer to the address of the previous node and next_node would
point the next node in the list. Hence, we can move in both the directions.
V. Lab Task
1 Write a program as follows
3. Search an element
4. Display List
5. Is List Empty
6. Exit
Lab # 8
An array based implementation of STACK with the help ofalgorithm
I. Introduction to:
1. STACK
3. Operation of STACK
II. Stack
Stack: is an ordered group of homogeneous items of elements.
Elements are added to and removed from the top of the stack (the most recently added items are
at the top of the stack).
The last element to be added is the first to be removed (LIFO: Last In, First Out).
a) Stack Operation
MakeEmpty
Boolean IsEmpty
Boolean IsFull
Push (ItemTypenewItem)
Push(ItemTypenewItemId)
Sir Syed University of University of Engineering and Technology Page 31│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 8
Pop(ItemType&Item)
Postconditions: Top element has been removed from stack and item is a copy of the removed
element.
3. Display all
4. Top element
5. Exit
2 Test the program using the following procedure: STACK of size N=6
1. Call PUSH(5)
2. Call PUSH(2)
3. Call PUSH(3)
4. Call POP()
5. Call PUSH(6)
6. Call PUSH(9)
7. Call PUSH(3)
8. Call DISPLAY()
Sir Syed University of University of Engineering and Technology Page 32│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 7
Lab # 9
I. Introduction to:
1. QUEUE
3. Operation of QUEUE
The process to add an element into queue is called Enqueue and the process of removal of an
element from queue is called Dequeue.
Like Stack, Queue is also an ordered list of elements of similar data types.
2. Once a new element is inserted into the Queue, all the elements inserted before the new
element in the queue must be removed, to remove the new element.
3. peek( ) function is oftenly used to return the value of first element without dequeuing it.
Sir Syed University of University of Engineering and Technology Page 33│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 8
b) Application of Queue
Queue, as the name suggests is used whenever we need to have any group of objects in an order
in which the first one coming in, also gets out first while the others wait for there turn, like in the
following scenarios :
Serving requests on a single shared resource, like a printer, CPU task scheduling etc.
1. In real life, Call Center phone systems will use Queues, to hold people calling them in an
order, until a service representative is free.
2. Handling of interrupts in real-time systems. The interrupts are handled in the same order as
they arrive, First come first served.
c) Implementation of Queue
Queue can be implemented using an Array, Stack or Linked List. The easiest way of
implementing a queue is by using an Array. Initially the head(FRONT) and the tail(REAR) of the
queue points at the first index of the array (starting the index of array from 0). As we add
elements to the queue, the tail keeps on moving ahead, always pointing to the position where the
next element will be inserted, while the head remains at the first index.
When we remove element from Queue, we can follow two possible approaches (mentioned [A]
and [B] in above diagram). In [A] approach, we remove the element at head position, and then
one by one move all the other elements on position forward. In approach [B] we remove the
element from head position and then move head to the next position.
In approach [A] there is an overhead of shifting the elements one position forward every time we
remove the first element. In approach [B] there is no such overhead, but whener we move head
one position ahead, after removal of first element, the size on Queue is reduced by one space
each time.
3. Display all
Sir Syed University of University of Engineering and Technology Page 34│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 9
4. Exit
enQueue(3) Call
deQueue ()
calldeQueue()
Call enQueue(6)
Call enQueue(3)
Call Display()
Sir Syed University of University of Engineering and Technology Page 35│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 8
Lab # 10
Implementation of the BINARY TREE with the help of algorithms
I. Introduction to:
Binary search tree is a data structure, which meets the following requirements:
• it is a binary tree;
• a total order is defined on these values (every two values can be compared with each
other);
• leftsubtree of a node contains only values lesser, than the node's value; • rightsubtree of a
Sir Syed University of University of Engineering and Technology Page 36│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 9
Like any other dynamic data structure, BST requires storing of some additional auxiliary data, in
order to keep its structure. Each node of binary tree contains the following information:
Sir Syed University of University of Engineering and Technology Page 37│ Page (Department of
Computer Science and Information Technology)
• a value (user's data);
• a link to the left child (auxiliary data);
• a link to the right child (auxiliary data).
Depending on the size of user data, memory overhead may vary, but in general it is quite
reasonable. In some implementations, node may store a link to the parent, but it depends on
algorithm, programmer want to apply to BST. For basic operations, like addition, removal and
search a link to the parent is not necessary. It is needed in order to implement iterators.
With a view to internal representation, the sample from the overview changes:
Leaf nodes have links to the children, but they don't have children. In a programming language it
means, that corresponding links are set to NULL.
Remove operation on binary search tree is more complicated, than add and search. Basically, in
can be divided into two stages:
Now, let's see more detailed description of a remove algorithm. First stage is identical to
algorithm for lookup, except we should track the parent of the current node. Second part is
trickier.
This case is quite simple. Algorithm sets corresponding link of the parent to NULL and disposes
the node.
Example. Remove -4 from a BST.
It this case, node is cut from the tree and algorithm links single child (with it'ssubtree) directly to
the parent of the removed node.Example.
This is the most complex case. To solve it, let us see one useful BST property first. We are going
to use the idea, that the same set of values may be represented as different binary-search trees.
For example those BSTs:
contains the same values {5, 19, 21, 25}. To transform first tree into second one, we can do
following:
choose minimum element from the right subtree (19 in the example); replace 5
The same approach can be utilized to remove a node, which has two children:
Replace 12 with 19. Notice, that only values are replaced, not nodes. Now we have two nodes
with the same value.
65
Data Structures and Algorithms (CS-212) Lab # 11
Lab # 11
I. Introduction to:
1. BINARY SEARCH TREE structure representation
Every node (excluding a root) in a tree is connected by a directed edge from exactly one other
node. This node is called a parent. On the other hand, each node can be connected to arbitrary
number of nodes, called children. Nodes with no children are called leaves, or external nodes.
Nodes which are not leaves are called internal nodes. Nodes with the same parent are called
siblings.
First of all, binary search tree (BST) is a dynamic data structure, which means, that its size is
only limited by amount of free memory in the operating system and number of elements may
vary during the program run. Main advantage of binary search trees is rapid search, while
addition is quite cheap. Let us see more formal definition of BST.
Binary search tree is a data structure, which meets the following requirements:
• it is a binary tree;
Sir Syed University of University of Engineering and Technology Page 41│ Page (Department of
Computer Science and Information Technology)
• a total order is defined on these values (every two values can be compared with each
other);
• leftsubtree of a node contains only values lesser, than the node's value; • rightsubtree of
a node contains only values greater, than the node's value. Notice, that definition above
doesn't allow duplicates.
Like any other dynamic data structure, BST requires storing of some additional auxiliary data, in
order to keep its structure. Each node of binary tree contains the following information:
Depending on the size of user data, memory overhead may vary, but in general it is quite
reasonable. In some implementations, node may store a link to the parent, but it depends on
algorithm, programmer want to apply to BST. For basic operations, like addition, removal and
search a link to the parent is not necessary. It is needed in order to implement iterators.
With a view to internal representation, the sample from the overview changes:
Leaf nodes have links to the children, but they don't have children. In a programming language it
means, that corresponding links are set to NULL.
Data Structures and Algorithms (CS-212) Lab # 11
Lab # 12
Implementation Tree Traversal with the help of algorithms
I. Tree Traversal:
A traversal is a process that visits all the nodes in the tree. Since a tree is a nonlinear data
structure, there is no unique traversal. We will consider several traversal algorithms with we
group in the following two kinds
• depth-first traversal
• breadth-first traversal
• PreOrder traversal - visit the parent first and then left and right children;
• InOrder traversal - visit the left child, then the parent and the right child;
• PostOrder traversal - visit left child, then the right child and then the parent;
There is only one kind of breadth-first traversal--the level order traversal. This traversal visits
nodes by levels from top to bottom and from left to right.
- 9, 5, 1, 7, 2, 12, 8, 4, 3, 11
Sir Syed University of University of Engineering and Technology Page 43│ Page (Department of
Computer Science and Information Technology)
II. Lab Task
1. Write a program to print the nodes of the following Tree diagram through Pre-Order,
Lab # 13
Implementation of Graph and its representation
A Graph is a non-linear data structure consisting of nodes and edges. The nodes are sometimes also
referred to as vertices and the edges are lines or arcs that connect any two nodes in the graph.
A Graph consists of a finite set of vertices(or nodes) and set of Edges which connect a pair of
nodes.
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}.An example of an undirected graph with 5 vertices.
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. For example, in Facebook, each person is
represented with a vertex(or node). Each node is a structure and contains information like person
id, name, gender, locale etc.
Graph is a data structure that consists of following two components:
1. A finite set of vertices also called as nodes.
2. A finite set of ordered pair of the form (u, v) called as edge. The pair is ordered because (u, v) is
not same as (v, u) in case of a directed graph(di-graph). The pair of the form (u, v) indicates that
there is an edge from vertex u to vertex v. The edges may contain weight/value/cost.
Sir Syed University of University of Engineering and Technology Page 45│ Page (Department of
Computer Science and Information Technology)
I. Adjacency Matrix:
Adjacency Matrix is a 2D array of size V x V where V is the number of vertices in a graph. Let
the 2D array be adj[][], a slot adj[i][j] = 1 indicates that there is an edge from vertex i to vertex j.
Adjacency matrix for undirected graph is always symmetric. Adjacency Matrix is also used to
represent weighted graphs. If adj[i][j] = w, then there is an edge from vertex i to vertex j with
weight w.
Pros: Representation is easier to implement and follow. Removing an edge takes O(1) time.
Queries like whether there is an edge from vertex „u‟ to vertex „v‟ are efficient and can be done
O(1).
Cons: Consumes more space O(V^2). Even if the graph is sparse(contains less number of edges), it
consumes the same space. Adding a vertex is O(V^2) time.
Please seethisfor a sample Python implementation of adjacency matrix.
An array of lists is used. Size of the array is equal to the number of vertices. Let the array be
array[]. An entry array[i] represents the list of vertices adjacent to theith vertex. This
representation can also be used to represent a weighted graph. The weights of edges can be
represented as lists of pairs. Following is adjacency list representation of the above graph.
III. Lab Task
1.Implement representation of graph by Adjacency Matrix and Adjacency List.
Data Structures and Algorithms (CS-212) Lab # 13
Lab # 14
Implementation of Breadth first and Depth first Traversal for
aGraph
Graphs may contain cycles, so we may come to the same node again. To avoid processing a node
more than once, we use a boolean visited array.
Sir Syed University of University of Engineering and Technology Page 48│ Page (Department of
Computer Science and Information Technology)
Data Structures and Algorithms (CS-212) Lab # 13
For example, in the following graph, we start traversal from vertex 2. When we come to vertex 0,
we look for all adjacent vertices of it. 2 is also an adjacent vertex of 0. If we don‟t mark visited
vertices, then 2 will be processed again and it will become a non-terminating process. A Depth
First Traversal of the following graph is 2, 0, 1, 3.
Sir Syed University of University of Engineering and Technology Page 49│ Page (Department of
Computer Science and Information Technology)