0% found this document useful (0 votes)
14 views

CS-250 Data Structures and Algorithms 2024

Uploaded by

ahtisham0100
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views

CS-250 Data Structures and Algorithms 2024

Uploaded by

ahtisham0100
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 96

COMPUTER LABORATORY MANUAL

CS-250
Data Structures and Algorithms
Fall Semester

DEPARTMENT OF COMPUTER SOFTWARE ENGINEERING


Military College of Signals
National University of Sciences and Technology
www.mcs.nust.edu.pk
PREFACE
This lab manual has been prepared to facilitate the students of software engineering in studying and analyzing data
structures and algorithms. The aim of this course is to provide an introduction to computer algorithms and data structures,
with an emphasis on practical implementations. Data Structures and Algorithms introduces fundamental techniques for
problem solving that are relevant to most areas of computer science, both theoretical and applied. Algorithms and data
structures for sorting, searching, graph problems, and geometric problems are covered. The lab manual is designed to help
students understand the basic concepts of data structures and implement basic computer science algorithms in object-
oriented approach.

PREPARED BY
Lab manual is prepared by Dr. Naima Iltaf and Lab Engr. Misbah Ghalib under the supervision of Head of Department
Dr. Naveed Iqbal Rao in year 2014.

GENERAL INSTRUCTIONS
a. Students are required to maintain the lab manual with them till the end of the semester.
b. All readings, answers to questions and illustrations must be solved on the place provided. If more space is
required then additional sheets may be attached.
c. It is the responsibility of the student to have the manual graded before deadlines as given by the instructor
d. Loss of manual will result in re submission of the complete manual.
e. Students are required to go through the experiment before coming to the lab session. Lab session details will
be given in training schedule.
f. Students must bring the manual in each lab.
g. Keep the manual neat clean and presentable.
h. Plagiarism is strictly forbidden. No credit will be given if a lab session is plagiarized and no re submission
will be entertained.
i. Marks will be deducted for late submission
VERSION HISTORY

Date Updated By Details


Sept 2012 Asst Prof Bilal Rauf First Version Created
Aug 2014 Dr Naima Iltaf Updated Experiment 1 and Experiment 3
Added resources and summaries to the experiments. Formatted the
Jan 2016 Aamna Mehfooz
manual according to standard. New exercises have been added
A/P Bilal Rauf & Lab Engr.
Sept 2017 Added new lab and contents revised.
Maemoona Kayani
A/P Bilal Rauf & Lab Engr.
Oct 2018 Added Lab Rubrics
Maemoona Kayani
A/p Dr Zaki, Lab Engr
Sept 2019 Updated CLOs and exercises
Marium Hida
Lt Col Khawir Mehmood,
Oct 2021 New Lab added, Lab Rubrics and Course CLOs updated
Lab Engr Marium Hida
Sep 2023 Lab Engr. Muntaha Noor New lab added, updated experiment# 1,2,3,10
Jan 2024 Lab Engr. Muntaha Noor Added Open Ended Lab

2 Data Structures and Algorithms


Department of Computer Software Engineering
Lab Rubrics
Programming Tasks
Criteria Unacceptable Substandard Adequate Proficient
(Marks=0) Marks=1 Marks=2 Marks=3
The program execution let to
The program was correctly
R1 The program failed to inaccurate or incomplete The program was correctly
functional and most of the
Completeness produce the right accurate results. It was not correctly functional, and all the features
features were
And Accuracy result functional or not all the were implemented
implemented
features were implemented
Student successfully figures Student successfully
The student fails to figure Student successfully figures out
R2 out few of syntax and figures out most of syntax
out the syntax and semantic all syntax and semantic errors
Syntax and semantic errors of the and semantic errors of the
errors of the incorrect of the program without any
Semantics program with extensive program with minimum
program guidance
guidance guidance
Student has basic Student has demonstrated on
Student failed to
Student has basic knowledge of accurate understanding of the
R3 demonstrate a clear
understanding, but asked understanding. Provides lab objective and concepts. All
Demonstration understanding of the
questions were not answered. fundamental answers to the questions are answered
assigned task
asked questions completely and correctly
R4 The code is readable only by The code is exceptionally well
The code is poorly organized The code is fairly easy to
Complexity and someone who knows what it is organized and very easy to
and very difficult to read read
Readability supposed be doing follow
Complete working program
Most of working program
R5 is copied indicating no effort Most of working program is
is contributed by the Complete working program is
Perseverance on student’s part resulting copied. Minor contribution by
student. Minor copied contributed by the student
and plagiarism in a total score of zero for the student
components
all rubrics

3 Data Structures and Algorithms


Department of Computer Software Engineering
Lab Rubrics
Group Tasks
Criteria Unacceptable Substandard Adequate Proficient
(Marks=0) Marks=1 Marks=2 Marks=3
The system execution let to
The system was correctly
R1 The system failed to inaccurate or incomplete The system was correctly
functional and most of
Completeness produce the right accurate results. It was not correctly functional, and all the features
the features were
and Accuracy result functional or not all the were implemented
implemented
features were implemented
The student has demonstrated
The student failed to The student has basic The student has
on accurate understanding of
R2 demonstrate a clear knowledge of understanding moderate knowledge of
the lab objective and concepts.
Demonstration understanding of the but asked questions were not understanding. Answer
All the questions are answered
assigned task answered. to the question are basic
completely and correctly
Complete working program
Most of working program
is copied indicating no effort Most of working program is
R3 is contributed by the Complete working program is
on student’s part resulting in copied. Minor contribution by
Plagiarism student. Minor copied contributed by the student
a total score of zero for all the student
components
rubrics
R4 Demonstrates
Shows little commitment to Demonstrates commitment to Actively helps to identify group
Contribution/ commitment to group
group goals and fails to group goals, but has difficulty goals and works effectively to
Group goals and carries out
perform assigned roles performing assigned roles meet them in all roles assumed
participation assigned roles effectively
Poor presentation; cannot Presentation lacks clarity and Well-organized, clear
Presentation acceptable;
R5 explain topic; scientific organization; little use of presentation; good use of
adequate use of scientific
Presentation terminology lacking or scientific terms and scientific vocabulary and
terms; acceptable
skills confused; lacks vocabulary; poor terminology; good
understanding of topic
understanding of topic understanding of topic understanding of topic

4 Data Structures and Algorithms


Department of Computer Software Engineering
Lab Rubrics
Open Ended Lab
Criteria Unacceptable Substandard Adequate Proficient
(Marks=0) Marks=1 Marks=2 Marks=3
R1 (CLO-4) The program lacks essential The program partially The program successfully The program fully implements
Functionality functionalities such as book implements functionalities but implements most all functionalities,
Completeness management, user lacks coherence in managing functionalities with minor demonstrating comprehensive
interaction, and transaction library resources. bugs or inconsistencies. management of library
history. resources and transactions
R2 (CLO-4) The code is disorganized, The code structure is The code is well- The code is exceptionally well-
Code Quality and unreadable, and fails to somewhat organized but lacks structured, readable, and organized, adheres to C++ best
Organization adhere to programming proper comments and mostly adheres to C++ best practices, and includes
standards. documentation. practices. comprehensive comments and
documentation.
R3 (CLO-4) The program exhibits The program demonstrates The program efficiently The program excels in
Algorithmic significant inefficiencies, basic efficiency but lacks utilizes data structures and efficiency, ensuring swift and
Efficiency resulting in slow optimization in search and algorithms for satisfactory responsive performance in all
performance sorting operations. performance. operations.
R4 (CLO-2) The program lacks a user- The program has a basic The program features a The program offers an
User Interface friendly interface, making it interface with limited user-friendly interface with exceptional user experience
and Experience difficult to navigate and use. functionalities and user intuitive controls and clear with a visually appealing
guidance. instructions. interface, seamless navigation,
and comprehensive user
guidance.
R5 (CLO-2) The documentation is The documentation is The documentation is well- The documentation is
Documentation absent or incomplete, rudimentary, providing prepared, including user exemplary, offering detailed
and Reflection lacking essential minimal guidance on program manuals, comprehensive user guides, extensive test
components such as user functionalities. test cases, and a reflective cases with expected outputs,
manuals and test cases analysis. and insightful reflective
analysis.

5 Data Structures and Algorithms


COURSE LEVEL OUTCOMES
CS-250 Data Structures and Algorithm

Course Learning Outcomes (CLOs)

At the end of the course the students will be able to: PLOs BT Level*

1. Explain various data structures and their algorithms 1 C-2


2. Demonstrate the working of simple algorithms and 2 C-3
determine their complexities
3 Analyze the problem statement and apply appropriate data 3 C-4
structures to design solutions
4 Practice and apply appropriate data structures and algorithms 5 P-3
to design solutions

Mapping of CLOs to Program Learning Outcomes


PLOs/CLOs CLO1 CLO2 CLO3 CLO4
PLO 1 (Engineering Knowledge) √
PLO 2 (Problem Analysis)
PLO 3 (Design/Development of Solutions) √
PLO 4 (Investigation) √
PLO 5 (Modern tool usage) √
PLO 6 (The Engineer and Society)
PLO 7 (Environment and Sustainability)
PLO 8 (Ethics)
PLO 9 (Individual and Team Work)
PLO 10 (Communication)
PLO 11 (Project Management)
PLO 12 (Lifelong Learning)

6 Data Structures and Algorithms


S No List of Experiments CLO
1 Introduction to DS, C++ Pointers and Arrays 3-4
2 Singly Linked List 3-4
3 Doubly Linked List 3-4
4 Circular Linked List 3-4
5 Stacks 3-4
6 Applications of Stack 3-4
7 Queues 3-4
8 Recursion 3-4
9 Sorting-I 3-4
10 Sorting-II 3-4
11 Searching 3-4
12 Binary Search Tree 3-4
13 Graphs 3-4
14 Hashing 3-4
15 Open Ended Lab -
16 Lab Exam/Project -

7 Data Structures and Algorithms


LIST OF EXPERIMENTS
EXPERIMENT 1 – INTRODUCTION TO DS, C++ POINTERS AND ARRAYS.............................................................9
EXPERIMENT 2 – SINGLY LINKED LISTS...................................................................................................................18
EXPERIMENT 3 – DOUBLY LINKED LISTS.................................................................................................................30
EXPERIMENT 4 – CIRCULAR LINKED LISTS..............................................................................................................42
EXPERIMENT 5 – STACKS.............................................................................................................................................45
EXPERIMENT 6– APPLICATIONS OF STACK..............................................................................................................50
EXPERIMENT 7 – QUEUES.............................................................................................................................................55
EXPERIMENT 8 – RECURSION......................................................................................................................................60
EXPERIMENT 9 – SORTING-I.........................................................................................................................................64
EXPERIMENT 10 – SORTING-II......................................................................................................................................67
EXPERIMENT 11 – SEARCHING....................................................................................................................................71
EXPERIMENT 12 – BINARY SEARCH TREE................................................................................................................74
EXPERIMENT 13 – GRAPHS...........................................................................................................................................81
EXPERIMENT 14– HASHING..........................................................................................................................................86
EXPERIMENT 15 OPEN ENDED LAB............................................................................................................................93

8 Data Structures and Algorithms


