ITDS 083
ITDS 083
IT-201
DATA STRUCTURE
LAB FILE
Submitted by:
Kshitij Dayal
2K20/ME/127
Experiment 1 (Programs on Strings and Passing Pointers to Functions &
Array)
C++ string class internally uses char array to store character but all memory management,
allocation, and null termination is handled by string class itself that is why it is easy to use.
The length of the C++ string can be changed at runtime because of dynamic allocation of
memory similar to vectors. As string class is a container class, we can iterate over all its
characters using an iterator similar to other containers like vector, set and maps, but
generally, we use a simple for loop for iterating over the characters and index them using
the [] operator.
C++ string class has a lot of functions to handle string easily. Most useful of them are
demonstrated in below code.
Problem 1 WAP with function to swap two numbers using call by reference. (C++)
Call-by-reference is a location or address of actual arguments passed to formal arguments.
Following program shows that the swapping of two numbers using call-by-reference.
CODE
#include<iostream>
using namespace std;
void swap (int &num1, int &num2) //&num1 and &bnum2 are Reference variables
{
int temp;
temp=num1;
num1=num2;
num2=temp;
}
int main()
{
//input
int a=5,b=10;
cout<<"\n Before swapping"<<"\n A = "<<a<<"\n B = "<<b<<endl;
swap(a,b);
cout<<"\n After swapping"<<"\n A = "<<a<<"\n B = "<<b<<endl;
return 0;
}
Output a=10,b=5
Problem 2 WAP with function to swap two integer arrays of same size using call by
reference.
#include <iostream>
using namespace std;
void swap(int array1[], int array2[])
{
int temp,i;
for(i=0; i<5; ++i)
{
temp = array1[SIZE];
array1[SIZE] = array2[SIZE];
array2[SIZE] = temp;
}
cout << "\nThe swapped arrays are as shown below: " << endl;
cout << " Array 1 is: ";
for (int i = 0; i < 5; ++i) {
cout << array1[i] << " ";
}
cout << "\n Array 2 is: ";
for (int i = 0; i < 5; ++i) {
cout << array2[i] << " ";
}
}
int main() {
int array1[SIZE] = {10,20,30,40,50};
int array2[SIZE] = {60,70,80,90,100};
swap(array1, array2);
return 0;
}
//output array1={60,70,80,90,100}
Array1={10,20,30,40,50}
#include<bits/stdc++.h>
using namespace std;
void Swap(int &arr){
while(l<h){
int temp=arr[l];
arr[l]=arr[h];
arr[h]=temp;
l++;
h--;
int l=0,h=arr.size(-1);
Int main()
{
Int arr[10]={1,2,3,4,5,6,7,8,9,10};
Swap(arr);
return 0;
}
WAP with function to swap two strings using pointers.
#include<stdio.h>
void swap1(char **str1_ptr, char **str2_ptr)
{
char *temp = *str1_ptr;
*str1_ptr = *str2_ptr;
*str2_ptr = temp;
}
int main()
{
char *str1 = "geeks";
char *str2 = "forgeeks";
swap1(&str1, &str2);
printf("str1 is %s, str2 is %s", str1, str2);
getchar();
return 0;
}
Output array={10,9,8,7,6,5,4,3,2,1
Experiment 2 (Dynamic Memory Allocation and File Operations)
1. ios:-
ios stands for input output stream.
This class is the base class for other classes in this class hierarchy.
This class contains the necessary facilities that are used by all the other derived
classes for input and output operations.
2. istream:-
istream stands for input stream.
This class is derived from the class ‘ios’.
This class handle input stream.
The extraction operator(>>) is overloaded in this class to handle input streams
from files to the program execution.
This class declares input functions such as get(), getline() and read().
3. ostream:-
ostream stands for output stream.
This class is derived from the class ‘ios’.
This class handle output stream.
The insertion operator(<<) is overloaded in this class to handle output streams
to files from the program execution.
This class declares output functions such as put() and write().
4. streambuf:-
This class contains a pointer which points to the buffer which is used to manage
the input and output streams.
5. fstreambase:-
This class provides operations common to the file streams. Serves as a base for
fstream, ifstream and ofstream class.
This class contains open() and close() function.
6. ifstream:-
This class provides input operations.
It contains open() function with default input mode.
Inherits the functions get(), getline(), read(), seekg() and tellg() functions from
the istream.
7. ofstream:-
This class provides output operations.
It contains open() function with default output mode.
Inherits the functions put(), write(), seekp() and tellp() functions from the
ostream.
8. fstream:-
This class provides support for simultaneous input and output operations.
Inherits all the functions from istream and ostream classes through iostream.
9. filebuf:-
Its purpose is to set the file buffers to read and write.
We can also use file buffer member function to determine the length of the file.
In C++, files are mainly dealt by using three classes fstream, ifstream, ofstream available in
fstream headerfile.
ofstream: Stream class to write on files
ifstream: Stream class to read from files
fstream: Stream class to both read and write from/to files.
C malloc() method
Problem 1 WAP to find the Median of the elements after merging the two sorted Arrays of
same size.
CODE:
#inlcude<bits/stdc++.h>
Using numspace std;
Int Median(int a,int b){
Vector<int>c;
While(a.size()!=0 && b.size()!=0){
If(a.front()>b.front())
c.push_back(b.front());
b.pop_front();
else{
c.push_back(a.front());
a.pop_front();
if(a.size()!=0){
c.push_back(a.front());
a.pop_front();
}
If(b.size()!=0){
c.push_back(b.front());
b.pop_front();
}
Int i=n;
Return c[i];
}
Int main(){
Int n;
Cin>>n;
//input
Vector<int>a={1,3,5,7,9};
Vector<int>b={2,4,6,8,10};
Median(a,b);
}
Output median =(5+6)/2=5.5
Problem 2 WAP to store an information in array of structure, dynamically, and also give a
function to display the current information. The program should give user a choice for
inserting a data or to display the current data. Implement the program for Student
structures (contains student_name, student_roll_no, total_marks).
int main() {
int i;
cout<<("Enter information of students:\n");
// storing information
for (i = 0; i < 5; ++i) {
s[i].roll = i + 1;
cout<<”For roll number ", s[i].roll);
cout<<("Enter first name: ");
cin>>s[i].firstName;
cout<<"Enter marks:";
cin>>s[i].marks;
}
Cout<<” Displaying Information”;
// displaying information
for (i = 0; i < 5; ++i) {
printf("\nRoll number: %d\n", i + 1);
cout<<”First Name”;
puts(s[i].firstName);
printf("Marks: %.1f", s[i].marks);
cout<<endl;
}
return 0;
WAP a program to store data of an employee in a structure variable
#include <iostream>
using namespace std;
struct Employee {
char name[50];
int salary;
int employeeCode;
char dept[5];
};
int main() {
Employee e;
WAP to Create a new file, Open an existing file, read the file to search a given word, write
into the file and close the file.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
fstream my_file;
my_file.open("my_file", ios::out);
if (!my_file) {
cout << "File not created!";
}
else {
cout << "File created successfully!";
my_file.close();
}
return 0;
}
Experiment 3 Searching and Sorting in Non-decreasing order)
Searching Algorithms are designed to check for an element or retrieve an element from any
data structure where it is stored. Based on the type of search operation, these algorithms are
generally classified into two categories:
1. Sequential Search: In this, the list or array is traversed sequentially and every
element is checked. For example Linear Search.
2. Interval Search: These algorithms are specifically designed for searching in
sorted data-structures. These type of searching algorithms are much more
efficient than Linear Search as they repeatedly target the center of the search
structure and divide the search space in half. For Example: Binary Search.
Problem 1 WAP to implement Linear search and Binary search on 1D array of Integers.
#include <iostream>
using namespace std;
// Driver's code
int main(void)
{
int arr[] = { 2, 3, 4, 10, 40 };
int x = 10;
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
int result = search(arr, N, x);
(result == -1)
? cout << "Element is not present in array"
: cout << "Element is present at index " << result;
return 0;
}
Time Complexity O(N)
Space Complexity O(1)
WAP to implement Insertion and Selection sort on 1D array of strings
Selection Sort
#include <bits/stdc++.h>
#include <string.h>
using namespace std;
#define MAX_LEN 100
void selectionSort(char arr[][MAX_LEN], int n)
{
int i, j, min_idx;
char minStr[MAX_LEN];
for (i = 0; i < n-1; i++)
{
int min_idx = i;
strcpy(minStr, arr[i]);
for (j = i + 1; j < n; j++)
{
if (strcmp(minStr, arr[j]) > 0)
{
strcpy(minStr, arr[j]);
min_idx = j;
}
}
if (min_idx != i)
{
char temp[MAX_LEN];
strcpy(temp, arr[i]); //swap item[pos] and item[i]
strcpy(arr[i], arr[min_idx]);
strcpy(arr[min_idx], temp);
}
}
}
Input : paper true soap floppy flower
Output: floppy, flower, paper, soap, true
WAP to implement Merge Sort on 1D array of Student structures (contains student_name,
student_roll_no, total_marks) with key as student_roll_no.
#include<stdio.h>
struct student
{
int rollno;
char name[20];
char college[40];
};
void main()
{
struct student s[20],temp;
int i,j,n;
clrscr();
printf("\nEnter no. of Students : ");
scanf("%d",&n);
printf("\nEnter the rollno,name,college name,score ");
for(i=0;i<n;i++)
scanf("%d%s%s%d",&s[i].rollno,s[i].name,s[i].college,&s[i].score);
for(i=0;i<=n-1;i++)
{
for(j=0;j<=n-1;j++)
{
if(s[j].score<s[j+1].score)
{
temp=s[j];
s[j]=s[j+1];
s[j+1]=temp;
}
}
}
printf("\nThe Merit List is :\n");
for(j=0;j<n;j++)
printf("%d\t%s\t%s\t%d\n",s[j].rollno,s[j].name,s[j].college,s[j].score);
getch();
}
Input Rohit Dav 203
Sumit Dav 202
Ritesh Dav 201
Rahul Dav 205
Rajesh Dav 204
Problem 1 WAP to store and display a Lower-Right triangular matrix in RMO and CMO
fashion.
Problem 2 WAP to store and display an Upper-Right triangular matrix in RMO and CMO
fashion.
Given a lower triangular matrix Mat[][], the task is to store the matrix using row-major
mapping.
Lower Triangular Matrix: A lower triangular matrix is a square matrix in which the lower
triangular part of a matrix consists of non-zero elements and the upper triangular part
consists of 0s. The lower triangular matrix for a 2D matrix Mat[][] is mathematically
defined as:
If i < j, set Mat[i][j] = 0.
If i >= j, set Mat[i][j] > 0.
#include<iostream>
using namespace std;
void lower(int matrix[3][3], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (i < j)
{
cout << "0" << " ";
}
else
cout << matrix[i][j] << " ";
}
cout << endl;
}
}
void upper(int matrix[3][3], int row, int col)
{
int i, j;
int main()
{
int matrix[3][3] = {{1, 2, 3},
{4, 5, 6},
{7, 8, 9}};
int row = 3, col = 3;
return 0;
}
Input : matrix[3][3] = {1 2 3
4 5 6
7 8 9}
Output :
Lower : 1 0 0 Upper : 1 2 3
4 5 0 0 5 6
7 8 9 0 0 9
Input : matrix[3][3] = {7 8 9
3 2 1
6 5 4}
Output :
Lower : 7 0 0 Upper : 7 8 9
3 2 0 0 2 1
6 5 4 0 0 4
WAP to store and display a Tri-Diagonal matirx in RMO and CMO fashion.
What does it mean by a tridiagonal matrix?
If we look at the elements, non-zero elements are present in the main diagonal, lower
diagonal, and upper diagonal and the rest of the elements are all zeros. Let us define the
property of this matrix based on indices of the matrix. If we observe the indices of
elements of:
1. Main Diagonal: row number is equal to column number (i = j).
2. Lower Diagonal: row number – column number = 1 (i – j = 1).
3. Upper Diagonal: row number – column number = -1 (i – j = -1).
struct Matrix
{
int *B;
int n;
};
void Set (struct Matrix *m, int i, int j, int y)
{
if (i - j == 1)
{
m->B[i - 1] = y;
}
if (i - j == 0)
{
m->B[m->n - 1 + i - 1] = y;
}
if (i - j == -1)
{
m->B[(2 * m->n) - 1 + i - 1] = y;
}
}
int Get (struct Matrix m, int i, int j)
{
if (i - j == 1)
{
return m.B[i - 1];
}
if (i - j == 0)
{
return m.B[m.n - 1 + i - 1];
}
if (i - j == -1)
{
return m.B[(2 * m.n) - 1 + i - 1];
}
return 0;
Experiment 5 (Stacks and Queues)
Stack
It is a linear data structure that follows a particular order in which the operations are
performed.
LIFO( Last In First Out ):
This strategy states that the element that is inserted last will come out first. You can take a
pile of plates kept on top of each other as a real-life example. The plate which we put last
is on the top and since we remove the plate that is at the top, we can say that the plate
that was put last comes out first.
Basic Operations on Stack
In order to make manipulations in a stack, there are certain operations provided to us.
push() to insert an element into the stack
pop() to remove an element from the stack
top() Returns the top element of the stack.
isEmpty() returns true is stack is empty else false
size() returns the size of stack
Queues are a type of container adapters that operate in a first in first out (FIFO) type of
arrangement. Elements are inserted at the back (end) and are deleted from the front.
Queues use an encapsulated object of deque or list (sequential container class) as its
underlying container, providing a specific set of member functions to access its elements.
Input: str = “2 3 1 * + 9 -“
Output: -4
#include <bits/stdc++.h>
using namespace std;
bool areBracketsBalanced(string expr)
{
stack<char> temp;
for (int i = 0; i < expr.length(); i++) {
if (temp.empty()) {
temp.push(expr[i]);
}
else if ((temp.top() == '(' && expr[i] == ')')
|| (temp.top() == '{' && expr[i] == '}')
|| (temp.top() == '[' && expr[i] == ']')) {
temp.pop();
}
else {
temp.push(expr[i]);
}
}
if (temp.empty()) {
return true;
}
return false;
}
int main()
{
string expr = "{()}[]";
if (areBracketsBalanced(expr))
cout << "Balanced";
else
cout << "Not Balanced";
return 0;
}
Input: exp = “[()]{}{[()()]()}”
Output: Balanced
Explanation: all the brackets are well-formed
Input: exp = “[(])”
Output: Not Balanced
Explanation: 1 and 4 brackets are not balanced
Experiment 6 (Singly Linked List)
Like arrays, Linked List is a linear data structure. Unlike arrays, linked list elements are not
stored at a contiguous location; the elements are linked using pointers. They include a
series of connected nodes. Here, each node stores the data and the address of the next
node.
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 a 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.
Problem 1 WAP to implement Stack ADT using Linked list with the basic operations as
Create(), IsEmpty(), Push(), Pop(), IsFull() with appropriate prototype to a functions.
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* link;
Node(int n)
{
this->data = n;
this->link = NULL;
}
};
class Stack {
Node* top;
public:
Stack() { top = NULL; }
void push(int data)
{
Node* temp = new Node(data);
if (!temp) {
cout << "\nStack Overflow";
exit(1);
}
temp->data = data;
temp->link = top;
top = temp;
}
bool isEmpty()
{
return top == NULL;
}
int peek()
{
if (!isEmpty())
return top->data;
else
exit(1);
}
void pop()
{
Node* temp;
if (top == NULL) {
cout << "\nStack Underflow" << endl;
exit(1);
}
else {
temp = top;
top = top->link;
free(temp);
}
}
void display()
{
Node* temp;
if (top == NULL) {
cout << "\nStack Underflow";
exit(1);
}
else {
temp = top;
while (temp != NULL) {
cout << temp->data;
temp = temp->link;
if (temp != NULL)
cout << " -> ";
}
}
}
};
Problem 2 WAP to swap elements in pairs in the given linked list. (e.g.: 1->2->3->4->5-
>null, then result should be 2->1->4->3->5->null.)
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head==NULL||head->next==NULL){
return head;
}
ListNode *curr=head;
ListNode *prev=new ListNode;
while((curr!=NULL)&&(curr->next!=NULL)){
prev->next=curr->next;
curr->next=curr->next->next;
prev->next->next=curr;
curr=curr->next;
prev=prev->next;
}
return prev->next;
}
};
Input =1->2->3->4->5->null
Output=2->1->4->3->5->null.)
Problem 3 WAP to find second last node of the given linked list.
#include <bits/stdc++.h>
using namespace std;
ListNode* seondlast(ListNode* head){
ListNode* temp=head;
While(temp->next->next!=NULL){
temp=temp->next;
}
Return temp;
}
Input=1->2->3->4->5->null
Output=4
Problem 4 WAP to concatenate two singly linked list in sorted order either ascending or
descending.
#include <bits/stdc++.h>
using namespace std;
ListNode* headsorted(ListNode* head1,ListNode* head2){
ListNode* temp=newNode(0);
ListNode* ans=temp;
While(head1->next!=NULL && head2->next!=NULL){
If(head1->data<head2->data){
Temp->next=head1;
Temp=temp->next;
}
Else{
Temp->next=head2;
Temp=temp->next;
}
While(head1->next!=NULL){
Temp->next=head1;
Temp=temp->next;
While(head2->next!=NULL){
Temp->next=head2;
Temp=temp->next;
}
Return ans;
Input =1->3->5->7->9->null and 2->4->6->8->10null
Output=1-->2->3->4->5->->6->7->8->9->10->null
#include <bits/stdc++.h>
using namespace std;
int firstCommon(struct Node* head1, struct Node* head2)
{
// Traverse through every node of first list
for (; head1 != NULL; head1=head1->next)
for (Node *p = head2; p != NULL; p = p->next)
if (p->data == head1->data)
return head1->data;
return 0;
}
Input=L1=13->7->9->4->8
L2=11->10->4->8->9
Output=4
Experiment 7 (Circular Singly Linked List and Doubly Linked List)
Circular Singly Linked List
In a singly linked list, for accessing any node of the linked list, we start traversing from the
first node. If we are at any node in the middle of the list, then it is not possible to access
nodes that precede the given node. This problem can be solved by slightly altering the
structure of a singly linked list. In a singly linked list, the next part (pointer to the next
node) of the last node is NULL. If we utilize this link to point to the first node, then we can
reach the preceding nodes.
Doubly linked list
A Doubly Linked List (DLL) contains an extra pointer, typically called the previous pointer,
together with the next pointer and data which are there in the singly linked list.
Advantages of DLL over the singly linked list:
A DLL can be traversed in both forward and backward directions.
The delete operation in DLL is more efficient if a pointer to the node to be
deleted is given.
We can quickly insert a new node before a given node.
In a singly linked list, to delete a node, a pointer to the previous node is
needed. To get this previous node, sometimes the list is traversed. In DLL, we
can get the previous node using the previous pointer.
WAP to represent various sparse matrices using linked list and give addition function to add two
sparse matrices.
Input: { 0 , 0 , 3 , 0 , 4 },
{ 0 , 0 , 5 , 7 , 0 },
{ 0 , 0 , 0 , 0 , 0 },
{ 0 , 2 , 6 , 0 , 0 }
#include<iostream>
using namespace std;
class Node
{
public:
int row;
int col;
int data;
Node *next;
};
void printList(Node *start)
{
Node *ptr = start;
cout << "row_position:";
while (ptr != NULL)
{
cout << ptr->row << " ";
ptr = ptr->next;
}
cout << endl;
cout << "column_position:";
ptr = start;
while (ptr != NULL)
{
cout << ptr->col << " ";
ptr = ptr->next;
}
cout << endl;
cout << "Value:";
ptr = start;
while (ptr != NULL)
{
cout << ptr->data << " ";
ptr = ptr->next;
}
}
Output:
row_position:0 0 1 1 3 3
column_position:2 4 2 3 1 2
Value:3 4 5 7 2 6
Experiment 8 (Binary Trees, BST, Heaps, Heap sort and Threaded Binary Trees)
A tree is a popular data structure that is non-linear in nature. Unlike other data structures
like array, stack, queue, and linked list which are linear in nature, a tree represents a
hierarchical structure. The ordering information of a tree is not important. A tree contains
nodes and 2 pointers. These two pointers are the left child and the right child of the
parent node. Let us understand the terms of tree in detail.
Root: The root of a tree is the topmost node of the tree that has no parent
node. There is only one root node in every tree.
Edge: Edge acts as a link between the parent node and the child node.
Leaf: A node that has no child is known as the leaf node. It is the last node of
the tree. There can be multiple leaf nodes in a tree.
Subtree: The subtree of a node is the tree considering that particular node as
the root node.
Depth: The depth of the node is the distance from the root node to that
particular node.
Height: The height of the node is the distance from that node to the deepest
node of that subtree.
Height of tree: The Height of the tree is the maximum height of any node. This
is same as the height of root node
Binary Tree: A tree whose elements have at most 2 children is called a binary tree. Since
each element in a binary tree can have only 2 children, we typically name them the left
and right child.
Binary Tree Representation: A tree is represented by a pointer to the topmost node of the
tree. If the tree is empty, then the value of the root is NULL.
A Tree node contains the following parts.
1. Data
2. Pointer to the left child
3. Pointer to the right child
A binary Search Tree is a node-based binary tree data structure which has the following
properties:
The left subtree of a node contains only nodes with keys lesser than the node’s
key.
The right subtree of a node contains only nodes with keys greater than the
node’s key.
The left and right subtree each must also be a binary search tree.
There must be no duplicate nodes.