ADSA Lab
ADSA Lab
AND MANAGEMENT
(Approved by AICTE, New Delhi & Affiliated to Anna University,
Chennai) “NEHRU GARDENS”, TM Palayam P.O.
COIMBATORE-641105
REGISTER NUMBER :
NAME
CLASS
SEMESTER
SUBJECT CODE
SUBJECT
:
NEHRU INSTITUTE OF INFORMATION TECHNOLOGY AND
MANAGEMENT
BONAFIDE CERTIFICATE
FACULTY SUPERVISED
INTERNAL EXAMINER
EXTERNAL EXAMINER
Date
Ex.
No
Experiments
Page.
No
Implementation of recursive
function for tree traversal and
Fibonacci
23.09.23
Implementation of iteration
function for tree traversal and
Fibonacci
25.09.23
12
27.09.23
Implementation of a Binary
Search Tree
18
04.10.23
25
07.10.23
Heap Implementation
29
09.10.23
36
11.10.23
Graph Traversals
39
16.10.23
43
18.10.23
10
47
25.10.23
11
53
28.10.23
12
55
20.09.23
Signature
Date
Ex.
No
01.11.23
13
57
04.11.23
14
59
06.11.23
15
Bubble Sort
61
15.11.23
16
Insertion Sort
63
17
65
22.11.23
18
67
25.11.23
19
Represent Graph Using
Adjacency List
69
27.11.23
20
72
29.11.23
21
75
06.12.23
22
77
11.12.23
23
80
13.12.23
24
82
20.11.23
Experiments
Page.
No
Signature
Date
Ex.
No
Experiments
Page.
No
18.12.23
25
84
20.12.23
26
86
23.12.23
27
88
27.12.23
28
91
Signature
Ex No :1A)
Date : 20.09.23
Aim :
To create a program to perform tree traversals.
Algorithm :
Step 1 : Start the program
Step 2 : create the node containing one value and two pointers in it
Step 3 : Assign the desired value to the created Nodes.
Step 4 : perform three types of traversal in the created tree.
1.Pre-order
2.In-order
3.post-order
Step 5 : Display the outputs and verify it.
Step 6 : Stop the Program.
Source code :
#include <iostream>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
Node(int val) : data(val), left(nullptr), right(nullptr) {}
};
1
void preOrderTraversal(Node* root) {
if (root == nullptr) return;
cout << root->data << " ";
preOrderTraversal(root->left);
preOrderTraversal(root->right); // Traverse right subtree
}
void inOrderTraversal(Node* root) {
if (root == nullptr) return;
inOrderTraversal(root->left); // Traverse left subtree
cout << root->data << " "; // Process the current node
inOrderTraversal(root->right); // Traverse right subtree
}
void postOrderTraversal(Node* root) {
if (root == nullptr) return;
postOrderTraversal(root->left); // Traverse left subtree
postOrderTraversal(root->right); // Traverse right subtree
cout << root->data << " "; // Process the current node
}
int main() {
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 << "Pre-order traversal: ";
2
preOrderTraversal(root);
cout << endl;
cout << "In-order traversal: ";
inOrderTraversal(root);
cout << endl;
cout << "Post-order traversal: ";
postOrderTraversal(root);
cout << endl;
return 0;
}
Output :
Pre-order traversal: 1 2 4 5 3
In-order traversal: 4 2 5 1 3
Post-order traversal: 4 5 2 3 1
Result:
The program has been executed successfully and the output was verified.
3
Ex No : 1 B)
Date: 20.09.23
Aim:
To create a program to get Fibonacci series.
Algorithm :
Step 1 : Start the program
Step 2 : Read the N value that the No of elements user want to print.
Step 3 : Perform the algorithm to print the N Fibonacci numbers based on
recursive method.
Step 4 : Print the results.
Step 5 : verify the outputs.
Step 6 : Stop the Program.
Source code :
#include <iostream>
int fibonacci(int n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
int main() {
int n = 10; // Change this value to get different Fibonacci numbers
4
for (int i = 0; i < n; ++i) {
std::cout << fibonacci(i) << " ";
}
std::cout << std::endl;
return 0;
}
Output :
Fibonacci sequence up to 10 terms:
0 1 1 2 3 5 8 13 21 34
Result:
The program has been executed successfully and the output was verified.
5
Ex.No : 2
Date : 23.09.23
Aim:
To Implement a CPP program for tree traversal and Fibonacci series using iteration.
Algorithm:
A .Tree Traversal
Step 1: Start the program.
Step 2: Create a tree structure.
Step 3: Using that structure assign the value for the tree.
Step 4: Using stack get the values of the tree .
Step 5: using loops print the values of the tree.
Step 6: Verify the output.
Step 7: Stop the Program.
Source code :
#include <iostream>
#include <stack>
struct Node {
int data;
Node* left;
Node* right;
Node(int val) : data(val), left(nullptr), right(nullptr) {}
};
6
void inOrderTraversal(Node* root) {
std::stack<Node*> stk;
Node* curr = root;
while (curr != nullptr || !stk.empty()) {
while (curr != nullptr) {
stk.push(curr);
curr = curr->left;
}
curr = stk.top();
stk.pop();
std::cout << curr->data << " ";
curr = curr->right;
}
}
void preOrderTraversal(Node* root) {
if (root == nullptr) return;
std::stack<Node*> stk;
stk.push(root);
while (!stk.empty()) {
Node* curr = stk.top();
stk.pop();
std::cout << curr->data << " ";
if (curr->right != nullptr) stk.push(curr->right);
if (curr->left != nullptr) stk.push(curr->left);
7
}
}
void postOrderTraversal(Node* root) {
if (root == nullptr) return;
std::stack<Node*> stk;
std::stack<int> out;
stk.push(root);
while (!stk.empty()) {
Node* curr = stk.top();
stk.pop();
out.push(curr->data);
if (curr->left != nullptr) stk.push(curr->left);
if (curr->right != nullptr) stk.push(curr->right);
}
while (!out.empty()) {
std::cout << out.top() << " ";
out.pop();
}
}
int main() {
// Example tree
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
8
root->left->right = new Node(5);
std::cout << "In-order traversal: ";
inOrderTraversal(root);
std::cout << std::endl;
std::cout << "Pre-order traversal: ";
preOrderTraversal(root);
std::cout << std::endl;
std::cout << "Post-order traversal: ";
postOrderTraversal(root);
std::cout << std::endl;
return 0;
}
Output:
In-order traversal: 4 2 5 1 3
Pre-order traversal: 1 2 4 5 3
Post-order traversal: 4 5 2 3 1
Result:
The program has been executed successfully and the output was verified
9
B. Fibonacci
Algorithm :
Step 1: Start the program.
Step 2: Read the limit from the user.
Step 3: Using loop print the Fibonacci series up to the limit.
Step 4: Create two variable x and y and assign them 0 and 1.
Step 5: print the value of x and y.
Step 6: Inside the loop swap or change the value of x and y using third variable z.
Source code :
#include <iostream>
int fibonacci(int n) {
if (n <= 1) return n;
int a = 0, b = 1, result;
for (int i = 2; i <= n; ++i) {
result = a + b;
a = b;
b = result;
}
return result;
}
int main() {
int n = 10; // Change this value to get different Fibonacci numbers
std::cout << "Fibonacci sequence up to " << n << " terms:\n";
for (int i = 0; i < n; ++i) {
10
std::cout << fibonacci(i) << " ";
}
std::cout << std::endl;
return 0;
}
Output:
Fibonacci sequence up to 10 terms:
0 1 1 2 3 5 8 13 21 34
Result:
The program has been executed successfully and the output was verified.
11
Ex.No :3)A)
MERGE SORT
Date : 25.09.23
Aim:
To create a program to perform Merge Sort.
Algorithm:
Step 1: Find the middle index of the array.
Middle = 1 + (last – first)/2
Step 2: Divide the array from the middle.
Step 3: Call merge sort for the first half of the array
MergeSort(array, first, middle)
Step 4: Call merge sort for the second half of the array.
MergeSort(array, middle+1, last)
Step 5: Merge the two sorted halves into a single sorted array.
Source code :
#include <iostream>
#include <vector>
void merge(std::vector<int>& arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
std::vector<int> L(n1), R(n2);
for (int i = 0; i < n1; ++i)
L[i] = arr[left + i];
12
for (int j = 0; j < n2; ++j)
R[j] = arr[mid + 1 + j];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
++i;
} else {
arr[k] = R[j];
++j;
}
++k;
}
while (i < n1) {
arr[k] = L[i];
++i;
++k;
}
while (j < n2) {
arr[k] = R[j];
++j;
++k;
}
}
13
void mergeSort(std::vector<int>& arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
}
}
int main() {
std::vector<int> arr = {12, 11, 13, 5, 6, 7};
int arrSize = arr.size();
std::cout << "Original array: ";
for (int num : arr)
std::cout << num << " ";
std::cout << std::endl;
mergeSort(arr, 0, arrSize - 1);
std::cout << "Sorted array: ";
for (int num : arr)
std::cout << num << " ";
std::cout << std::endl;
return 0;
}
Output :
Original array: 12 11 13 5 6 7
Sorted array: 5 6 7 11 12 13
Result:
The program has been executed successfully and the output was verified.
14
Ex.No :3)B)
QUICK SORT
Date :25.09.23
Aim :
To create a program to perform Quick sort.
Algorithm :
Step 1 : Find a “pivot” item in the array. This item is the basis for comparison
for a
single round.
Step 2 : Start a pointer (the left pointer) at the first item in the array.
Step 3 : Start a pointer (the right pointer) at the last item in the array.
Step 4 : While the value at the left pointer in the array is less than the pivot
value,
move the left pointer to the right (add 1). Continue until the value at the left
pointer is greater than or equal to the pivot value.
Step 5 : While the value at the right pointer in the array is greater than the
pivot value,
move the right pointer to the left (subtract 1). Continue until the value at the
right pointer is less than or equal to the pivot value.
Source code :
#include <iostream>
struct Node {
int data;
Node* left;
Node* right;
Node(int val) : data(val), left(nullptr), right(nullptr) {}
};
class BST {
private:
Node* root;
15
Node* insertRecursive(Node* current, int value) {
if (current == nullptr) {
return new Node(value);
}
if (value < current->data) {
current->left = insertRecursive(current->left, value);
} else if (value > current->data) {
current->right = insertRecursive(current->right, value);
}
return current;
}
void inOrderTraversal(Node* current) {
if (current != nullptr) {
inOrderTraversal(current->left);
std::cout << current->data << " ";
inOrderTraversal(current->right);
}
}
public:
BST() : root(nullptr) {}
void insert(int value) {
root = insertRecursive(root, value);
}
void inOrder() {
std::cout << "In-order traversal: ";
16
inOrderTraversal(root);
std::cout << std::endl;
}
};
int main() {
BST tree;
tree.insert(8);
tree.insert(3);
tree.insert(10);
tree.insert(1);
tree.insert(6);
tree.insert(14);
tree.insert(4);
tree.insert(7);
tree.insert(13);
tree.inOrder();
return 0;
}
Output :
In-order traversal: 1 3 4 6 7 8 10 13 14
Result:
The program has been executed successfully and the output was verified.
17
Ex.No : 4
BST Operation
Date :27.09.23
Aim:
To write a program to perform binary search operations.
Algorithm:
Step 1: Create a structure called tree node and declare necessary variables.
Step 2: Create a function to find the minimum value in the tree.
Step 3: Create a function to find the maximum value in the tree.
Step 4: Create a function to insert new element to the tree.
Step 5: Create a function to delete element from the tree.
Step 6: Create a function to find an element from the tree.
Step 7: Create a function to print the in order of the tree.
Step 8: Create a function to print the preorder of the tree.
Step 9: Create a function to print the post order of the tree.
Step 10: In the main function give all the option and receive choice from the user.
Step 11: Using a switch case call the corresponding function according to the
choice.
Source code :
#include <iostream>
using namespace std;
enum Color { RED, BLACK };
struct Node {
int data;
Color color;
Node *left, *right, *parent;
Node(int data) : data(data) {
18
parent = left = right = nullptr;
color = RED;
}
};
class RedBlackTree {
private:
Node *root;
void rotateLeft(Node *x) {
Node *y = x->right;
x->right = y->left;
if (y->left != nullptr)
y->left->parent = x;
y->parent = x->parent;
if (x->parent == nullptr)
root = y;
else if (x == x->parent->left)
x->parent->left = y;
else
x->parent->right = y;
y->left = x;
x->parent = y;
}
void rotateRight(Node *x) {
Node *y = x->left;
x->left = y->right;
19
if (y->right != nullptr)
y->right->parent = x;
y->parent = x->parent;
if (x->parent == nullptr)
root = y;
else if (x == x->parent->right)
x->parent->right = y;
else
x->parent->left = y;
y->right = x;
x->parent = y;
}
void fixViolation(Node *&root, Node *&newNode) {
Node *parent = nullptr;
Node *grandParent = nullptr;
while ((newNode != root) && (newNode->color != BLACK) &&
(newNode->parent->color == RED)) {
parent = newNode->parent;
grandParent = newNode->parent->parent;
if (parent == grandParent->left) {
Node *uncle = grandParent->right;
if (uncle != nullptr && uncle->color == RED) {
grandParent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
20
newNode = grandParent;
} else {
if (newNode == parent->right) {
rotateLeft(parent);
newNode = parent;
parent = newNode->parent;
}
rotateRight(grandParent);
swap(parent->color, grandParent->color);
newNode = parent;
}
} else {
Node *uncle = grandParent->left;
if (uncle != nullptr && uncle->color == RED) {
grandParent->color = RED;
parent->color = BLACK;
uncle->color = BLACK;
newNode = grandParent;
} else {
if (newNode == parent->left) {
rotateRight(parent);
newNode = parent;
parent = newNode->parent;
}
21
rotateLeft(grandParent);
swap(parent->color, grandParent->color);
newNode = parent;
}
}
}
root->color = BLACK;
}
public:
RedBlackTree() : root(nullptr) {}
void insert(int key) {
Node *newNode = new Node(key);
if (root == nullptr) {
root = newNode;
root->color = BLACK;
return;
}
Node *parent = nullptr;
Node *current = root;
while (current != nullptr) {
parent = current;
if (newNode->data < current->data)
current = current->left;
else
current = current->right;
22
}
newNode->parent = parent;
if (parent == nullptr)
root = newNode;
else if (newNode->data < parent->data)
parent->left = newNode;
else
parent->right = newNode;
fixViolation(root, newNode);
}
void inorder() {
inorderHelper(root);
}
private:
void inorderHelper(Node *node) {
if (node == nullptr)
return;
inorderHelper(node->left);
cout << node->data << " ";
inorderHelper(node->right);
}
};
int main() {
RedBlackTree tree;
tree.insert(7);
23
tree.insert(3);
tree.insert(18);
tree.insert(10);
tree.insert(22);
tree.insert(8);
tree.insert(11);
tree.insert(26);
cout << "Inorder traversal of the constructed Red-Black tree is: \n";
tree.inorder();
cout << endl;
return 0;
}
Output :
Inorder traversal of the constructed Red-Black tree is:
3 7 8 10 11 18 22 26
Result:
The program has been executed and verified.
24
Ex.No :5
Date : 04.10.23
Aim:
To Implement a Cpp program to perform insert operation in red black tree.
Algorithm:
Step 1: Check whether tree is Empty.
Step 2: If tree is Empty then insert the newNode as Root node with color Black and
exit from the operation.
Step 3: If tree is not Empty then insert the newNode as a leaf node with Red color.
Step 4: If the parent of newNode is Black then exit from the operation.
Step 5: If the parent of newNode is Red then check the color of parent node's
sibling
of newNode.
Step 6: print the values Inserted in the tree.
Step 7: Verify the result.
Step 8: Stop the program.
Source code :
#include <iostream>
#include <vector>
class MinHeap {
private:
std::vector<int> heap;
int getParentIndex(int childIndex) {
return (childIndex - 1) / 2;
}
int getLeftChildIndex(int parentIndex) {
return (2 * parentIndex) + 1;
25
}
int getRightChildIndex(int parentIndex) {
return (2 * parentIndex) + 2;
}
void heapifyUp(int index) {
while (index > 0 && heap[index] < heap[getParentIndex(index)]) {
std::swap(heap[index], heap[getParentIndex(index)]);
index = getParentIndex(index);
}
}
void heapifyDown(int index) {
int left = getLeftChildIndex(index);
int right = getRightChildIndex(index);
int smallest = index;
if (left < heap.size() && heap[left] < heap[index]) {
smallest = left;
}
if (right < heap.size() && heap[right] < heap[smallest]) {
smallest = right;
}
if (smallest != index) {
std::swap(heap[index], heap[smallest]);
heapifyDown(smallest);
}
}
26
public:
void insert(int value) {
heap.push_back(value);
heapifyUp(heap.size() - 1);
}
void deleteMin() {
if (heap.empty()) {
std::cout << "Heap is empty\n";
return;
}
heap[0] = heap.back();
heap.pop_back();
heapifyDown(0);
}
int getMin() {
if (heap.empty()) {
std::cout << "Heap is empty\n";
return -1; // Or any appropriate value
}
return heap[0];
}
void printHeap() {
std::cout << "Heap elements: ";
for (const auto &element : heap) {
27
std::cout << element << " ";
}
std::cout << "\n";
}
};
int main() {
MinHeap minHeap;
minHeap.insert(5);
minHeap.insert(3);
minHeap.insert(8);
minHeap.insert(1);
minHeap.insert(6);
minHeap.printHeap(); // Output: Heap elements: 1 3 8 5 6
minHeap.deleteMin();
minHeap.printHeap(); // Output: Heap elements: 3 5 8 6
std::cout << "Minimum element: " << minHeap.getMin() << "\n"; // Output: Minimum
element: 3
return 0;
}
Output :
Heap elements: 1 3 8 5 6
Heap elements: 3 5 8 6
Minimum element: 3
Result:
The program has been executed successfully and the output was verified.
28
Ex.No : 6
MIN HEAP
Date :07.10.23
Aim :
To Create a CPP program for min heap.
Algorithm:
Step 1: Star the program.
Step 2: Read the array size n from the user.
Step 3: Create an array size n.
Step 4: Read the n elements to create min heap.
Step 5: Heapify the array to create Min Heap.
a.find the two childs of the first element.
Child1 = a[n/2] and child2 = a[n]
b. Like the above steps find childs to heaify the array.
Step 6: Display the result.
Step 7: Stop the program.
Source code :
#include <iostream>
#include <vector>
#include <unordered_map>
#include <cmath>
class FibonacciNode {
public:
int key;
int degree;
bool marked;
29
FibonacciNode* parent;
FibonacciNode* child;
FibonacciNode* left;
FibonacciNode* right;
FibonacciNode(int k) : key(k), degree(0), marked(false),
parent(nullptr), child(nullptr),
left(this), right(this) {}
};
class FibonacciHeap {
private:
FibonacciNode* minNode;
std::unordered_map<int, FibonacciNode*> nodeMap;
void link(FibonacciNode* y, FibonacciNode* x) {
y->left->right = y->right;
y->right->left = y->left;
y->parent = x;
if (x->child == nullptr) {
x->child = y;
y->right = y;
y->left = y;
} else {
y->left = x->child;
y->right = x->child->right;
x->child->right->left = y;
x->child->right = y;
30
}
x->degree++;
y->marked = false;
}
void consolidate() {
int maxDegree = static_cast<int>(std::log2(size()) + 1);
std::vector<FibonacciNode*> degreeTable(maxDegree, nullptr);
FibonacciNode* current = minNode;
do {
FibonacciNode* x = current;
int degree = x->degree;
while (degreeTable[degree] != nullptr) {
FibonacciNode* y = degreeTable[degree];
if (x->key > y->key) {
std::swap(x, y);
}
link(y, x);
degreeTable[degree] = nullptr;
degree++;
}
degreeTable[degree] = x;
current = current->right;
} while (current != minNode);
minNode = nullptr;
for (FibonacciNode* node : degreeTable) {
31
if (node != nullptr) {
if (minNode == nullptr || node->key < minNode->key) {
minNode = node;
}
}
}
}
public:
FibonacciHeap() : minNode(nullptr) {}
void insert(int key) {
FibonacciNode* newNode = new FibonacciNode(key);
nodeMap[key] = newNode;
if (minNode == nullptr) {
minNode = newNode;
} else {
newNode->left = minNode;
newNode->right = minNode->right;
minNode->right->left = newNode;
minNode->right = newNode;
if (key < minNode->key) {
minNode = newNode;
}
}
}
32
int getMin() {
if (isEmpty()) {
std::cerr << "Heap is empty!" << std::endl;
return -1; // or any suitable value indicating an error
}
return minNode->key;
}
int extractMin() {
if (isEmpty()) {
std::cerr << "Heap is empty!" << std::endl;
return -1; // or any suitable value indicating an error
}
FibonacciNode* z = minNode;
int minValue = z->key;
if (z->child != nullptr) {
FibonacciNode* child = z->child;
do {
FibonacciNode* nextChild = child->right;
child->left->right = child->right;
child->right->left = child->left;
child->left = minNode;
child->right = minNode->right;
minNode->right->left = child;
minNode->right = child;
child->parent = nullptr;
33
child = nextChild;
} while (child != z->child);
}
z->left->right = z->right;
z->right->left = z->left;
if (z == z->right) {
minNode = nullptr;
} else {
minNode = z->right;
consolidate();
}
nodeMap.erase(minValue);
delete z;
return minValue;
}
bool isEmpty() const {
return minNode == nullptr;
}
size_t size() const {
return nodeMap.size();
}
};
int main() {
FibonacciHeap fibHeap;
fibHeap.insert(10);
34
fibHeap.insert(7);
fibHeap.insert(25);
fibHeap.insert(3);
std::cout << "Minimum element in the heap: " << fibHeap.getMin() << std::endl;
int extractedMin = fibHeap.extractMin();
std::cout << "Extracted minimum element: " << extractedMin << std::endl;
std::cout << "New minimum element in the heap: " << fibHeap.getMin() << std::endl;
return 0;
}
Output:
Minimum element in the heap: 3
Extracted minimum element: 3
New minimum element in the heap: 7
Result:
The program has been executed successfully and the output was verified.
35
Ex.No :7
Date :09.10.23
Aim:
To create a program to perform insertion in a fibonacci heap.
Algorithm :
Step 1: Start the program.
Step 2: create the Node with parent, child, left, right pointers
Step 3: Create a new node ‘x’.
Step 4: Check whether heap H is empty or not.
Step 5: If H is empty then:
• Make x as the only node in the root list.
• Set H(min) pointer to x.
Step 6: Else:
• Insert x into root list and update H(min)
Step 7: Verify the results.
Step 8: Stop the program.
Source code :
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
class Graph {
int V;
vector<vector<int>> adj;
public:
36
Graph(int vertices) : V(vertices), adj(vertices) {}
void addEdge(int v, int w) {
adj[v].push_back(w); // Add w to v’s list
}
void DFSUtil(int v, unordered_set<int>& visited) {
visited.insert(v); // Mark the current node as visited
cout << v << " ";
for (int i : adj[v]) {
if (visited.find(i) == visited.end()) {
DFSUtil(i, visited); // Recur for all the vertices adjacent to this vertex
}
}
}
void DFS(int v) {
unordered_set<int> visited;
DFSUtil(v, visited);
}
};
int main() {
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
37
g.addEdge(3, 3);
cout << "Depth-First Traversal (starting from vertex 2): ";
g.DFS(2);
cout << endl;
return 0;
}
Output :
Depth-First Traversal (starting from vertex 2): 2 0 1 3
Result:
The program has been executed successfully and the output was verified.
38
Ex.No :8
Date : 11.10.23
Aim :
To implement a program to perform depth first search and breath first search
Algorithm :
Step 1:Start the program.
Step 2: SET STATUS = 1 (ready state) for each node in G
Step 3: Push the starting node A on the stack and set its STATUS = 2 (waiting
state)
Step 4: Repeat Steps 4 and 5 until STACK is empty
Step 5: Pop the top node N. Process it and set its STATUS = 3 (processed state)
Step 6: Push on the stack all the neighbour’s of N that are in the ready state
(whose STATUS=1) and set their
STATUS = 2 (waiting state)
[END OF LOOP]
Step 7: EXIT
Step 8: verify the result
Source code :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge {
int src, dest, weight;
};
class Graph {
39
int V;
vector<Edge> edges;
public:
Graph(int vertices) : V(vertices) {}
void addEdge(int src, int dest, int weight) {
Edge edge = {src, dest, weight};
edges.push_back(edge);
}
int findParent(vector<int>& parent, int i) {
if (parent[i] == -1)
return i;
return findParent(parent, parent[i]);
}
void unionSets(vector<int>& parent, int x, int y) {
int xroot = findParent(parent, x);
int yroot = findParent(parent, y);
parent[xroot] = yroot;
}
void KruskalMST() {
vector<Edge> result(V - 1);
int e = 0; // Index variable for sorted edges
int i = 0; // Index variable for result[]
sort(edges.begin(), edges.end(), [](Edge const& a, Edge const& b) {
return a.weight < b.weight;
40
});
int main() {
int V = 4;
Graph g(V);
g.addEdge(0, 1, 10);
g.addEdge(0, 2, 6);
g.addEdge(0, 3, 5);
41
g.addEdge(1, 3, 15);
g.addEdge(2, 3, 4);
g.KruskalMST();
return 0;
}
Result:
The program has been executed successfully and the output was verified.
42
EX.NO : 9
DATE : 16.10.23
ALGORITHM
Aim :
To implement a cpp program for prim’s algorithm.
Algorithm :
Step 1: Start the program.
Step 2: We start from one vertex and keep adding edges with the lowest
weight until we reach our goal.
Step 3:The steps for implementing Prim's algorithm are as follows:
1. Initialize the minimum spanning tree with a vertex chosen at random.
2. Find all the edges that connect the tree to new vertices, find the minimum
and add it to the tree.
3. Keep repeating step 2 until we get a minimum spanning tree
Step 4: Verify the results.
Step 5: Stop the Program.
Program :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge {
int src, dest, weight;
};
43
class Graph {
int V;
vector<Edge> edges;
public:
Graph(int vertices) : V(vertices) {}
void addEdge(int src, int dest, int weight) {
Edge edge = {src, dest, weight};
edges.push_back(edge);
}
int findParent(vector<int>& parent, int i) {
if (parent[i] == -1)
return i;
return findParent(parent, parent[i]);
}
void unionSets(vector<int>& parent, int x, int y) {
int xroot = findParent(parent, x);
int yroot = findParent(parent, y);
parent[xroot] = yroot;
}
void KruskalMST() {
vector<Edge> result(V - 1);
int e = 0; // Index variable for sorted edges
int i = 0; // Index variable for result[]
sort(edges.begin(), edges.end(), [](Edge const& a, Edge const& b) {
return a.weight < b.weight;
44
});
vector<int> parent(V, -1);
while (i < V - 1 && e < edges.size()) {
Edge next_edge = edges[e++];
int x = findParent(parent, next_edge.src);
int y = findParent(parent, next_edge.dest);
if (x != y) {
result[i++] = next_edge;
unionSets(parent, x, y);
}
}
cout << "Edges in the Minimum Spanning Tree:\n";
for (i = 0; i < V - 1; ++i) {
cout << result[i].src << " - " << result[i].dest << " : " << result[i].weight <<
endl;
}
}
};
int main() {
int V = 4;
Graph g(V);
g.addEdge(0, 1, 10);
g.addEdge(0, 2, 6);
g.addEdge(0, 3, 5);
g.addEdge(1, 3, 15);
g.addEdge(2, 3, 4);
45
g.KruskalMST();
return 0;
}
Output :
Edges in the Minimum Spanning Tree:
2-3:4
0-3:5
0 - 1 : 10
Result:
The program has been executed successfully and the output was verified.
46
Ex No :10)A)
DIJKSTRA ALGORITHM
Date :18.10.23
Aim:
To create a program to find the shortest path from the given gaph.
Algorithm :
Step 1 : Start the program.
Step 2 : Create a set sptSet (shortest path tree set) that keeps track of vertices
included
in the shortest-path tree, i.e., whose minimum distance from the source is
calculated and finalized.
Step 3 : Initially, this set is empty.
Step 4: Assign a distance value to all vertices in the input graph. Initialize all
distance
values as INFINITE. Assign distance value as 0 for the source vertex so that it
is picked first.
Step 5: For every adjacent vertex v, if the sum of distance value of u (from
source)
and weight of edge u-v, is less than the distance value of v, then update the
distance value of v.
Program :
#include <iostream>
#include <vector>
#include <queue>
#include <limits>
using namespace std;
class Graph {
int V;
vector<vector<pair<int, int>>> adj;
public:
Graph(int vertices) : V(vertices), adj(vertices) {}
void addEdge(int src, int dest, int weight) {
47
adj[src].push_back({dest, weight});
adj[dest].push_back({src, weight}); // For undirected graphs
}
void dijkstraShortestPath(int src) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
vector<int> dist(V, INF);
pq.push({0, src});
dist[src] = 0;
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
for (const auto& neighbor : adj[u]) {
int v = neighbor.first;
int weight = neighbor.second;
if (dist[v] > dist[u] + weight) {
dist[v] = dist[u] + weight;
pq.push({dist[v], v});
}
}
}
cout << "Shortest distances from source " << src << " to other vertices:\n";
for (int i = 0; i < V; ++i) {
cout << "Vertex " << i << ": " << dist[i] << endl;
}
}};
48
int main() {
int V = 5;
Graph g(V);
g.addEdge(0, 1, 4);
g.addEdge(0, 2, 2);
g.addEdge(1, 2, 5);
g.addEdge(1, 3, 10);
g.addEdge(2, 3, 3);
g.addEdge(3, 4, 4);
int source = 0; // Source vertex for shortest path calculation
g.dijkstraShortestPath(source);
return 0;
}
Output :
Shortest distances from source 0 to other vertices:
Vertex 0: 0
Vertex 1: 4
Vertex 2: 2
Vertex 3: 5
Vertex 4: 9
Result:
The program has been executed successfully and the output was verified.
49
EX.NO : 10)B)
DATE :18.10.23
Aim:
To implement a CPP program for Bellman and Ford algorithm.
Algorithm:
Step 1: Start the Program.
Step 2: Initialize distances from the source to all vertices as infinite and
distance to
the source itself as 0.
Step 3: for each edge a->b of the graph If dis[b] > dis[a] + weight of edge (a->b)
then
dis[b] = dis[a] + weight of edge (a->b)
1. repeat step 2 for nv-1 times (nv is no. of vertices).
2.If dis[b] > dis[a] + weight of edge (a->b) then report a negative cycle
in the graph.
Step 4: Display the results.
Step 5: stop the program.
Program :
#include <iostream>
#include <vector>
#include <limits>
using namespace std;
struct Edge {
int src, dest, weight;};
class Graph {
int V, E;
vector<Edge> edges;
50
public:
Graph(int vertices, int edgesCount) : V(vertices), E(edgesCount) {}
void addEdge(int src, int dest, int weight) {
Edge edge = {src, dest, weight};
edges.push_back(edge);
}
void bellmanFordShortestPath(int src) {
vector<int> dist(V, INF);
dist[src] = 0;
for (int i = 1; i <= V - 1; ++i) {
for (const auto& edge : edges) {
int u = edge.src;
int v = edge.dest;
int weight = edge.weight;
if (dist[u] != INF && dist[u] + weight < dist[v]) {
dist[v] = dist[u] + weight;
}
}
}
cout << "Shortest distances from source " << src << " to other vertices:\n";
for (int i = 0; i < V; ++i) {
cout << "Vertex " << i << ": " << dist[i] << endl;
}
}};
51
int main() {
int V = 5; // Number of vertices
int E = 8; // Number of edges
Graph g(V, E);
g.addEdge(0, 1, 4);
g.addEdge(0, 2, 2);
g.addEdge(1, 2, 5);
g.addEdge(1, 3, 10);
g.addEdge(2, 3, 3);
g.addEdge(3, 4, 4);
g.addEdge(4, 1, -6);
int source = 0; // Source vertex for shortest path calculation
g.bellmanFordShortestPath(source);
return 0;
}
Output :
Shortest distances from source 0 to other vertices:
Vertex 0: 0
Vertex 1: 3
Vertex 2: 2
Vertex 3: 5
Vertex 4: 9
Result:
The program has been executed successfully and the output was verified.
52
Ex No :11
Date :25.10.23
Aim:
To create a program to find out minimum cost of multiplication between N –
Matrices.
Algorithm:
Step 1 : Start the Program .
Step 2 : To find the minimum number of operations needed to multiply the matrices,
we need to derive some formula.
Step 3 : Each matrix can only multiply with its adjacent matrix, a prefix can only
start
from A1 to some matrix Ak, and a suffix can only start from A(k+1) to An,
split at some index k.
Step 4 : The resultant dimensions from multiplying 2 matrices are important to find
the cost.
Step 5 : In a sequence of matrices Ai . . . Aj .If we split at a point k, the
resultant
dimensions of the prefix is ri * ck and the suffix is r(k+1) * cj. The cost of
multiplying these 2 matrices are therefore ri * ck * cj.
FORMULA : C[I,J] = MIN(C[I,K]+C[K+1,J]+(DI-1 * DK * DJ))
Step 6 : return DP[1][n] as the least cost.
Source code :
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int matrixChainOrder(const vector<int>& dims) {
int n = dims.size();
vector<vector<int>> dp(n, vector<int>(n, 0));
53
for (int len = 2; len < n; ++len) {
for (int i = 1; i < n - len + 1; ++i) {
int j = i + len - 1;
dp[i][j] = INT_MAX;
for (int k = i; k < j; ++k) {
int cost = dp[i][k] + dp[k + 1][j] + dims[i - 1] * dims[k] * dims[j];
if (cost < dp[i][j]) {
dp[i][j] = cost;
}}
}}
return dp[1][n - 1];
}
int main() {
vector<int> dims = {10, 30, 5, 60}; // Dimensions of matrices
int minOperations = matrixChainOrder(dims);
cout << "Minimum number of scalar multiplications: " << minOperations << endl;
return 0;
}
Output :
Minimum number of scalar multiplications: 4500
Result:
The program has been executed successfully and the output was verified.
54
EX.NO :12)
DATE :28.10.23
Aim:
To implement a program for Activity selection.
Algorithm:
Step 1: Start the program.
Step 2: Sort the given activities in ascending order according to their finishing
time.
Step 3: Select the first activity from sorted array act[] and add it to sol[]
array.
Step 4: Repeat steps 4 and 5 for the remaining activities in act[].
Step 5: If the start time of the currently selected activity is greater than or
equal to the
finish time of previously selected activity, then add it to the sol[] array.
Step 6: Display the results.
Step 7: Verify the results.
Step 8: Stop the program.
Source code :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Activity {
int start, finish;
};
bool activityCompare(const Activity& a, const Activity& b) {
return (a.finish < b.finish);
55
}
void printMaxActivities(vector<Activity>& activities) {
sort(activities.begin(), activities.end(), activityCompare);
int n = activities.size();
cout << "Selected activities: ";
int i = 0;
cout << "(" << activities[i].start << ", " << activities[i].finish << ") ";
for (int j = 1; j < n; j++) {
if (activities[j].start >= activities[i].finish) {
cout << "(" << activities[j].start << ", " << activities[j].finish << ") ";
i = j;
}
}}
int main() {
vector<Activity> activities = {{1, 4}, {3, 5}, {0, 6}, {5, 7}, {3, 8}, {5, 9}, {6,
10}, {8,
11}, {8, 12}, {2, 13}, {12, 14}};
printMaxActivities(activities);
return 0;
}
Output:
Selected activities: (1, 4) (5, 7) (8, 11) (12, 14)
Result:
The program has been executed successfully and the output was verified.
56
Ex.No:13
Date: 01.11.23
Aim:
To write a c++ program to implement Push Heap and Pop Heap.
Algorithm:
Step 1. Create an empty vector heap and initialize it with {33, 43, 53, 38, 28}.
Step 2. Convert the vector into a heap using the make_heap function.
Step 3. Display the top element of the heap as "Top element before insert".
Step 4. Add an element (60) to the heap.
Step 5. Rearrange the heap to maintain the heap property using push_heap.
Step 6. Display the new top element of the heap as "Top element after insert".
Step 7. Remove the top element from the heap.
Step 8. Rearrange the heap after removal using pop_heap.
Step 9. Delete the last element from the vector (since it was the top element).
Step 10. Display the new top element of the heap as "Top element after deletion".
Step 11. Exit.
Program :
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> heap = {33, 43, 53, 38, 28};
make_heap(heap.begin(), heap.end());
57
cout << "Top element before insert: " << heap.front() << endl;
heap.push_back(60);
push_heap(heap.begin(), heap.end());
cout << "Top element after insert: " << heap.front() << endl;
pop_heap(heap.begin(), heap.end());
heap.pop_back();
cout << "Top element after deletion: " << heap.front() << endl;
return 0;
}
Output:
Top element before insert: 53
Top element after insert: 60
Top element after deletion: 53
Result:
The program has been executed successfully and the output was verified.
58
Ex.No:14
Date: 04.11.23
GREEDY STRATEGY
Aim:
To implement the activity selection problem using a greedy strategy.
Algorithm:
Step 1.Sort the activities based on their finish times in ascending order.
Step 2.Initialize an empty set to store the selected activities.
Step 3.Select the first activity and add its index to the set.
Step 4.For each remaining activity, if its start time is greater than or equal to
the finish
time of the previously selected activity, add its index to the set.
Step 5.Repeat step 4 until the set contains at most four activities or all
activities are
considered.
Source code :
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void activitySelection(int start[], int finish[], int n, int k) {
vector<pair<int, int>> activities;
for (int i = 0; i < n; ++i) {
activities.push_back({i, finish[i]}); }
sort(activities.begin(), activities.end(), [](const auto &a, const auto &b) {
return a.second < b.second;
});
vector<int> selectedActivities;
int prevFinishTime = -1;
59
for (const auto &activity : activities) {
int index = activity.first;
if (start[index] >= prevFinishTime) {
selectedActivities.push_back(index);
prevFinishTime = finish[index];
}
Output:
Selected Activities: 0 1 3 4
Result:
The program has been executed successfully and the output was verified.
60
Ex.No:15
BUBBLE SORT
Date: 06.11.23
Aim:
To write a c++ program for Sort an array using the Bubble Sort algorithm.
Algorithm:
Step 1. Start from the first element and compare it with the next element.
Step 2. If the first element is greater than the next element, swap them.
Step 3. Move to the next pair of elements and repeat step 2.
Step 4. Continue this process for each pair of adjacent elements until the end of
the
array.
Step 5. Repeat steps 1-4 until the entire array is sorted.
Source code :
#include <iostream>
using namespace std;
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
void bubbleSort(int arr[], int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
}
61
}
}
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Original array: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
bubbleSort(arr, n);
cout << "\nSorted array: ";
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
return 0;
}
Output:
Original array: 64 34 25 12 22 11 90
Sorted array: 11 12 22 25 34 64 90
Result:
The program has been executed successfully and the output was verified.
62
Ex.No:16
INSERTION SORT
Date: 15.11.23
Aim:
To write a c++ program for Sort an array using the Insertion Sort algorithm.
Algorithm:
Step 1. Start from the second element (assuming the first element is already
sorted).
Step 2. Compare the current element with the sorted part of the array and insert it
at
the correct position.
Step 3.Move to the next unsorted element and repeat step 2 until the entire array
is
sorted.
Source code :
#include <iostream>
using namespace std;
void insertionSort(intarr[], int n) {
inti, key, j;
for (i = 1; i< n; i++) {
key = arr[i];
j = i - 1;
while (j >= 0 &&arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
63
}
int main() {
intarr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
cout<< "Original array: ";
for (inti = 0; i< n; i++) {
cout<<arr[i] << " ";
}
insertionSort(arr, n);
cout<< "\nSorted array: ";
for (inti = 0; i< n; i++) {
cout<<arr[i] << " ";
}
return 0;
}
Output:
Original array: 64 34 25 12 22 11 90
Sorted array: 11 12 22 25 34 64 90
Result:
The program has been executed successfully and the output was verified.
64
Ex.No:17
Date: 20.11.23
Aim:
To implement Matrix Chain Multiplication using Dynamic Programming.
Algorithm:
Step 1. Create a matrix m[][] to store the minimum number of scalar multiplications
for multiplying chains of matrices.
Step 2. Create a matrix s[][] to store the optimal positions for parenthesis.
Step 3. Iterate through the chains of matrices to calculate the minimum number of
multiplications required using dynamic programming.
Step 4. Return the minimum number of scalar multiplications and the optimal
parenthesis configuration.
Source code :
#include <iostream>
#include <climits>
using namespace std;
void matrixChainOrder(int p[], int n) {
int m[n][n];
int s[n][n];
for (int i = 1; i < n; i++)
m[i][i] = 0;
for (int l = 2; l < n; l++) {
for (int i = 1; i < n - l + 1; i++) {
int j = i + l - 1;
m[i][j] = INT_MAX;
for (int k = i; k <= j - 1; k++) {
65
int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
cout << "Minimum number of scalar multiplications: " << m[1][n - 1] << endl;
}
int main() {
int arr[] = {30, 35, 15, 5, 10, 20, 25}; // Example matrix chain dimensions:
(30x35),
(35x15), (15x5), (5x10), (10x20), (20x25)
int size = sizeof(arr) / sizeof(arr[0]);
matrixChainOrder(arr, size);
return 0;
}
Output:
Minimum number of scalar multiplications: 15125
Result:
The program has been executed successfully and the output was verified.
66
Ex.No:18
Date: 22.11.23
Aim:
To implement greedy algorithm to find the minimum number of coins.
Algorithm:
Step 1. Sorting the available coin denominations in descending order.
Step 2. Then iterates through the sorted coins.
Step 3. The minimum number of coins needed to make change for the given amount.
Source code :
#include <bits/stdc++.h>
using namespace std;
int denomination[]
= { 1, 2, 5, 10, 20, 50, 100, 500, 1000 };
int n = sizeof(denomination) / sizeof(denomination[0]);
void findMin(int V)
{
sort(denomination, denomination + n);
vector<int> ans;
for (int i = n - 1; i >= 0; i--) {
while (V >= denomination[i]) {
V -= denomination[i];
ans.push_back(denomination[i]);
}
}
67
for (int i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
}
int main()
{
int n = 99;
cout << "Following is minimal"
<< " number of change for " << n << ": ";
findMin(n);
return 0;
Output:
Following is minimal number of change for 99: 50 20 20 5 2 2
Result:
The program has been executed successfully and the output was verified.
68
Ex.No:19
Date: 25.11.23
Aim:
To write a c++ program to represent graph using adjacency list.
Algorithm:
Step 1 : Define the structure with Node and Graph.
Step 2 : Connect vertices in the graph.
Step 3 : Displays the adjacency list.
Step 4 : Create the main class and add Graph initialization, list setup and
specified
Edges.
Step 5 : Connecting specified vertices.
Step 6 : Prints connected vertices based on added edges.
Source code :
#include <iostream>
#include <vector>
using namespace std;
struct Node {
int vertex;
Node* next;
};
struct Graph {
int numVertices;
vector<Node*> adjacencyList;
};
void addEdge(Graph* graph, int src, int dest) {
69
Node* newNode = new Node;
newNode->vertex = dest;
newNode->next = graph->adjacencyList[src];
graph->adjacencyList[src] = newNode;
}
void printGraph(Graph* graph) {
for (int i = 0; i < graph->numVertices; ++i) {
Node* temp = graph->adjacencyList[i];
cout << "Vertex " << i << ": ";
while (temp) {
cout << temp->vertex << " ";
temp = temp->next;
}
cout << endl;
}
}
int main() {
Graph* graph = new Graph;
graph->numVertices = 5;
graph->adjacencyList.resize(graph->numVertices);
addEdge(graph, 0, 1);
addEdge(graph, 0, 4);
addEdge(graph, 1, 2);
addEdge(graph, 1, 3);
addEdge(graph, 1, 4);
70
addEdge(graph, 2, 3);
addEdge(graph, 3, 4);
printGraph(graph);
return 0;
}
Output:
Vertex 0: 4 1
Vertex 1: 4 3 2
Vertex 2: 3
Vertex 3: 4
Vertex 4:
Result:
The program has been executed successfully and the output was verified.
71
Ex.No:20
Date: 27.11.23
Aim:
To write a c++ program to find shortest distances between every pair of vertices in
a
given edge weighted directed graph using Floyd warshall algorithm.
Algorithm:
STEP1: Create a matrix A of dimension n*n where n is the number of vertices. The
row and the column are indexed as I and j respectively.
STEP2: Now create a matrix A1 using matrix A. the elements in the first column and
the first row are left as they are. Let k be the immediate vertex in the shortest
path from source to the destination.
STEP3: similarly A2 is created using A1. The elements in the second column and the
second row are left as they are. STEP4: similarly A3 and A4 also created.
STEP5: A4 gives the shortest path between each pair of vertices.
Source code :
#include <iostream>
using namespace std;
#define nV 4
#define INF 999
void printMatrix(int matrix[][nV]);
72
for (k = 0; k < nV; k++) {
for (i = 0; i < nV; i++) {
for (j = 0; j < nV; j++) {
if (matrix[i][k] + matrix[k][j] < matrix[i][j])
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
}
}
printMatrix(matrix);
}
int main() {
int graph[nV][nV] = {{0, 3, INF, 5},
73
{2, 0, INF, 4},
{INF, 1, 0, INF},
{INF, INF, 2, 0}};
floydWarshall(graph);
}
Output:
0 3 7 5
2 0 6 4
3 1 0 5
5 3 2 0
Result:
The program has been executed successfully and the output was verified.
74
Ex.No:21
Date: 29.11.23
Aim:
Write a C++ program for implementation to sort the given matrix.
Algorithm:
Step 1. Let flatMatrix be an empty 1D array.
Step 2. Append all elements of the row to flatMatrix.
Step 3. Sort flatMatrix in non-decreasing order.
Step 4. Let sortedMatrix be an empty 2D array.
Step 5. Append the next len(matrix[0]) elements of flatMatrix to sortedMatrix.
Step 6. Return sortedMatrix.
Source code :
#include <iostream>
#define SIZE 10
void sortMat(int mat[SIZE][SIZE], int n) {
for (int i = 0; i < n * n - 1; i++) {
for (int j = 0; j < n * n - i - 1; j++) {
if (mat[j / n][j % n] > mat[(j + 1) / n][(j + 1) % n]) {
int temp = mat[j / n][j % n];
mat[j / n][j % n] = mat[(j + 1) / n][(j + 1) % n];
mat[(j + 1) / n][(j + 1) % n] = temp; } } }}
void printMat(int mat[SIZE][SIZE], int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
75
std::cout << mat[i][j] << " ";
std::cout << std::endl; } }
int main() {
int mat[SIZE][SIZE] = {
{5, 4, 7},
{1, 3, 8},
{2, 9, 6} };
int n = 3;
std::cout << "Original Matrix:" << std::endl;
printMat(mat, n);
sortMat(mat, n);
std::cout << "Matrix After Sorting:" << std::endl;
printMat(mat, n);
return 0; }
Output:
Original Matrix:
547
138
296
Matrix After Sorting:
123
456
789
Result:
The program has been executed successfully and the output was verified.
76
Ex.No:22
Date: 06.12.23
Aim:
To write a c++ program execute sorting using Heap algorithm.
Algorithm:
Step 1. Start a program with defining a heap function.
Step 2. Convert the array into a max heap by calling heapify on non-leaf nodes from
the last to the first.
Step 3. Ensures a subtree rooted at index i maintains the max heap property by
comparing the element with its children and swapping if necessary.
Step 4. Start by building a max heap.
Step 5. Repeatedly extract the maximum element (root) by swapping it with the last
element.
Step 6. Reduce the heap size by one and perform heapify to maintain the max heap
property.
Step 7. Continue until the entire array is sorted.
Source code :
#include <iostream>
#include <algorithm>
void heapify(int arr[], int n, int i)
{
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest])
largest = left;
77
if (right < n && arr[right] > arr[largest])
largest = right;
if (largest != i) {
std::swap(arr[i], arr[largest]);
heapify(arr, n, largest);
}
}
void heapSort(int arr[], int n)
{
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
for (int i = n - 1; i > 0; i--) {
std::swap(arr[0], arr[i]);
heapify(arr, i, 0);
}
}
void printArray(int arr[], int n)
{
for (int i = 0; i < n; ++i)
std::cout << arr[i] << " ";
std::cout << "\n";
}
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
78
int n = sizeof(arr) / sizeof(arr[0]);
std::cout << "Original array: \n";
printArray(arr, n);
heapSort(arr, n);
std::cout << "Sorted array: \n";
printArray(arr, n);
return 0;
}
Output:
Original array:
12 11 13 5 6 7
Sorted array:
5 6 7 11 12 13
Result:
The program has been executed successfully and the output was verified.
79
Ex.No:23
Date: 11.12.23
Aim :
Write a C++ program to find factorial of a given number using Recursion.
Algorithm:
Step 1: Take an integer input as the number for which the factorial needs to be
calculated.
Step 2: If the input number is 0 or 1, return 1 (base case of factorial).
Step 3: Otherwise, recursively call the function with (n-1) until the base case is
reached.
Step 4: Multiply the current number n with the factorial of (n-1).
Source code :
#include <iostream>
using namespace std;
unsigned long long factorial(unsigned int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
int main() {
80
unsigned int number;
cout << "Enter a number to find its factorial: ";
cin >> number;
if (number < 0) {
cout << "Factorial is not defined for negative numbers.";
}
else {
unsigned long long result = factorial(number);
cout << "Factorial of " << number << " is: " << result;
}
return 0;
}
Output:
Enter a number to find its factorial: 5
Factorial of 5 is: 120
Result:
The program has been executed successfully and the output was verified.
81
Ex.No:24
Date: 13.12.23
Aim :
To write a C++ program to find factorial of a number without Recursion.
Algorithm:
Step 1. Take an integer input as the number for which the factorial needs to be
calculated.
Step 2. Initialize a variable to store the factorial result as 1.
Step 3. Use a loop structure (like a for loop) starting from 1 up to the input
number.
Step 4. Multiply the current value of the factorial result by the loop index in
each
iteration.
Step 5. Continue the loop until the loop index reaches the input number.
Source code :
#include <iostream>
using namespace std;
unsigned long long factorial(unsigned int n) {
unsigned long long result = 1;
for (unsigned int i = 1; i <= n; ++i) {
result *= i;
}
return result;
}
82
int main() {
unsigned int number;
cout << "Enter a number to find its factorial: ";
cin >> number;
if (number < 0) {
cout << "Factorial is not defined for negative numbers.";
} else {
unsigned long long result = factorial(number);
cout << "Factorial of " << number << " is: " << result;
}
return 0;
}
Output :
Result:
The program has been executed successfully and the output was verified.
83
Ex NO.25
Date : 18.12.23
Aim:
Find the longest common subsequence for the given two strings.
Algorithm:
Step 1. Create a 2D array dp to store subproblem solutions.
Step 2. Fill the dp array by comparing characters in both strings and updating
based
on matching characters.
Step 3. Trace back through dp to construct the LCS string.
Step 4. The constructed string represents the Longest Common Subsequence.
Step 5. O(m * n), where m and n are the lengths of the input strings.
Step 6. O(m * n) for the 2D array dp, accommodating subproblem solutions.
Source code :
#include <iostream>
#include <vector>
using namespace std;
string findLCS(const string& str1, const string& str2) {
int m = str1.length();
int n = str2.length();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (str1[i - 1] == str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1; }
84
else { dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}} }
return lcs; }
int main() {
string str1 = "stone";
string str2 = "longest";
string lcs = findLCS(str1, str2);
cout << "Longest Common Subsequence: " << lcs << endl;
return 0; }
Output:
Longest Common Subsequence : one
Result:
The program has been executed successfully and the output was verified.
85
Ex.No:26
Date: 20.12.23
Aim :
To write a c++ program for Prime number generator .
Algorithm :
Step 1. Initialize a boolean array `isPrime` of size `limit + 1`, marking all
numbers as
prime initially.
Step 2. Start a loop from `p = 2` up to `p * p <= limit`.
Step 3. Inside the loop, if `isPrime[p]` is true:
Step 4. Mark all multiples of `p` starting from `p * p` up to `limit` as not prime
by
setting ‘isPrime[i] = false`.
Step 5. After the loop, display prime numbers up to the given limit by iterating
through the array `isPrime` and printing numbers where `isPrime[p]` is true.
Step 6. End the program.
Source code :
#include <iostream>
#include <vector>
void sieveOfEratosthenes(int limit) {
std::vector<bool> isPrime(limit + 1, true);
for (int p = 2; p * p <= limit; ++p) {
if (isPrime[p] == true) {
for (int i = p * p; i <= limit; i += p)
isPrime[i] = false;
86
}
}
std::cout << "Prime numbers up to " << limit << " are:\n";
for (int p = 2; p <= limit; ++p) {
if (isPrime[p])
std::cout << p << " ";
}
std::cout << "\n";
}
int main() {
int n;
std::cout << "Enter the limit to generate prime numbers: ";
std::cin >> n;
sieveOfEratosthenes(n);
return 0;
}
Output :
Enter the limit to generate prime numbers: 60
Prime numbers up to 60 are:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59
Result:
The program has been executed successfully and the output was verified.
87
Ex.No:27
Date: 23.12.23
DIRECTED GRAPH
Aim :
To write a c++ program to find if there is a path between two vertices in a
directed graph.
Algorithm :
Step 1 : Initialize the number of vertices and an adjacency list.
Step 2 : Add edges to the graph by updating the adjacency list.
Step 3 : Use DFS recursively to check if there is a path between two vertices.
Step 4: Initialize a visited array and call the private `isReachable` function.
Step 5: Create a graph, add edges, and specify source and destination vertices.
Step 6: Using the `isPath` function, determine if a path exists between the
specified
vertices and print the result.
Source Code :
#include <iostream>
#include <vector>
using namespace std;
class Graph {
int V;
vector<vector<int>> adj;
bool isReachable(int src, int dest, vector<bool>& visited) {
if (src == dest)
return true;
88
visited[src] = true;
for (int i = 0; i < adj[src].size(); ++i) {
if (!visited[adj[src][i]] && isReachable(adj[src][i], dest, visited))
return true;
}
return false;
}
public:
Graph(int vertices) {
V = vertices;
adj.resize(V);
}
int main() {
89
Graph graph(4);
graph.addEdge(0, 1);
graph.addEdge(0, 2);
graph.addEdge(1, 2);
graph.addEdge(2, 0);
graph.addEdge(2, 3);
graph.addEdge(3, 3);
return 0;
}
Output :
There is a path from 1 to 3
Result:
The program has been executed successfully and the output was verified.
90
Ex No . 28
Date : 27.12.23
IN A BINARY SEARCH
AIM:
To implement a function that searches for a specified key element in a Binary
Search
Tree (BST).
ALGORITHM:
Step 1.Check If the current node is null, the key is not found; return false.
Step 2 .If the key matches the current node's data, return true.
Step 3 .The key is less than the current node's data, recursively search in the
left subtree.
Step 4 .If the key is greater than the current node's data, recursively search in
the right
subtree.
Step 5 .Return the result of the recursive search, indicating whether the key is
present in
the Binary Search Tree.
SOURCE CODE:
#include <iostream>
struct TreeNode {
int data;
TreeNode* left;
TreeNode* right;
TreeNode(int value) : data(value), left(nullptr), right(nullptr) {}
};
bool search(TreeNode* root, int key) {
if (root == nullptr || root->data == key) {
return root != nullptr; }
91
if (key < root->data) {
return search(root->left, key);
} else {
return search(root->right, key);
}}
int main() {
TreeNode* root = new TreeNode(50);
root->left = new TreeNode(30);
root->right = new TreeNode(70);
root->left->left = new TreeNode(20);
root->left->right = new TreeNode(40);
root->right->left = new TreeNode(60);
root->right->right = new TreeNode(80);
int keyToSearch = 40;
if (search(root, keyToSearch)) {
std::cout << "Key " << keyToSearch << " found in the BST." << std::endl;
} else {
std::cout << "Key " << keyToSearch << " not found in the BST." << std::endl; }
return 0; }
OUTPUT:
Key 40 found in the BST.
Result:
The program has been executed successfully and the output was verified.
92