EXPERIMENT 1 – INTRODUCTION TO DS, C++ POINTERS AND ARRAYS
1. Objectives:
(a). Revise arrays and use of arrays with pointers
(b). To learn basic terminologies and syntax to use pointers in C++
2. Time Required: 3 hrs
3. Software Required:
(a). Windows OS
(b). Bloodshed Dev C++
(c). Microsoft Visual Studio 2012

4. Constructors:
It is convenient if an object can initialize itself when it is first created, without need to make a
separate call to its member functions. C++ provides a non-static member function called as
constructor that is automatically called when object is created. After objects are created, their
members can be initialized by using constructors.

Important points to be noted while using constructors


 Constructor name must be the same as that of its class name in which it belongs.
 Constructors are invoked automatically when objects are created.
 Constructors cannot specify return types nor return values.
 Constructors cannot be declared static or const.
 Constructors should have public access within the class

The syntax of Constructors is as follows:

<class-name> (list-of-parameters);

Constructors can be defined inside or outside the class declaration:-

The syntax for defining the constructor within the class:

<class-name> (list-of-parameters) { // constructor definition }

The syntax for defining the constructor outside the class:

<class-name>: :<class-name> (list-of-parameters){ // constructor definition

9 Data Structures and Algorithms


Activity 1.1 : Class with Constructor

# include<iostream.h>
class maths{
int a;
public:
maths(); //constructor declaration
void showdata(); //method to display the value of a
};
maths :: maths(){ //implementation of constructor and initizalize a with value 100
cout<<”\n this is a constructor”;
a=100;
}

void maths :: showdata(){ //method implementation prints value of a i.e. 100


cout<<”\n the value of a=”<<a;
}
void main (){ //main function
maths m; //object creation, constructor is called
m.showdata(); // calls method showdata
}

// defining the constructor within the class

#include <iostream>
using namespace std;

class student { //class define


int rno;
char name[10];
double fee; //float

public:
student() //constructor define within the class
{
cout << "Enter the RollNo:";
cin >> rno;
cout << "Enter the Name:";
cin >> name;
cout << "Enter the Fee:";
cin >> fee;
}

void display() //display method


{
cout << endl << rno << "\t" << name << "\t" << fee;
}
};

int main() // main function


{
student s; // constructor gets called automatically when
// we create the object of the class
s.display();

return 0;
}

10 Data Structures and Algorithms


// defining the constructor outside the class

#include <iostream>
using namespace std;
class student { // define class
int rno;
char name[50];
double fee;

public:
student(); //constructor declaration
void display(); //display function declaration
};

student::student() //constructor defin outside the class


{
cout << "Enter the RollNo:";
cin >> rno;

cout << "Enter the Name:";


cin >> name;

cout << "Enter the Fee:";


cin >> fee;
}

void student::display()
{
cout << endl << rno << "\t" << name << "\t" << fee;
}

int main()
{
student s;
s.display();

return 0;
}

11 Data Structures and Algorithms


//parameterized constructor

#include <iostream>

using namespace std;


class Line {
public:
void setLength( double len ); //function to set length
double getLength( void ); //function to get length
Line(double len); // parameterized constructor

private:
double length;
};

// Member functions definitions including constructor

Line::Line( double len) { //parameteri8zed const define


cout << "Object is being created, length = " << len <<
endl;
length = len;
}
void Line::setLength( double len ) { //function define
length = len;
}
double Line::getLength( void ) {
return length;
}

// Main function for the program


int main() {
Line obj(10.0);

// get initially set length.


cout << "Length of line : " << obj.getLength() <<endl;

// set line length again


obj.setLength(6.0);
cout << "Length of line : " << obj.getLength() <<endl;

return 0;
}

12 Data Structures and Algorithms


5. Destructors:
A destructor is a member function that is called automatically when an object is destroyed.
The syntax for defining the destructor within the class
~ <class-name>()
{
}
Where the class name is the name of the destructor and is preceded by a tilde (~)
(pronounced as til-duh) symbol.

The syntax for defining the destructor outside the class

<class-name>: : ~ <class-name>()
{

It is not possible to define more than one destructor. The destructor is only one way to destroy the
object created by the constructor. Hence destructor can-not be overloaded. Destructor neither
requires any argument nor returns any value. It is automatically called when the object goes out of
scope. Destructors release memory space occupied by the objects created by the constructor. In
destructor, objects are destroyed in the reverse of object creation.

First Example
#include <iostream>
using namespace std;

class Test {
public:
Test() { cout << "\n Constructor executed"; }//construction

~Test() { cout << "\n Destructor executed"; }//destructor


};
main()
{
Test t; //1 time execution of both

return 0;
}
Second Example
#include <iostream>
using namespace std;
class Test {
public:
Test() { cout << "\n Constructor executed"; }

~Test() { cout << "\n Destructor executed"; }


};

main()
{
Test t, t1, t2, t3; //4 time execution
return 0;
}

13 Data Structures and Algorithms


Characteristics of a destructor:-
1. Destructor is invoked automatically by the compiler when its corresponding constructor
goes out of scope and releases the memory space that is no longer required by the program.
2. Destructor neither requires any argument nor returns any value therefore it cannot be
overloaded.
3. Destructor cannot be declared as static and const;
4. Destructor should be declared in the public section of the program.
5. Destructor is called in the reverse order of its constructor invocation.

6. Arrays:
An array is a collection of individual values, all of the same data type, stored in adjacent memory
locations. Using the array name together with an integral valued index in square brackets refers to
the individual values. Multi-dimensional arrays have additional indices for each additional
dimension. The index indicates the position of the individual component value within the collection
of values. The index is also called the subscript.
In C++, the first array element always has subscript 0. The second array element has subscript 1,
etc. The base address of an array is its beginning address in memory.

Activity 1.2 : Swap 1st & last element of 1-dimensional Array


#include<iostream.h>
#include<conio.h>

int main()
{
intArr[100],n,temp; //array hold up to 100 integers, temp is temporary variable used for swapping values

cout<<"Enter number of elements you want to insert ";


cin>>n;

for(inti=0;i<n;i++)
{
cout<<"Enter element "<<i+1<<":";
cin>>Arr[i]; //reads user input and store in array index i
}

temp=Arr[0]; //store first element of array


Arr[0]=Arr[n-1]; //assign last element to first position
Arr[n-1]=temp; //assign original first element store in temp to last position

cout<<"\nArray after swapping"<<endl; //msg indicates that array has been modified

for(i=0;i<n;i++) //loop through array from index 0 to n-1


cout<<Arr[i]<<" "; //print each element of array, separated by space

getch(); //key press for closing program


return 0;
}

14 Data Structures and Algorithms


7. Pointers:
A pointer is a memory variable that stores a memory address of another variable and can also be
defined as it is a variable that holds the address of some other memory location. It is always
denoted by ‘*’. Following example describes that how to declare and assign memory address to an
integer pointer.

Activity 1.3 : How to use pointer


#include <iostream>
#include<conio.h>
using namespace std;
int main ()
{
int firstvalue = 5, secondvalue = 15; //2 int
cout<< "first value before pointers is "<<firstvalue<<endl;
cout<< "second value before pointers is "<<secondvalue<<endl;
int * p2; //pointers
int *p1 = &firstvalue; // p1 = address of firstvalue, & operator give memory address to
firstvalue

p2 = &secondvalue; // p2 = address of second value


*p1 = 10; // first value changes by 10
*p2 = 20; // value pointed by p2 = 20
cout<<"After pointers"<<endl;
cout<< "firstvalue is " <<firstvalue<<endl;
cout<< "secondvalue is " <<secondvalue<<endl;
return 0;
}

15 Data Structures and Algorithms


16 Data Structures and Algorithms
8. Exercises:

Exercise 1.1:
Write a program with constructor function and another for destruction function.

Exercise 1.2:
Write a program to search an element (given by user) in a two-dimensional array.

Exercise 1.3:
Introduce int variables x, y, z and int* pointer variables p, q, r. Set x, y, z to three
distinct values. Set p, q, r to the addresses of x, y, z respectively.

• Print with labels the values of x, y, z, p, q, r, *p, *q, *r.


• Print the message: Swapping values.
• Execute the swap code: z = x; x = y; y = z;
• Print with labels the values of x, y, z, p, q, r, *p, *q, *r.

9. Web Resources:
http://www.tutorialspoint.com/cplusplus/cpp_constructor_destructor.htm
http://www.cplusplus.com/doc/tutorial/arrays/
http://www.tutorialspoint.com/cplusplus/cpp_pointers.htm

10. Video Resources:


http://www.infiniteskills.com/training/programming-c++-training-video/arrays-in-functions.html
http://www.learnerstv.com/video/Free-video-Lecture-5620-Computer-Science.htm
http://www.learnerstv.com/video/Free-video-Lecture-13737-Computer-Science.htm

11. Summary:
This lab session introduces the concepts of constructors and destructors, arrays and pointers in C++.
This lab is designed to revise the concepts of arrays and pointers which will be used in
implementing the concepts of data structures.

17 Data Structures and Algorithms


EXPERIMENT 2 – SINGLY LINKED LISTS
1. Objectives:
(a). Understand the concepts of singly linked lists
(b). Implement singly linked list using dynamic structures
2. Time Required: 3 hrs

3. Software Required:
(a) Microsoft Windows
(b) Microsoft Visual Studio 2012

4. Linked Lists: A linked list is a data structure consisting of a group of nodes which together
represent a sequence. Under the simplest form, each node is composed of a datum and a reference
(in other words, a link) to the next node in the sequence; more complex variants add additional
links. This structure allows for efficient insertion or removal of elements from any position in the
sequence.
last
first

Why Linked List?


Arrays can be used to store linear data of similar types, but arrays have the following
limitations:
 The size of the arrays is fixed: So we must know the upper limit on the number of
elements in advance. Also, generally, the allocated memory is equal to the upper limit
irrespective of the usage.
 Insertion of a new element / Deletion of an existing element in an array of elements is
expensive: The room has to be created for the new elements and to create room existing
elements have to be shifted but in Linked list if we have the head node then we can
traverse to any node through it and insert new node at the required position.

Syntax to create a linked list.


class Node {
public:
int data;
Node* next; //pointer
};
Construction of a simple linked list with 3 nodes:
#include<iostream>
using namespace std;

class Node {
public:

18 Data Structures and Algorithms


int data;
Node* next; //pointer
};

int main()
{
Node* head = NULL;
Node* second = NULL;
Node* third = NULL;

// allocate 3 nodes in the heap


head = new Node();
second = new Node();
third = new Node();

/* Three blocks have been allocated dynamically.


We have pointers to these three blocks as head,
second and third
head second third
| | |
| | |
+---+-----+ +----+----+ +----+----+
| # | # | | # | # | | # | # |
+---+-----+ +----+----+ +----+----+

# represents any random value.


Data is random because we haven’t assigned
anything yet */

head->data = 1; // assign data in first node


head->next = second; // Link first node with
// the second node

/* data has been assigned to the data part of first


block (block pointed by the head). And next
pointer of the first block points to second.
So they both are linked.

head second third


| | |
| | |
+---+---+ +----+----+ +-----+----+
| 1 | o----->| # | # | | # | # |
+---+---+ +----+----+ +-----+----+
*/

// assign data to second node


second->data = 2;

// Link second node with the third node


second->next = third;

/* data has been assigned to the data part of the second


block (block pointed by second). And next
pointer of the second block points to the third
block. So all three blocks are linked.

19 Data Structures and Algorithms


head second third
| | |
| | |
+---+---+ +---+---+ +----+----+
| 1 | o----->| 2 | o-----> | # | # |
+---+---+ +---+---+ +----+----+ */

third->data = 3; // assign data to third node


third->next = NULL;

/* data has been assigned to the data part of the third


block (block pointed by third). And next pointer
of the third block is made NULL to indicate
that the linked list is terminated here.

We have the linked list ready.

head
|
|
+---+---+ +---+---+ +----+------+
| 1 | o----->| 2 | o-----> | 3 | NULL |
+---+---+ +---+---+ +----+------+

Note that only the head is sufficient to represent


the whole list. We can traverse the complete
list by following the next pointers. */

return 0;
}

Traversal of a Linked List


#include<iostream>
using namespace std;

class Node {
public:
int data;
Node* next;
};

// This function prints contents of linked list


// starting from the given node
void printList(Node* n)
{
while (n != NULL) {
cout << n->data << " ";
n = n->next;
}
}

20 Data Structures and Algorithms


int main()
{
Node* head = NULL;
Node* second = NULL;
Node* third = NULL;

// allocate 3 nodes in the heap


head = new Node();
second = new Node();
third = new Node();

head->data = 1; // assign data in first node


head->next = second; // Link first node with second

second->data = 2; // assign data to second node


second->next = third;

third->data = 3; // assign data to third node


third->next = NULL;

// Function call
printList(head);

return 0;
5. }

Insertion: To insert data in a linked list, a record is created holding the new item. The nextpointer
of the new record is set to link it to the item which is to follow it in the list. The nextpointer of the
item which is to precede it must be modified to point to the new item.

21 Data Structures and Algorithms


A node can be added in three ways
 At the front of the linked list
 After a given node.
 At the end of the linked list.

At the front of the linked list


void front(int n)
{
node *tmp = new node;
tmp -> data = n;
tmp -> next = head;
head = tmp;
}
After a given node
void after(node *a, int value)
{
node* p = new node;
p->data = value;
/*
if initial linked list is
_______ _______ _______
| 1 |____\ | 3 |____\ | 5 |____\ NULL

22 Data Structures and Algorithms


|_______| / |_______| / |_______| /
and new node's value is 10
then the next line will do something like
_______ _______ _______
| 1 |____\ | 3 |____\ | 5 |____\ NULL
|_______| / |_______| / |_______| /
/ \
|
|
___|___
| 10 |
|_______|
*/
p->next = a->next;
a->next = p;
/*
now the linked list will look like:
_______ _______ _______ _______
| 1 |____\| 10 |____\ | 3 |____\ | 5 |____\ NULL
|_______| /|_______| / |_______| / |_______| /
*/
}

At the end of the linked list


void add_node(int n)
{
node *tmp = new node;
tmp->data = n;
tmp->next = NULL;

if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}

6. Deletion:To deleted data from list, The nextpointer of the item immediately preceding the one to
be deleted is altered, and made to point to the item following the deleted item.

23 Data Structures and Algorithms


Deletion example
#include <iostream>
using namespace std;

// A linked list node


class Node{
public:
int data;

24 Data Structures and Algorithms


Node* next;
};

// Given a reference (pointer to pointer)


// to the head of a list and an int,
// inserts a new node on the front of the
// list.
void push(Node** head_ref, int new_data)
{
Node* new_node = new Node();
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
// Given a reference (pointer to pointer)
// to the head of a list and a key, deletes
// the first occurrence of key in linked list
void deleteNode(Node** head_ref, int key)
{

// Store head node


Node* temp = *head_ref;
Node* prev = NULL;

// If head node itself holds


// the key to be deleted
if (temp != NULL && temp->data == key)
{
*head_ref = temp->next; // Changed head
delete temp; // free old head
return;
}

// Else Search for the key to be deleted,


// keep track of the previous node as we
// need to change 'prev->next' */
else
{
while (temp != NULL && temp->data != key)
{
prev = temp;
temp = temp->next;
}

// If key was not present in linked list


if (temp == NULL)
return;

// Unlink the node from linked list


prev->next = temp->next;

// Free memory
delete temp;
}
}

// This function prints contents of


// linked list starting from the
// given node
void printList(Node* node)

25 Data Structures and Algorithms


{
while (node != NULL)
{
cout << node->data << " ";
node = node->next;
}
}

// Driver code
int main()
{

// Start with the empty list


Node* head = NULL;

// Add elements in linked list


push(&head, 7);
push(&head, 1);
push(&head, 3);
push(&head, 2);

cout<<"(Created Linked List: )";


printList(head);

deleteNode(&head, 1);
cout<<"(Linked List after Deletion of 1: )";

printList(head);

return 0;
}

Another example
#include <iostream>

using namespace std;

struct node
{
int data;
node *next;
};

class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}

void add_node(int n)
{
node *tmp = new node;
tmp->data = n;
tmp->next = NULL;

26 Data Structures and Algorithms


if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}

node* gethead()
{
return head;
}

static void display(node *head)


{
if(head == NULL)
{
cout << "NULL" << endl;
}
else
{
cout << head->data << endl;
display(head->next);
}
}

static void concatenate(node *a,node *b)


{
if( a != NULL && b!= NULL )
{
if (a->next == NULL)
a->next = b;
else
concatenate(a->next,b);
}
else
{
cout << "Either a or b is NULL\n";
}
}

void front(int n)
{
node *tmp = new node;
tmp -> data = n;
tmp -> next = head;
head = tmp;
}

void after(node *a, int value)


{
node* p = new node;
p->data = value;
p->next = a->next;
a->next = p;

27 Data Structures and Algorithms


}

void del (node *before_del)


{
node* temp;
temp = before_del->next;
before_del->next = temp->next;
delete temp;
}
};

int main()
{
linked_list a;
a.add_node(1);
a.add_node(2);
a.front(3);
a.add_node(5);
a.add_node(15);
a.after(a.gethead()->next->next->next, 10);
a.del(a.gethead()->next);
linked_list::display(a.gethead());
return 0;
}

7. Exercises:

28 Data Structures and Algorithms


Exercise 2.1:

Write a program to display string using linked list. Take a string of character from user and
split the string in character, and then insert each character into linked list.
Example:
String = “RPI”

head R P I NULL

Exercise 2.2:

Consider a scenario where a firm wants to maintain the data of its employees. The data
containing employee number, name, and salary and department # are saved in a singly linked
list. Create following functions for the employee list.
InsertAtFront: Insertion of a record at the front.
InsertAtEnd: Insertion of a record at the end.
Insert: Insertion of a record at any position in the list
DeleteFirst: Deletion of first record.
DeleteLast: Deletion of last record.
Delete: Deletion of a record at any position in the list.
Search: Searching any record based on employee number and dept no.
Display: Displaying all records.

29 Data Structures and Algorithms


Exercise 2.3:

Write a program to split a single linked list in two separate lists and display the both lists.

8. Web Resources:
http://www.cprogramming.com/tutorial/lesson15.html
http://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/linked%20lists.html
http://www.sourcetricks.com/2008/07/c-singly-linked-lists.html

9. Video Resources:
http://www.youtube.com/watch?v=pBrz9HmjFOs
http://www.youtube.com/watch?v=o5wJkJJpKtM

10. Summary:
This lab session introduces the concepts of single linked lists. It also helps students in
implementing singly linked lists using dynamic allocation.

30 Data Structures and Algorithms


EXPERIMENT 3 – DOUBLY LINKED LISTS
1. Objectives:
(a). Understanding the concepts and operations of doubly linked lists
(b). Implement doubly linked list using dynamic structures
2. Time Required: 3 hrs
3. Software Required:
(a). Windows OS
(b). Microsoft Visual Studio 2012

4. Doubly Linked Lists:A doubly linked list is a data structure consisting of a group of nodes which
together represent a sequence and are connected to each other in both directions (Bi-directional). In
Doubly linked list, each node has two pointers. One pointer to its successor (NULL if there is none)
and one pointer to its predecessor (NULL if there is none) which enables bi-directional traversing.

Head

Syntax for declaring doubly linked list


// Node of a doubly linked list
class Node {
public:
int data;

// Pointer to next node in DLL


Node* next;

// Pointer to previous node in DLL


Node* prev;
};
5. Insertion:To insert data in a doubly linked list, a record is created holding the new item. The next
pointer of the new record is set to link it to the item which is to follow it in the list. The pre-pointer of
the new record is set to link it to the item which is to before it in the list.

31 Data Structures and Algorithms


Insertion in DLL:

A node can be added in four ways:


 At the front of the DLL
 After a given node.
 At the end of the DLL
 Before a given node.

1) Add a node at the front:


The new node is always added before the head of the given Linked List. And newly added
node becomes the new head of DLL. For example, if the given Linked List is 1->0->1-
>5 and we add an item 5 at the front, then the Linked List becomes 5->1->0->1->5.

Let us call the function that adds at the front of the list push(). The push() must receive a
pointer to the head pointer because the push must change the head pointer to point to the new
node
Add a node at the front:
/* Given a reference (pointer to pointer) to the head of a
list and an int, inserts a new node on the front of the list.
*/
void push(Node** head_ref, int new_data)
{
/* 1. allocate node */
Node* new_node = new Node();

/* 2. put in the data */


new_node->data = new_data;

/* 3. Make next of new node as head


and previous as NULL */
new_node->next = (*head_ref);
new_node->prev = NULL;

/* 4. change prev of head node to new node */


if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;

/* 5. move the head to point to the new node */


(*head_ref) = new_node;
}
32 Data Structures and Algorithms
2) Add a node after a given node:
We are given a pointer to a node as prev_node, and the new node is inserted after
the given node.

Add a node after a given node:


/* Given a node as prev_node, insert
a new node after the given node */
void insertAfter(Node* prev_node, int new_data)
{
/*1. check if the given prev_node is NULL */
if (prev_node == NULL) {
cout << "the given previous node cannot be NULL";
return;
}

/* 2. allocate new node */


Node* new_node = new Node();

/* 3. put in the data */


new_node->data = new_data;

/* 4. Make next of new node as next of prev_node */


new_node->next = prev_node->next;

/* 5. Make the next of prev_node as new_node */


prev_node->next = new_node;

/* 6. Make prev_node as previous of new_node */


new_node->prev = prev_node;

/* 7. Change previous of new_node's next node */


if (new_node->next != NULL)
new_node->next->prev = new_node;
}

3) Add a node at the end:


The new node is always added after the last node of the given Linked List. For example, if
the given DLL is 5->1->0->1->5->2 and we add item 30 at the end, then the DLL
becomes 5->1->0->1->5->2->30. Since a Linked List is typically represented by its head of
it, we have to traverse the list till the end and then change the next of last node to the new
node.
33 Data Structures and Algorithms
Add a node at the end:
/* Given a reference (pointer to pointer) to the head
of a DLL and an int, appends a new node at the end */
void append(Node** head_ref, int new_data)
{
/* 1. allocate node */
Node* new_node = new Node();

Node* last = *head_ref; /* used in step 5*/

/* 2. put in the data */


new_node->data = new_data;

/* 3. This new node is going to be the last node, so


make next of it as NULL*/
new_node->next = NULL;

/* 4. If the Linked List is empty, then make the new


node as head */
if (*head_ref == NULL) {
new_node->prev = NULL;
*head_ref = new_node;
return;
}
/* 5. Else traverse till the last node */
while (last->next != NULL)
last = last->next;

/* 6. Change the next of last node */


last->next = new_node;

/* 7. Make last node as previous of new node */


new_node->prev = last;

return;
}

34 Data Structures and Algorithms


Complete program
// A complete working C++ program to
// demonstrate all insertion methods
#include <bits/stdc++.h>
using namespace std;

// A linked list node


class Node {
public:
int data;
Node* next;
Node* prev;
};

/* Given a reference (pointer to pointer)


to the head of a list
and an int, inserts a new node on the front of the list. */
void push(Node** head_ref, int new_data)
{
/* 1. allocate node */
Node* new_node = new Node();

/* 2. put in the data */


new_node->data = new_data;

/* 3. Make next of new node as head


and previous as NULL */
new_node->next = (*head_ref);
new_node->prev = NULL;

/* 4. change prev of head node to new node */


if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;

/* 5. move the head to point to the new node */


(*head_ref) = new_node;
}

/* Given a node as prev_node, insert a new node after the


given node */
void insertAfter(Node* prev_node, int new_data)
{
/*1. check if the given prev_node is NULL */
35 Data Structures and Algorithms
if (prev_node == NULL) {
cout << "the given previous node cannot be NULL";
return;
}

/* 2. allocate new node */


Node* new_node = new Node();

/* 3. put in the data */


new_node->data = new_data;

/* 4. Make next of new node as next of prev_node */


new_node->next = prev_node->next;

/* 5. Make the next of prev_node as new_node */


prev_node->next = new_node;

/* 6. Make prev_node as previous of new_node */


new_node->prev = prev_node;

/* 7. Change previous of new_node's next node */


if (new_node->next != NULL)
new_node->next->prev = new_node;
}

/* Given a reference (pointer to pointer) to the head


of a DLL and an int, appends a new node at the end */
void append(Node** head_ref, int new_data)
{
/* 1. allocate node */
Node* new_node = new Node();

Node* last = *head_ref; /* used in step 5*/

/* 2. put in the data */


new_node->data = new_data;

/* 3. This new node is going to be the last node, so


make next of it as NULL*/
new_node->next = NULL;

/* 4. If the Linked List is empty, then make the new


node as head */
if (*head_ref == NULL) {
new_node->prev = NULL;
*head_ref = new_node;
36 Data Structures and Algorithms
return;
}

/* 5. Else traverse till the last node */


while (last->next != NULL)
last = last->next;

/* 6. Change the next of last node */


last->next = new_node;

/* 7. Make last node as previous of new node */


new_node->prev = last;

return;
}

// This function prints contents of


// linked list starting from the given node
void printList(Node* node)
{
Node* last;
cout << "\nTraversal in forward direction \n";
while (node != NULL) {
cout << " " << node->data << " ";
last = node;
node = node->next;
}

cout << "\nTraversal in reverse direction \n";


while (last != NULL) {
cout << " " << last->data << " ";
last = last->prev;
}
}

// Driver code
int main()
{
/* Start with the empty list */
Node* head = NULL;

// Insert 6. So linked list becomes 6->NULL


append(&head, 6);

// Insert 7 at the beginning. So


// linked list becomes 7->6->NULL
37 Data Structures and Algorithms
push(&head, 7);

// Insert 1 at the beginning. So


// linked list becomes 1->7->6->NULL
push(&head, 1);

// Insert 4 at the end. So linked


// list becomes 1->7->6->4->NULL
append(&head, 4);

// Insert 8, after 7. So linked


// list becomes 1->7->8->6->4->NULL
insertAfter(head->next, 8);

cout << "Created DLL is: ";


printList(head);

return 0;
}
6. Deletion: In deletion process, element can be deleted from three different places. When the node is
deleted, the memory allocated to that node is released and the previous and next nodes of that node
are linked.

Deleting a node
// C++ program to delete a node from
// Doubly Linked List
#include <bits/stdc++.h>
using namespace std;

/* a node of the doubly linked list */


class Node
{
public:
int data;
Node* next;
Node* prev;
};

/* Function to delete a node in a Doubly Linked List.


38 Data Structures and Algorithms
head_ref --> pointer to head node pointer.
del --> pointer to node to be deleted. */
void deleteNode(Node** head_ref, Node* del)
{
/* base case */
if (*head_ref == NULL || del == NULL)
return;

/* If node to be deleted is head node */


if (*head_ref == del)
*head_ref = del->next;

/* Change next only if node to be


deleted is NOT the last node */
if (del->next != NULL)
del->next->prev = del->prev;

/* Change prev only if node to be


deleted is NOT the first node */
if (del->prev != NULL)
del->prev->next = del->next;

/* Finally, free the memory occupied by del*/


free(del);
return;
}

/* UTILITY FUNCTIONS */
/* Function to insert a node at the
beginning of the Doubly Linked List */
void push(Node** head_ref, int new_data)
{
/* allocate node */
Node* new_node = new Node();

/* put in the data */


new_node->data = new_data;

/* since we are adding at the beginning,


prev is always NULL */
new_node->prev = NULL;

/* link the old list off the new node */


new_node->next = (*head_ref);

/* change prev of head node to new node */


if ((*head_ref) != NULL)
(*head_ref)->prev = new_node;
39 Data Structures and Algorithms
/* move the head to point to the new node */
(*head_ref) = new_node;
}

/* Function to print nodes in a given doubly linked list


This function is same as printList() of singly linked list */
void printList(Node* node)
{
while (node != NULL)
{
cout << node->data << " ";
node = node->next;
}
}

/* Driver code*/
int main()
{
/* Start with the empty list */
Node* head = NULL;

/* Let us create the doubly linked list 10<->8<->4<->2 */


push(&head, 2);
push(&head, 4);
push(&head, 8);
push(&head, 10);

cout << "Original Linked list ";


printList(head);

/* delete nodes from the doubly linked list */


deleteNode(&head, head); /*delete first node*/
deleteNode(&head, head->next); /*delete middle node*/
deleteNode(&head, head->next); /*delete last node*/

/* Modified linked list will be NULL<-8->NULL */


cout << "\nModified Linked list ";
printList(head);

return 0;
}

40 Data Structures and Algorithms


Exercises:

Exercise3.1:

Write a menu driven program to perform insertion, deletion and display functions for
doubly linked list.

Exercise 3.2:

Using the Exercise 5.1, write a function MoveToFront( ) with one argument of data type
integer. This function will first search the linked list and compare the Data member of the
node with the given number as argument. If the search finds the number in the list then this
function will move that node to the start of the list as shown in the example below. The order
of the remaining nodes is to remain unchanged. If no node in the list contains the integer,
MoveToFront( ) should leave the list unchanged. Assume that the list contains no duplicate
values. The structure definition of the doubly linked list is

structListNode{
ListNode *pre;
int Data;
ListNode *Next;
}*head;
The function declaration of MoveToFront function is Void MoveToFront(int);

Example:
The two diagrams below illustrate the effect of the call MoveToFront( 5).
Before the call:

41 Data Structures and Algorithms


8. Web References:
http://idlebrains.org/tutorials/data-structures-tutorials/doubly-linked-list-tutorial/
http://www.codeproject.com/Articles/668818/Implementing-a-Doubly-Linked-List-to-be-used-on-an
https://www.geeksforgeeks.org/doubly-linked-list/

9. Video Resource:
http://www.youtube.com/watch?v=5s0x8bc9DvQ
http://www.youtube.com/watch?v=JdQeNxWCguQ

42 Data Structures and Algorithms


EXPERIMENT 4 – CIRCULAR LINKED LISTS

Circular Linked List


Basically, a linked list is a data structure that can store an indefinite amount of items. These items don’t have to be the
same data type. As long as pointers connect these items in a sequential manner, it technically counts as a linked list.

Arrays vs. Linked Lists

Usually, programmers learn about arrays before they learn about linked lists, so it’s useful to compare the two. Although
arrays and linked lists are both data structures for storing multiple values, there are some major differences between the
two. There are pros and cons to using each.

Arra Linked
y Lists
 Physically Contiguous  Logically Contiguous Only
 Fixed Length  Changeable Length
 Access Elements by Index  Access Elements by Traversal
 Insertion/Removal is Costly  Insertion/Removal is Efficient

Memory Allocation

Linked list is one of the fundamental data structures, and can be used to implement other data structures. In a linked list
there are different numbers of nodes. Each node is consists of two fields. The first field holds the value or data and the
second field holds the reference to the next node or null if the linked list is empty.

Unlike a linked list, an array is both physically and logically contiguous. A good way to think about an array is to imagine
a single chunk of memory cells. The elements of an array are actually located next to each other as consecutive memory
addresses in RAM (Random Access Memory).

43 Data Structures and Algorithms


The elements of a linked list, by contrast, are logically contiguous in their implementation, but not physically contiguous
in memory. A linked list doesn’t occupy a single block of memory, allowing it to use whatever memory “scraps” are
available. Because of this flexibility, node elements can be different sizes as well as different data types.

Accessing Elements

One advantage an array has over a linked list is indexing. Instead of having to traverse down every element in the array,
you can access an element directly by its index number. This costs only one instruction cycle. To get the fifth element of
an array, you only need to perform one lookup operation. The same operation in a linked list would cost you five
instruction cycles since you have to “inchworm” your way down the list.

In technical terms, retrieving an element by its index number in an array is always an O(1) operation. By contrast, the
same logically-equivalent operation in a linked list would take a variable amount of runtime depending on the number of
elements preceding the one you’re trying to access. Thus, retrieving a particular element in a linked list would be an O(n)
operation at worst and an O(1) operation at best (if the sought-after element happens to be at the front of the list).

Inserting/Removing Elements

One advantage a linked list has over an array is the ease of inserting and removing elements. In order to insert an element
into the middle of an array, you have to shift each element over to make space for insertion. This can be quite costly. In a
linked list, however all you need to do is reassign the pointer of one node to make it point to the new element and have
that new element point to the next logical node in the sequence.

44 Data Structures and Algorithms


Linked List Nodes

The elements of a linked list are usually referred to as “nodes.” A C++ linked list is composed of node structs, each with a
data component and a pointer to other nodes in the list. The data attributes of the node in this example store a song name
and an artist name. The next pointer refers to the next song in the playlist.

Length:

Perhaps the most obvious difference between a linked list and an array is the fact that an array is a fixed length while a
linked list can expand or shrink during runtime. Memory slots can be added or removed from a linked list as needed. In an
array, however, you are stuck with an inflexible chunk of memory cells for the array’s lifetime. Even a dynamic array
(one that is assigned a length during runtime) is incapable of changing length once it’s created.

The pointer holds the address of the next element, not the address of the data in the next element, even though they are the
same in value sometimes. And It should be set to NULL while acting as the last node of the list.

Lab Task: Implement singly circular link list?

45 Data Structures and Algorithms


EXPERIMENT 5 – STACKS

1. Objectives:
(a). Understand the concept of stacks and their uses
(b). Implement stacks using both static and dynamic implementation
2. Time Required: 3 hrs
3. Software Required:
(a). Windows OS
(b). Microsoft Visual Studio

4. Stack:
Stack is a memory portion, which is used for storing the elements. The elements are stored based
on the principle of LIFO (Last In, First Out). In stack insertion and deletion of elements take place
at the same end (Top). The last element inserted will be the first to be retrieved.
• This end is called Top
• The other end is called Bottom

Data4 Top

Data3

Data2

Data1 Bottom

5. Top:The stack top operation gets the data from the top-most position and returns it to the user
without deleting it. The underflow state can also occur in stack top operation if stack is empty.

6. Push:The push operation adds a new element to the top of the stack, or initializes the stack if it is
empty. If the stack is full and does not contain enough space to accept the given item, the stack is
then considered to be in an overflow state.
7. Pop:The pop operation removes an item from the top of the stack. A pop either returns previously
inserted items, or NULL if stack is empty.

8. Overflow:When stack contains equal number of elements as per its capacity and no more
elements can be added, the status of stack is known as overflow

46 Data Structures and Algorithms


9. Dynamic Stack Implementation:

a) Stack Class definition: This class contains private data members i.e. a structure of node
describes the type data to be stored in element and a top pointer to node.

class ListStack{
private:
struct node
{
int num;
node *next;
}*top;
public:
ListStack()
{
top=NULL;
}
void push();
void pop();
void display();
};

b) Push( ) function:This function creates a new node and ask the user to enter the data to be
saved on the newly created node.

void ListStack::push()
{
node *newNode;
newNode= new node;
cout<<“Enter number to add on stack";
cin>>newNode->num;
newNode->next=top;
top=newNode;
}

47 Data Structures and Algorithms


c) Pop ( ) function: This function deletes an element from top of stack.

void ListStack::pop()
{
node *temp;
temp=top;
if(top==NULL)
cout<<"Stack UnderFlow"<<endl;
else
{
cout<<"deleted Number from the stack =";
cout<<top->num;
top=top->next;
delete temp;
}
}

d) Main( ) function:

void main() switch(choice){


{ case 1:
clrscr(); LS.push();
ListStack LS; break;
int choice; case 2:
do{ LS.pop();
cout<<"Menu "<<endl; break;
cout<<"1.Push" <<endl; case 3:
cout<<"2.Pop"<<endl; LS.display();
cout<<"3.Show"<<endl; break;
cout<<"4.EXIT"<<endl; }
cin>>choice; }while(choice!=4);
}

48 Data Structures and Algorithms


10. Exercises:
Exercise 5.1: Display ( ) Function test in main function

Write this function to display the elements of stack e.g.


Void ListStack::display()

Exercise 5.2: Implement using static stacks.


Write a program using stack operations, which accepts a non-negative base 10 integer
as a parameter, and display binary representation of number.

Description: To convert a number from decimal to binary, you simply divide by two and
push reminder to stack until quotient is reached to zero, then use pop operation to
display the binary representation of number. For example, to convert (35) 10 to binary,
you perform the following computation.

35/2 = 1

17/2 = 1

8/2 = 0

4/2 = 0

2/2 = 0

If you examine the remainders from the last division to the first one, writing them down
as you go, you will get the following sequence: 100011. i.e. (100011)2=(35)10

49 Data Structures and Algorithms


Exercise 5.3:

Write a program to compare opening and closing brackets in expression. This program
takes an expression in the form of string and scan it character by character. Finally the
output of the program is the valid or invalid expression.

Algorithm: To do this comparison a stack ADT can be used to keep track of the scope
delimiters encountered while scanning the expression.

• Whenever a scope “opener” is encountered, it can be “pushed” onto a stack


• Whenever a scope “ender” is encountered, the stack is examined:
– If the stack is “empty”, there is no matching scope “opener” and the
expression is invalid.
– If the stack is not empty, we pop the stack and check if the “popped” item
corresponds to the scope ender
– If match occurs, we continue scanning the expression
• When end of the expression string is reached, the stack must be empty, otherwise
one or more opened scopes have not been closed and the expression is invalid

11. Web Resources:


http://www.cs.utsa.edu/~wagner/CS2213/stack/stack.html
http://scanftree.com/Data_Structure/DynamicStack
https://www.cs.bu.edu/teaching/c/stack/array/

12. Video Resources:


http://www.youtube.com/watch?v=sFVxsglODoo
http://www.youtube.com/watch?v=FNZ5o9S9prU

13. Summary:
This lab introduces the concepts of stacks. This lab is designed to implement the concepts of
stacks using both static and dynamic implementation.

50 Data Structures and Algorithms


EXPERIMENT 6– APPLICATIONS OF STACK

Objectives:
(c). Understand the applications of stacks
(d). Implement stacks using both static and dynamic implementation
Time Required: 3 hrs

Software Required:
(c). Windows OS
(d). Microsoft Visual Studio
4. Infix to Postfix:
An algorithm for parsing an infix notation without parentheses is given here.
Algorithm:
1. Create an empty stack called opstack for keeping operators. Create an empty string for output.
2. Each character in string is a token.
3. Scan the token list from left to right.
o If the token is an operand, append it to the end of the output string.
o If the token is a left parenthesis, push it on the opstack.
o If the token is a right parenthesis, pop the opstack until the corresponding left parenthesis is
removed. Append each operator to the end of the output string.
o If the token is an operator, *, /, +, or -, push it on the opstack. However, first remove any
operators already on the opstack that have higher or equal precedence and append them to the
output list.
4. When the input expression has been completely processed, check the opstack. Any operators still on the
stack can be removed and appended to the end of the output string.

51 Data Structures and Algorithms


Exercise 6.1:

In this Exercise, you have to take a string expression as input from user. Using this infix
expression, you have to convert it into its equivalent postfix notation.
Example: a + ( b * c )
Read an Expression Stack Output

a a

+ + a

( +( a

b +( ab

* +(* ab

c +(* abc

) + abc*

abc*+

#include<iostream>
#include<stack>
using namespace std;

bool isOperator(char c)
{
if(c=='+'||c=='-'||c=='*'||c=='/'||c=='^')
{
return true;
}
else
{
return false;
}
}

int precedence(char c)
{
if(c == '^')
return 3; //highest
else if(c == '*' || c == '/')
return 2; //lower
else if(c == '+' || c == '-')
return 1; //lowest
else

52 Data Structures and Algorithms


return -1;
}

string InfixToPostfix(stack<char> s, string infix)


{
string postfix;
for(int i=0;i<infix.length();i++)
{
if((infix[i] >= 'a' && infix[i] <= 'z')
||(infix[i] >= 'A' && infix[i] <= 'Z'))
{
postfix+=infix[i];
}
else if(infix[i] == '(')
{
s.push(infix[i]);
}
else if(infix[i] == ')')
{
while((s.top()!='(') && (!s.empty()))
{
char temp=s.top();
postfix+=temp;
s.pop();
}
if(s.top()=='(')
{
s.pop();
}
}
else if(isOperator(infix[i]))
{
if(s.empty())
{
s.push(infix[i]);
}
else
{
if(precedence(infix[i])>precedence(s.top()))
{
s.push(infix[i]);
}
else
if((precedence(infix[i])==precedence(s.top()))&&(infix[i]=='^'))
{
s.push(infix[i]);
}
else
{
while((!
53 Data Structures and Algorithms
s.empty())&&( precedence(infix[i])<=precedence(s.top())))
{
postfix+=s.top();
s.pop();
}
s.push(infix[i]);
}
}
}
}
while(!s.empty())
{
postfix+=s.top();
s.pop();
}

return postfix;
}

int main()
{

string infix_exp, postfix_exp;


cout<<"Enter a Infix Expression :"<<endl;
cin>>infix_exp;
stack <char> stack;
cout<<"INFIX EXPRESSION: "<<infix_exp<<endl;
postfix_exp = InfixToPostfix(stack, infix_exp);
cout<<endl<<"POSTFIX EXPRESSION: "<<postfix_exp;

return 0;
}

5. Parsing Infix Notation: An algorithm for parsing an infix notation without parentheses is given here.

Two stacks are required, one for numbers and the other for operators. The algorithm is:
 For each item in the infix expression (no parentheses) from the right to the left
o If the item is a number then push it on the number stack.
o If the item is an operator (+,-,*, or /) and: the operator stack is empty or the operator on
the top of the stack is higher in priority (* and / are higher in priority than + or -), then
 Pop an operator from the operator stack.
 Pop two numbers off the number stack.
 Calculate using second number-operator-first number.
 Push the result on the number stack.
 Push the item on the operator stack.
o Else push the item on the operator stack.
 After the loop, while the operator stack is not empty
o Pop an operator from the operator stack.

54 Data Structures and Algorithms


o Pop two numbers off the number stack.
o Calculate using second number-operator-first number.
o Push the result on the number stack.
The answer is the last item in the number stack.

Exercise 6.2:

Write a C++ code to evaluate the infix expression without parenthesis given by user.
Example: 3+4-5/2
Infix String Operand Stack Operator Stack Value
3 3
+ 3 +
4 34 +
- 34 +-
5 345 +-
/ 345 +-/
2 3452 +-/
34 +- / 2 5 -> 5/2 , Push 2
342 +-
3 + - 2 4 -> 4-2, Push 2
32 +
5 + 2 3 -> 3+2, Push 5

11. Web Resources:


http://jcsites.juniata.edu/faculty/kruse/cs240/stackapps.html
http://scanftree.com/Data_Structure/Application-of-stack

12. Video Resources:


http://www.youtube.com/watch?v=x_B_mH5BpiE
http://www.youtube.com/watch?v=iWnPbPUfhCg

13. Summary:
This lab introduces different real world applications of stacks and their implementation using
static stacks in C++.

55 Data Structures and Algorithms


EXPERIMENT 7 – QUEUES
1. Objectives:
(a). To understand and implement the concepts of queues using data structures
(b). To learn priority queue and its implementation
2. Time Required: 3 hrs
3. Software Required:
(a). Microsoft Windows
(b). Microsoft Visual Studio 2012

4. Queue:
A queue is a particular kind of collection in which the entities in the collection are kept in order
and the principal (or only) operations on the collection are the addition of entities to the rear
terminal position and removal of entities from the front terminal position. This makes the queue a
First-In-First-Out (FIFO) data structure. In a FIFO data structure, the first element added to the
queue will be the first one to be removed. This is equivalent to the requirement that once an
element is added, all elements that were added before have to be removed before the new element
can be invoked. A queue is an example of a linear data structure.

Static: Queue is implemented by an array, and size of queue remains fix

Dynamic: A queue can be implemented as a linked list, and expand or shrink with each enqueue
or dequeue operation.
Front Back

Data1 Data2 Data3 Data4

5. Enqueue:TheEnqueue ( ) operation adds a new item to the end of the queue, or initializes the
queue if it is empty.

6. Dequeue:TheDequeue ( ) operation removes an item from the front of the queue. A Dequeue
operation on an empty stack results in an underflow.

56 Data Structures and Algorithms


7. Dynamic Queue Implementation:
a) Queue Class definition:

class DynQueue{
private:
structqueueNode
{
intnum;
queueNode *next;
};
queueNode *front;
queueNode *rear;
public:
DynQueue();
~DynQueue();
void enqueue();
void dequeue();
bool isEmpty();
void displayQueue();
void makeNull();
};

b) Constructor:

DynQueue::DynQueue()
{
front = NULL;
rear = NULL;
}

c) Enqueue() function:

void DynQueue::enqueue()
{
queueNode *ptr;
ptr = new queueNode;
cout<<"Enter Data";
cin>>ptr->num;
ptr->next= NULL;
if (front == NULL)
{
front = ptr;
rear = front;

57 Data Structures and Algorithms


}
else
{
rear->next=ptr;
rear = ptr;
}
}

d) Dequeue( ) Function:

void DynQueue::dequeue()
{
queueNode *temp;
temp = front;
if(isEmpty())
cout<<"Queue is Empty";
else
{
cout<<"data deleted="<<temp->num;
front = front->next;
delete temp;
}
}

8. Exercises:

Exercise 7.1:

Write a menu driven program to perform different operations with queue such aEnqueue
( ),

Dequeue( ) and DisplayQueue( ).

58 Data Structures and Algorithms


Exercise 7.2:

In this Exercise, you have to take a single string as input. Using this input string, you
have to create multiple queues in which each queue will comprise of separate word
appeared in input string. At the end, you will again concatenate all queues to a single
queue.

Example:

String = “Data Structure and Algo”


Q1 = D → a → t → a
Q2 = S → t → r → u → c → t → u → r → e
Q3 = a → n → d
Q4 = A → l → g → o
At the end concatenate all queues and display them.
Q1 → Q2 → Q3 → Q4

Exercise 7.3:

Write a program to demonstrate a printer queue in which jobs for printing are added on
the basis of priority. Each printing job should have name (e.g. A, B, C, D …..) and
priority value (e.g. 1=High, 2=Medium, 3=Low). If two jobs has same priority then
FIFO rule should be applied.

fron A B A C rear
t

1 2 2 3

59 Data Structures and Algorithms


9. Web Resources:
http://www.cprogramming.com/tutorial/computersciencetheory/queue.html
http://www.sourcetricks.com/2008/07/c-queues.html#.VA66h8KSxcw
http://www.cppforschool.com/tutorial/dynamic-queue.html

10. Video Resources:


http://www.youtube.com/watch?v=zQZMc8FXPYY
www.youtube.com/watch?v=dpg-ULnNnnE

11. Summary:
This lab session introduces the concepts of queues. This lab helps students in implementing
queues using dynamic allocation.

60 Data Structures and Algorithms


EXPERIMENT 8 – RECURSION
1. Objectives:
(a). Understanding the concepts of recursion and its practical usage
(b). Implementation of recursion
2. Time Required: 3 hrs
3. Software Required:
(a). Windows
(b). Microsoft Visual Studio 2012
4. Recursion: Recursion is a programming technique in which procedures and functions call
themselves. When a function calls itself, it is making a recursive call. This approach can be applied
to solve many types of problems. Most computer programming languages support recursion by
allowing a function to call itself within the program.

5. Recursive Call:A function call in which the function being called is the same as the one making the
call.

6. Base Case:

 The case for which the solution can be stated non-recursively


 The case for which the answer is explicitly known.

7. Recursive Case: A recursive function definition also contains one or more recursive cases; meaning
input(s) for which the program recurs (calls itself).
The job of the recursive cases can be seen as breaking down complex inputs into simpler ones. In a
properly-designed recursive function, with each recursive call, the input problem must be simplified
in such a way that eventually the base case must be reached.
For example, the factorial function can be defined recursively by the equations 0! = 1 and, for all n
> 0, n! = n (n − 1)! None of equation by itself constitutes a complete definition, the first is the base
case, and the second is the recursive case.

61 Data Structures and Algorithms


Advantages of C++ Recursion
 It makes our code shorter and cleaner.
 Recursion is required in problems concerning data structures and advanced algorithms, such
as Graph and Tree Traversal.

Disadvantages of C++ Recursion


 It takes a lot of stack space compared to an iterative program.
 It uses more processor time.
 It can be more difficult to debug compared to an equivalent iterative program.

8. Tower of Hanoi: Tower of Hanoi is a mathematical puzzle invented by a French


Mathematician Edouard Lucas in 1883. A tower of Hanoi is based on Recursion.
Suppose we are given with some towers, and that on one tower we have already placed
some rings. The rings are placed according to the descending order of magnitude. The
problem is to; place all these rings on another tower, such that the rings are kept in the
order, even now.

9. Algorithm: In this problem, there are pegs say A, B and C. There are n discs on peg A of
different diameters and are placed one above the other such that always a smaller disc is placed
above the larger disc. The two pegs B and C are empty. All the discs from peg A are to be
transferred to peg C using peg B as temporary storage. The subsequent guidelines must be
adhered while transferring the discs:

• Only one disc is moved at a time.

• Smaller disc is on top of the larger disc at any time.

• A disc can be moved from one peg to another.

If there is only one disc, move that disc from A to C. If there are two discs, move the first disc
from A to B, move the second from A to C, then move the disc from B to C. In general, to
move n discs from A to C, the recursive technique consists of three steps:

• Move n-1 discs from A to B.

• Move nth from A to C.

• Move n-1 discs from B to C.

10. Pseudo code:


MoveDisc(whichDisc, frompeg, topeg)
{
Cout<<"Move ring"+ whichDisc+"frompeg"+frompeg+"topeg"+topeg);
}
MoveTower( height, frompeg, topeg, usingpeg)
{
MoveTower( height-1, frompeg,usingpeg, topeg);
MoveDisc( height, frompeg, topeg);

62 Data Structures and Algorithms


MoveTower( height-1, usingpeg, topeg,frompeg);}

11. Exercises:

63 Data Structures and Algorithms


Exercise 8.1:
Write a function to calculate triangular number using recursion.
Int trinum(int x);
trinum(4)=10 i.e. 4+3+2+1+0=10

Exercise 8.2:

Create a recursive function for Fibonacci series and a program for calculating it. In
mathematics, the Fibonacci numbers are the numbers in the following integer sequence:
0, 1, 1, 2, 3, 5, 8, 13, 21
By definition, the first two Fibonacci numbers are 0 and 1, and each subsequent number is the
sum of the previous two. In mathematical terms, the sequence Fn of Fibonacci numbers is
defined by the recurrence relation F(n) = F(n-1) + F(n-2) with seed values F(0) = 0 and F(1) =
1
Exercise 8.3:
Write a recursive function to display the data members of linked List in reverse order.

Exercise 8.4:
Write a program to reverse a number.

Exercise 8.5:
Write a recursive function to implement the algorithm of tower of Hanoi.

9. Web References:
http://www.cplusplus.com/articles/D2N36Up4/
http://www.danzig.us/cpp/recursion.html
64 Data Structures and Algorithms
http://www.learncpp.com/cpp-tutorial/710-recursion/
http://en.wikipedia.org/wiki/Tower_of_Hanoi
http://www.dsalgo.com/2013/02/towers-of-hanoi.html

10. Video Link:


www.youtube.com/watch?v=R-SraYQDL8M
www.youtube.com/watch?v=NvVYd08NUXI
www.youtube.com/watch?v=DjLCaQVt_Xk
www.youtube.com/watch?v=5QuiCcZKyYU
www.youtube.com/watch?v=5_6nsViVM00

11. Summary:
This lab introduces students with the concepts of recursion. It allows them to understand the
implementation of recursion with practical resolution of a well-known problem using concepts of
Data Structure and Algorithms.

65 Data Structures and Algorithms


.

EXPERIMENT 9 – SORTING-I
1. Objectives:
(a). Learning different sorting algorithms
(b). Implementation of selection, insertion, bubble and merge sort.
2. Time Required: 3 hrs
3. Software Required:
(a). C++
(b). Windows
(c). Microsoft Visual Studio 2012
4. Sorting: Sorting is the process of arranging values in any particular order. The order can be
ascending or descending.
5. Selection sort: is a sorting algorithm which works as follows:
 Find the minimum value in the list
 Swap it with the value in the first position
 Repeat the steps above for remainder of the list (starting at the second position)

Pseudo code:

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

Put the next smallest element in location data[i]

6. Insertion Sort:This algorithm takes one value at a time and builds up another sorted list of values.
It helps if you can imagine what you do when you play a game of cards: you pick a card and insert
it to an already sorted list of cards.

Pseudo code:

insertionSort(array A)
{This procedure sorts in ascending order.}
begin
for i := 1 to length(A)-1 do
begin
value := A[i];
j := i - 1;
done := false;
repeat
{ To sort in descending order simply reverse
the operator i.e. A[j] < value }
if A[j] > value then
begin
A[j + 1] := A[j];
j := j - 1;
if j < 0 then
done := true;
66 Data Structures and Algorithms
end
else
done := true;
until done;
A[j + 1] := value;
end;
end;
###############################
Step 1: Repeat Steps 2 to 5 for K = 1 to N-1
Step 2: set temp = A[K]
Step 3: set J = K – 1
Step 4: Repeat while temp <=A[J]
set A[J + 1] = A[J]
set J = J – 1
[end of inner loop]
Step 5: set A[J + 1] = temp
[end of loop]
Step 6: exit

67 Data Structures and Algorithms


Exercises:

Exercise 9.1:

Write a program to sort a given array by using the insertion sort.

Exercise 9.2:

Write a program to sort a given array by using the selection sort.

68 Data Structures and Algorithms


EXPERIMENT 10 – SORTING-II

Objectives:
(a). Learning different sorting algorithms
(b). Implementation of selection, insertion, bubble and merge sort.
Time Required: 3 hrs
Software Required:
(a). C++
(b). Windows
(c). Microsoft Visual Studio 2012

Bubble Sort: This algorithm looks at pairs of entries in the array and swaps their order if needed.
After the first step of the algorithm the maximal value will "bubble" up the list and will occupy
the last entry. After the second iteration, the second largest value will "bubble" up the list and will
occupy the next to last entry, and so on.

69 Data Structures and Algorithms


Pseudo code:

for (i=n-1; i>=0; i--)


for (j=0; j<i; j++)
if (data[j] > data[j+1])
swap(data[j], data[j+1])

Merge Sort:This recursive algorithm belongs to


the very important divide-and-conquer
paradigm. It consists of the following steps:
 Divide-the elements to be sorted into two
groups of equal (or almost equal) size.
 Conquer - Sort each of these smaller
groups of elements (by recursive calls).
 Merge - Combine the two sorted groups
into one large sorted list.

Pseudo code:

70 Data Structures and Algorithms


funcmergesort( var a as array )
if ( n == 1 ) return a

var l1 as array = a[0] ... a[n/2]


var l2 as array = a[n/2+1] ... a[n]

l1 = mergesort( l1 )
l2 = mergesort( l2 )

return merge( l1, l2 )


end func

func merge( var a as array, var b as array )


var c as array

while ( a and b have elements )


if ( a[0] > b[0] )
add b[0] to the end of c
remove b[0] from b
else
add a[0] to the end of c
remove a[0] from a
while ( a has elements )
add a[0] to the end of c
remove a[0] from a
while ( b has elements )
add b[0] to the end of c
remove b[0] from b
return c
end func

9. Exercises:

71 Data Structures and Algorithms


Exercise 10.1:

Write a program to sort a given array by using the bubble sort.

Exercise 10.2 :

Write a program to sort a given array by using the merge sort.

10. Web Resources:


https://www.cs.auckland.ac.nz/software/AlgAnim/sorting.html
http://www.cprogramming.com/algorithms-and-data-structures.html
http://www.studytonight.com/data-structures/introduction-to-sorting

11. Video Resources:


www.youtube.com/watch?v=P00xJgWzz2c
http://video.mit.edu/watch/blossoms-sorting-algorithms-10260/

12. Summary:
This lab introduces students with the concepts of sorting. It also helps them in implementing
different sorting algorithms such as bubble, merge, insertion and selection sort.

72 Data Structures and Algorithms


EXPERIMENT 11 – SEARCHING
1. Objectives:
(a). Understand different searching Algorithms
(b). Implement sequential search and binary search.
2. Time Required: 3 hrs
3. Software Required:
(a). C++
(b). Windows
4. Searching:Searching is the process of finding a particular data in the collection.
5. Sequential search:It is a list or array begins at the beginning of the list or array and continues
until the item is found or the entire list or array has been searched.

Pseudocode:
LINEAR(DATA,N, ITEM,LOC)
Set DATA[N+1] = ITEM
Set LOC = 1
Repeat while DATA[LOC] !=ITEM
Set LOC = LOC +1
If LOC = N+1, then Set LOC =0
Exit.

6. Binary search:It looks for an item in a list using a divide-and-conquer strategy.


 Binary search algorithm assumes that the items in the array being searched are sorted
 The algorithm begins at the middle of the array in a binary search
 If the item for which we are searching is less than the item in the middle, we know that the
item won’t be in the second half of the array
 Once again we examine the “middle” element
 The process continues with each comparison cutting in half the portion of the array where the
item might be

Pseudo code:
BINARY(DATA,LB,UB,ITEM,LOC)

Set BEG=LB, END=UB, and MID= INT((BEG+END)/2)


Repeat Steps 3 and 4 while BEG<=END and DATA[MID]!=ITEM
if ITEM<DATA[MID] then
set END=MID – 1
else
set BEG = MID +1
Set MID = = INT((BEG+END)/2)
if DATA[MID]=ITEM, then
set LOC = MID
else
set LOC = NULL
Exit.

73 Data Structures and Algorithms


7. Exercises:

Exercise 11.1:

Create function for each algorithm using Array:


 Linear search
 Binary search
Input list of numbers: 6 13 14 25 33 43 51 53 64 72 84 93 95 96 97

Exercise 11.2:

Write a program to search an element linearly from the entered numbers. Also, indicate its
position in case the element is found or unavailability.

Exercise 11.3:

Write a program to demonstrate binary search. Use character array and store 10 names. This
program prompts the user to enter ten names. They are stored in ascending order the name[15]
[10] the fn[15] is used to store the name which we want to search.

74 Data Structures and Algorithms


8. Web Resources:
http://algorithms.openmymind.net/search/linear.html
http://www.csit.parkland.edu/~mbrandyberry/CS1Java/Lessons/Lesson27/BinarySearch.htm

9. Video Links:
www.youtube.com/watch?v=vohuRrwbTT4
http://tune.pk/video/2451896/binary-search-tree-implementation-in-cc

10. Summary:
This lab introduces students with the search algorithms. It helps students in implementing binary
search and linear search algorithms.

75 Data Structures and Algorithms


EXPERIMENT 12 – BINARY SEARCH TREE
1. Objectives:
(a). Understand concepts and usages of binary search tree
(b). Practice the implementation of binary search tree
2. Time Required: 3 hrs
3. Software Required:
(a). C++
(b). Windows
4. Binary Search Trees: Stores keys in the nodes in a way so that searching, insertion and deletion
can be done efficiently. Binary search tree is either empty or each node N of tree satisfies the
following property
 The Key value in the left child is not more than the value of root
 The key value in the right child is more than or identical to the value of root
 All the sub-trees, i.e. left and right sub-trees follow the two rules mention above.

76 Data Structures and Algorithms


Advantages of Binary search tree
 Searching an element in the Binary search tree is easy as we always have a hint that which
subtree has the desired element.
 As compared to array and linked lists, insertion and deletion operations are faster in BST.

Minimum: The minimum element of a binary search tree is the last node of the left roof

Maximum: The maximum element is the last node of the right roof.
Basic Operations:
 Search
 Insert
 Delete
 Traverse
Search:
Search(key)

Begin

If(root == null || root->data == key)


Return root;
If(root->key < key)
Search(root->left,key)
Else if (root->key >key )
Search(root->right,key);

end

77 Data Structures and Algorithms


Insert:
insert (element, root)
Node x = root
Node y = NULL
while x:
y = x
if x.value < element.value
x = x.right
else
x = x.left
if y.value < element
y.right = element
else
y.left = element

Delete:
Deleting a node from Binary search tree includes following three cases

Deleting a node from Binary search tree includes following three cases...
 Case 1: Deleting a Leaf node (A node with no children)
 Case 2: Deleting a node with one child
 Case 3: Deleting a node with two children
Case 1: Deleting a leaf node
 Step 1 - Find the node to be deleted using search operation
 Step 2 - Delete the node using free function (If it is a leaf) and terminate the function.

78 Data Structures and Algorithms


Case 2: Deleting a node with one child
 Step 1 - Find the node to be deleted using search operation
 Step 2 - If it has only one child then create a link between its parent node and child node.
 Step 3 - Delete the node using free function and terminate the function.

Case 3: Deleting a node with two children


 Step 1 - Find the node to be deleted using search operation
 Step 2 - If it has two children, then find the largest node in its left subtree (OR)
the smallest node in its right subtree.
 Step 3 - Swap both deleting node and node which is found in the above step.
 Step 4 - Then check whether deleting node came to case 1 or case 2 or else go to step 2
 Step 5 - If it comes to case 1, then delete using case 1 logic.
 Step 6- If it comes to case 2, then delete using case 2 logic.
 Step 7 - Repeat the same process until the node is deleted from the tree.

79 Data Structures and Algorithms


delete (value, root):
Node x = root
Node y = NULL
# searching the node
while x:
y = x
if x.value < value
x = x.right
else if x.value > value
x = x.left
else if value == x
break
# if the node is not null, then replace it with successor
if y.left or y.right:
newNode = GetInOrderSuccessor(y)
root.value = newNode.value
# After copying the value of successor to the root #we're deleting the
successor
free(newNode)
else
free(y)
Traversals in binary tree:
There are three types of traversals in binary tree:
 Inorder traversal :
 Traverse the left subtree, i.e., call Inorder(left->subtree)
 Visit the root.
 Traverse the right subtree, i.e., call Inorder(right->subtree)

void inorder(Node* root){


if(root == NULL)
return;

//First recur on left subtree


inorder(root->left);
//Then read the data of child
cout << root->data << " ";
// Recur on the right subtree
inorder(root->right);
}

 Preorder traversal: In this traversal, we first visit the node, then traverse the right subtree
completely and then the left subtree.
 Visit the root.
 Traverse the left subtree, i.e., call Preorder(left->subtree)
 Traverse the right subtree, i.e., call Preorder(right->subtree)

80 Data Structures and Algorithms


void preorder(Node* root){
if(root == NULL)
return;

//First read the data of child


cout << root->data << " ";
//Then recur on left subtree
preorder(root->left);
//Then Recur on the right subtree
preorder(root->right);
}

 Postorder traversal: In this traversal, we first traverse the left subtree then the right
subtree and in the end visit the node.
 Traverse the left subtree, i.e., call Postorder(left->subtree)
 Traverse the right subtree, i.e., call Postorder(right->subtree)
 Visit the root

void postorder(Node* root){


if(root == NULL)
return;

//Then recur on left subtree


postorder(root->left);
//Then Recur on the right subtree
postorder(root->right);
//First read the data of child
cout << root->data << " ";
}

81 Data Structures and Algorithms


7. Exercises:

Exercise 12.1:
Write a menu driven program for inserting and deleting an element of binary search tree.

Exercise 12.2:
Write a menu-driven program to traverse the binary search tree by using the following:
 Preorder traversals
 Inorder traversals
 Postorder traversals

8. Web References:
http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/binarySearchTree.htm
https://www.cs.auckland.ac.nz/~jmor159/PLDS210/niemann/s_bin.htm
http://www.sanfoundry.com/cpp-program-implement-binary-tree-2/

9. Video References:
www.youtube.com/watch?v=COZK7NATh4k
www.youtube.com/watch?v=5vwVuLMzqxQ

10. Summary:
This lab introduces students with the concepts of Binary search tree, its practical usages and its
implementation.

82 Data Structures and Algorithms


EXPERIMENT 13 – GRAPHS
1. Objectives:
(a). Understand the concepts if graphs
(b). Implementation of graphs
2. Time Required: 3 hrs
3. Software Required:
(a). C++
(b). Windows
4. Graph:
Graph is a data structure that consists of a
set of nodes (vertices) and a set of edges
that relate the nodes to each other. The set
of edges describes relationships among the
vertices.
A graph G is defined as follows:
G = (V,E)
V(G): a finite, nonempty set of vertices
E(G): a set of edges (pairs of vertices)

5. Graph Traversing:Traversing a graph consists of visiting each vertex only one time. We can
traverse the graph by two ways:
 Depth first search
 Breadth first search

6. Breadth First Search: Breadth-first search (BFS) is a graph search algorithm that begins at the root
node and explores all the neighbouring nodes. Then for each of those nearest nodes, it explores their
unexplored neighbour nodes, and so on, until it finds the goal.

The breadth-first search (BFS) algorithm is used to search a tree or graph data structure for a
node that meets a set of criteria. It starts at the tree’s root or graph and searches/visits all
nodes at the current depth level before moving on to the nodes at the next depth level.
Breadth-first search can be used to solve many problems in graph theory.

Pseudo code:

Input: A graph G and a root v of G

----------------------------------------------------------------------------------------------------------------

procedure BFS(Graph,v):
create a queue Q
enqueue v onto Q
mark v
while Q is not empty:
t ← Q.dequeue()
for all edges e in G.incidentEdges(t) do
o ← G.opposite(t,e)
83 Data Structures and Algorithms
if o is not marked:
mark o
enqueue o onto Q

#include <iostream>
#include
using namespace std;
struct Node {
int data;
struct Node *left, *right;
};
Node* newNode(int data) {
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
int main() {
Node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
cout << "Level Order traversal of binary tree is
";
queue<Node *> q;
q.push(root);
while (q.empty() == false) {
Node *node = q.front();
cout << node->data << " ";
q.pop();
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
}
return 0;
}

7. Depth First Search: Depth-first search (DFS) is an algorithm for traversing or searching a tree,
tree structure, or graph. One starts at the root (selecting some node as the root in the graph case) and
explores as far as possible along each branch before backtracking.
#include <iostream>
using namespace std;

84 Data Structures and Algorithms


struct Node {
int data;
struct Node* left, *right;
Node(int data) {
this->data = data;
left = right = NULL;
}
};
void printPostorder(struct Node* node) {
if (node == NULL)
return;
printPostorder(node->left);
printPostorder(node->right);
cout << node->data << " ";
}
void printInorder(struct Node* node) {
if (node == NULL)
return;
printInorder(node->left);
cout << node->data << " ";
printInorder(node->right);
}
void printPreorder(struct Node* node) {
if (node == NULL)
return;
cout << node->data << " ";
printPreorder(node->left);
printPreorder(node->right);
}
int main() {
struct Node *root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
cout << "
Preorder traversal of binary tree is
";
printPreorder(root);
cout << "
Inorder traversal of binary tree is
";
printInorder(root);
cout << "

85 Data Structures and Algorithms


Postorder traversal of binary tree is
";
printPostorder(root);
return 0;
}

8. Exercises:

Exercise 13.1:
Create the following class Graph. Implement all function listed in class and test using menu
driven program.

class Graph

{
private:
structGNode
{
int data;
GNode *ptr;
bool visited;
};
GNode *GList;
public:
graph();
void Create();
voidInsertVertex(int);
voidInsertEdge();
voidDisplayVertices();
voidDeleteVertex();
voidDeleteEdges();
boolSearchVertex();
boolSearchEdge();
voidBFSTraversal();
voidDFSTraversal();

};

86 Data Structures and Algorithms


Exercise 13.2:

Write a function called DelAllMinEdges( ). This function will first search all the edges in the
graph and will delete all those edges having minimum weight. Consider that graph is
implemented using Adjacency List. Consider the following structure for both Vertices and
Edges
StructGNode
{
int weight;
GNode *ptr;
}*GList;

Note: In the following example DelAllMinEdges( ) will delete the edge between vertex 4 to 3
and 1to 4 because of minimum weight.

9. Web References:
http://www3.cs.stonybrook.edu/~algorith/files/graph-data-structures.shtml
http://interactivepython.org/runestone/static/pythonds/Graphs/graphintro.html
https://www.cs.auckland.ac.nz/~jmor159/PLDS210/mst.html

10. Video References:


www.youtube.com/watch?v=vfCo5A4HGKc
www.youtube.com/watch?v=dJc38Vh2TrY

11. Summary:
This lab introduces students with the concepts of graphs and their implementation.

87 Data Structures and Algorithms


EXPERIMENT 14– HASHING
1. Objectives:
To learn the concepts of hashing and to implement them
2. Time Required: 3 hrs
3. Software Required:
(a). C++
(b). Windows
4. Hashing: Hashing is technique that maps each key to a location in memory. This method is
useful in searching.
Hashing refers to the process of generating a fixed-size output from an input of variable size
using the mathematical formulas known as hash functions. This technique determines an index or
location for the storage of an item in a data structure.

Components of Hashing
There are majorly three components of hashing:

Key: A Key can be anything string or integer which is fed as input in the hash function the
technique that determines an index or location for storage of an item in a data structure.
Hash Function: The hash function receives the input key and returns the index of an element in
an array called a hash table. The index is known as the hash index.
Hash Table: Hash table is a data structure that maps keys to values using a special function
called a hash function. Hash stores the data in an associative manner in an array where each data
value has its own unique index.

What is a Hash function?


The hash function creates a mapping between key and value, this is done through the use of
mathematical formulas known as hash functions. The result of the hash function is referred to as a
hash value or hash. The hash value is a representation of the original string of characters but
usually smaller than the original.

For example: Consider an array as a Map where the key is the index and the value is the value at
that index. So for an array A if we have index i which will be treated as the key then we can find
the value by simply looking at the value at A[i].
Types of Hash functions:
There are many hash functions that use numeric or alphanumeric keys.

 Division Method.
 Mid Square Method.
 Folding Method.
 Multiplication Method.

Properties of a Good hash function:


A good hash function should have the following properties:

 Efficiently computable.
 Should uniformly distribute the keys (Each table position is equally likely for each.
 Should minimize collisions.
 Should have a low load factor(number of items in the table divided by the size of the
table)
Hash Table: A hash table is simply an array that is addressed via a hash function. Here Hash
Table is an array with 8 elements. Each element is a pointer to a linked list of numeric data. The
hash function for this example simply divides the data key by 8, and uses the remainder as an
index into the table. This yields a number from 0 to 7. Since the range of indices for Hash Table
is 0 to 7, we are guaranteed that the index is valid.

Problem with Hashing


If we consider the above example, the hash function we used is the sum of the letters, but if we
examined the hash function closely then the problem can be easily visualized that for different
strings same hash value is begin generated by the hash function.

For example: {“ab”, “ba”} both have the same hash value, and string {“cd”,”be”} also generate
the same hash value, etc. This is known as collision and it creates problem in searching, insertion,
deletion, and updating of value.

What is collision?
The hashing process generates a small number for a big key, so there is a possibility that two keys
could produce the same value. The situation where the newly inserted key maps to an already
occupied, and it must be handled using some collision handling technology.
How to handle Collisions?
There are mainly two methods to handle collision:

 Separate Chaining:
The idea is to make each cell of the hash table point to a linked list of records that have the same
hash function value. Chaining is simple but requires additional memory outside the table.

Example: We have given a hash function and we have to insert some elements in the hash table
using a separate chaining method for collision resolution technique.
Hash function = key % 5,
Elements = 12, 15, 22, 25 and 37.
 Open Addressing:
In open addressing, all elements are stored in the hash table itself. Each table entry contains
either a record or NIL. When searching for an element, we examine the table slots one by one
until the desired element is found or it is clear that the element is not in the table.

a) Linear Probing

In linear probing, the hash table is searched sequentially that starts from the original location
of the hash. If in case the location that we get is already occupied, then we check for the next
location.
Algorithm:
Calculate the hash key. i.e. key = data % size
Check, if hashTable[key] is empty
store the value directly by hashTable[key] = data
If the hash index already has some value then
check for next index using key = (key+1) % size
Check, if the next index is available hashTable[key] then store the value. Otherwise try for
next index.
Do the above process till we find the space.

b) Quadratic probing is an open addressing scheme in computer programming for resolving


hash collisions in hash tables. Quadratic probing operates by taking the original hash index
and adding successive values of an arbitrary quadratic polynomial until an open slot is found.

An example sequence using quadratic probing is:

H + 12, H + 22, H + 32, H + 42…………………. H + k2

This method is also known as the mid-square method because in this method we look for i2‘th
probe (slot) in i’th iteration and the value of i = 0, 1, . . . n – 1. We always start from the
original hash location. If only the location is occupied then we check the other slots.

Let hash(x) be the slot index computed using the hash function and n be the size of the hash
table.

If the slot hash(x) % n is full, then we try (hash(x) + 12) % n.


If (hash(x) + 12) % n is also full, then we try (hash(x) + 22) % n.
If (hash(x) + 22) % n is also full, then we try (hash(x) + 32) % n.
This process will be repeated for all the values of i until an empty slot is found

c) Double Hashing
Double hashing is a collision resolving technique in Open Addressed Hash tables. Double
hashing make use of two hash function,

The first hash function is h1(k) which takes the key and gives out a location on the hash table.
But if the new location is not occupied or empty then we can easily place our key.
But in case the location is occupied (collision) we will use secondary hash-function h2(k) in
combination with the first hash-function h1(k) to find the new location on the hash table.
This combination of hash functions is of the form

h(k, i) = h1(k) + i * h2(k)) % n


where

i is a non-negative integer that indicates a collision number,


k = element/key which is being hashed
n = hash table size.

// CPP program to implement hashing with chaining


#include<iostream>
#include <list>
using namespace std;

class Hash
{
int BUCKET; // No. of buckets

// Pointer to an array containing buckets


list<int> *table;
public:
Hash(int V); // Constructor

// inserts a key into hash table


void insertItem(int x);

// deletes a key from hash table


void deleteItem(int key);

// hash function to map values to key


int hashFunction(int x) {
return (x % BUCKET);
}

void displayHash();
};

Hash::Hash(int b)
{
this->BUCKET = b;
table = new list<int>[BUCKET];
}

void Hash::insertItem(int key)


{
int index = hashFunction(key);
table[index].push_back(key);
}

void Hash::deleteItem(int key)


{
// get the hash index of key
int index = hashFunction(key);

// find the key in (inex)th list


list <int> :: iterator i;
for (i = table[index].begin();
i != table[index].end(); i++) {
if (*i == key)
break;
}
// if key is found in hash table, remove it
if (i != table[index].end())
table[index].erase(i);
}

// function to display hash table


void Hash::displayHash() {
for (int i = 0; i < BUCKET; i++) {
cout << i;
for (auto x : table[i])
cout << " --> " << x;
cout << endl;
}
}

// Driver program
int main()
{
// array that contains keys to be mapped
int a[] = {15, 11, 27, 8, 12};
int n = sizeof(a)/sizeof(a[0]);

// insert the keys into the hash table


Hash h(7); // 7 is count of buckets in
// hash table
for (int i = 0; i < n; i++)
h.insertItem(a[i]);

// delete 12 from hash table


h.deleteItem(12);

// display the Hash table


h.displayHash();

return 0;
}

7. Exercises:
Exercise 14.1:

Write a program to prepare the hashing table as shown above. Take the elements through the
keyboard and map them in hash table.

Exercise 14.2:

Write a function deleteNode deletes and frees a node from the table.

Exercise 14.3:

Write a function findNode searches the table for a particular value.

8. Web Resources:
https://www.cs.auckland.ac.nz/software/AlgAnim/hash_func.html
http://datastructuresnotes.blogspot.com/2009/03/hashing-hash-data-structure-and-hash.html

9. Video Resources:
www.youtube.com/watch?v=MfhjkfocRR0
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-046j-introduction-to-
algorithms-sma-5503-fall-2005/video-lectures/lecture-7-hashing-hash-functions/

10. Summary:
This lab introduces students with hash functions, hash tables, their uses and their implementation.
EXPERIMENT 15 OPEN ENDED LAB

Title: Library Management System

Objective:
The primary objective of this open-ended lab activity is to design and implement a Library Management
System. Through this activity, students will apply their knowledge of data structures, file handling, and object-
oriented programming to create a functional program capable of managing library resources, handling user
interactions, and performing efficient search and sorting operations.

Prerequisites:
- Intermediate understanding of programming language.
- Familiarity with data structures such as arrays, linked lists, and file handling concepts.

Materials Needed:
- Development environment (IDE or text editor)
- Sample library dataset (books, users, transactions)

Activity Description:

Task:
Develop a program for managing a library's resources, user interactions, and transactions. The program should
incorporate the following functionalities:

1. Book and User Management:


- Utilize appropriate data structures to store information about books (Title, Author, ISBN, Availability) and
users (ID, Name, Contact Details).

2. Borrowing and Returning Books:


- Implement functions to handle the borrowing and returning of books by users, updating the availability
status accordingly.

3. Transaction History:
- Maintain a transaction history to record details of books borrowed and returned by users, including
timestamps and user information.

4. Search and Sorting:


- Implement search functionalities to find books by Title, Author, or ISBN, and users by ID or Name.
- Arrange the book records by Title or Author in ascending order using an appropriate sorting algorithm.

Deliverables:

1. Program Code: Well-structured code implementing the Library Management System, including
appropriate comments and documentation.

2. User Manual: A comprehensive user manual outlining the functionalities of the program, including
instructions for managing books, users, and transactions.

3. Test Cases: A set of test cases and their expected outputs to validate the correctness and robustness of the
program.
4. Reflection and Analysis: A reflective analysis discussing the design decisions, challenges faced, and
insights gained during the development process.

Evaluation Criteria:

- Functionality Completeness: The program should fully implement the specified functionalities, ensuring
accurate management of library resources and transactions.
- Code Quality: The code should be well-organized, readable, and maintainable, adhering to best practices of
programming.
- Efficiency: Efficient utilization of data structures and algorithms to optimize the performance of search and
sorting operations.
- Documentation and Reflection: The quality and completeness of documentation, including user manuals,
test cases, and reflective analysis.

You might also like