ADSA Practical
ADSA Practical
Aim:
To write a C++ program to implement Binary Search using Recursive and Non
recursive function
Procedure:
Step 1: Start the program.
Step 5: In the main() function define a sorted array and calculate its size. Prompt the user to
input the target element to search. Call the binarySearchRecursive() function and store the
result. Print the index if the element is found or a "not found" message if it isn't. Call the
binarySearchNonRecursive() function and store the result. Print the index if the element is
found or a "not found" message if it isn't.
Program:
#include <iostream>
using namespace std;
int binarySearchRecursive(int arr[], int left, int right, int target) {
if (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target)
return mid;
if (arr[mid] > target)
return binarySearchRecursive(arr, left, mid - 1, target);
return binarySearchRecursive(arr, mid + 1, right, target);
}
return -1;
}
int binarySearchNonRecursive(int arr[], int size, int target) {
int left = 0, right = size - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target)
return mid;
if (arr[mid] > target)
right = mid - 1;
else
left = mid + 1;
}
return -1; // Target not found
}
int main() {
int arr[] = {2, 4, 6, 8, 10, 12, 14};
int size = sizeof(arr) / sizeof(arr[0]);
int target;
cout << "Enter the element to search: ";
cin >> target;
int resultRecursive = binarySearchRecursive(arr, 0, size - 1, target);
if (resultRecursive != -1)
cout << "Element found at index (Recursive): " << resultRecursive << endl;
else
cout << "Element not found (Recursive)" << endl;
int resultNonRecursive = binarySearchNonRecursive(arr, size, target);
if (resultNonRecursive != -1)
cout << "Element found at index (Non-Recursive): " << resultNonRecursive << endl;
else
cout << "Element not found (Non-Recursive)" << endl;
return 0;
}
Output:
2. (A) TO IMPLEMENT THE MERGE SORT
Aim:
Procedure:
Step 1: Start the program.
Step 2: Define a function merge() that merges two sorted sub-arrays into a single sorted array.
Create two temporary arrays leftArray[] and rightArray[] to hold elements of the left and right
subarrays. Compare elements of the two arrays and copy the smaller element back to the
original array. Copy any remaining elements from leftArray[] and rightArray[] to the original
array.
Step 3: Define a function mergeSort() that divides the array into two halves recursively. Check
if left < right (the array has more than one element). Find the middle index mid. Call
mergeSort() on the left half of the array. Call mergeSort() on the right half of the array. Call
the merge() function to combine the two sorted halves.
Step 4: In the main() function define an unsorted array arr[].calculate the size of the array.
Print the original unsorted array. Call the mergeSort() function with the array and its start (left
= 0) and end (right = n-1) indices. Print the sorted array.
Program:
#include <iostream>
using namespace std;
void merge(int a[], int l, int m, int r) {
int b[r - l + 1], i = l, j = m + 1, k = 0;
while (i <= m && j <= r) b[k++] = (a[i] < a[j]) ? a[i++] : a[j++];
while (i <= m) b[k++] = a[i++];
while (j <= r) b[k++] = a[j++];
for (i = l, k = 0; i <= r; i++) a[i] = b[k++];
}
void mergeSort(int a[], int l, int r) {
if (l < r) {
int m = (l + r) / 2;
mergeSort(a, l, m);
mergeSort(a, m + 1, r);
merge(a, l, m, r);
}
}
int main() {
int n;
cout << "Enter number of elements: ";
cin >> n;
int a[n];
cout << "Enter elements: ";
for (int i = 0; i < n; i++) cin >> a[i];
mergeSort(a, 0, n - 1);
cout << "Sorted: ";
for (int i = 0; i < n; i++) cout << a[i] << " ";
}
Output:
2. (B) TO IMPLEMENT THE HEAPSORT
Aim:
Procedure:
Step 1: Start the program.
Step 2: Define a function heapify that ensures the heap property is maintained for a sub tree
Input: Array arr[], size n, and index i.
b) Find the largest value among the current node, left child, and right child.
c) If the largest value is not the current node, swap it with the largest child and calls
heapify recursively for the affected sub tree.
Step 3: Define the heap Sort function build a max heap from the input array by calling heapify
on all non-leaf nodes, starting from the bottom. For sorting swap the root (maximum element)
with the last element of the array. Reduce the heap size and call heapify on the root to maintain
the heap property.
Step 4: Define the print Array function to display the contents of the array.
Program:
#include <iostream>
#include <vector>
using namespace std;
void heapify(vector<int>& arr, int n, int i) {
int largest = i, l = 2 * i + 1, r = 2 * i + 2;
if (l < n && arr[l] > arr[largest]) largest = l;
if (r < n && arr[r] > arr[largest]) largest = r;
if (largest != i) { swap(arr[i], arr[largest]); heapify(arr, n, largest); }
}
void heapSort(vector<int>& arr) {
for (int i = arr.size() / 2 - 1; i >= 0; i--) heapify(arr, arr.size(), i);
for (int i = arr.size() - 1; i > 0; i--) { swap(arr[0], arr[i]); heapify(arr, i, 0); }
}
int main() {
int n;
cout << "Enter number of elements: ";
cin >> n;
vector<int> arr(n);
cout << "Enter elements: ";
for (int i = 0; i < n; i++) cin >> arr[i];
heapSort(arr);
cout << "Sorted array: ";
for (int i = 0; i < n; i++) cout << arr[i] << " ";
return 0;
}
Output:
3. TO PERFORM IN-ORDER RECURSIVE TRAVERSAL OF BINARY TREE
Aim:
Procedure:
Step 1: Start the Program.
Step 2: Define the structure Node to represent the nodes of a binary tree. Each node contains
an integer data to store the value of the node. Two pointers left and right to point to the left and
right child nodes, respectively.
Step 3: Create a Constructor for the Node Initialize the data with the given value Set left and
right to NULL.
Step 4: Create a function inOrderTraversal(Node* root) that performs the in-order traversal of
the binary tree. If the root is NULL, return (base case). Recursively call the function for the
left sub tree. Print the data value of the current node. Recursively call the function for the right
sub tree.
Step 5: Create the root node using the constructor: Node* root = new Node (1). Add left and
right child nodes to the root using the constructor. Continue adding child nodes for the left and
right children recursively to build the tree.
Step 6: Call the inOrderTraversal function with the root node to display the elements of the
binary tree in in-order.
Program:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
Node(int value) {
data = value;
left = NULL;
right = NULL;
}
};
void inOrderTraversal(Node* root) {
if (root == NULL) {
return;
}
inOrderTraversal(root->left);
cout << root->data << " ";
inOrderTraversal(root->right);
}
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 << "In-order Traversal: ";
inOrderTraversal(root);
cout << endl;
return 0;
}
Output:
4. FIND PATH BETWEEN TWO VERTICES IN A DIRECTED GRAPH
Aim:
To Write a C++ program to find if there is a path between two vertices in a Directed
graph.
Procedure:
Step 1: Start the program.
Step 2: Define the structure Node to represent a tree node with data, left, and right pointers.
Step 3: Create the function newNode(data) to allocate memory for a new node and initialize
its values.
Step 7: In the main() function build the binary tree using newNode() and Call
countFibonacciPathsWrapper (root) to compute the number of Fibonacci paths. Print the
result.
Program:
#include <iostream>
#include <vector>
using namespace std;
bool dfs(int current, int target, vector<vector<int> >& adj, vector<bool>& visited) {
if (current == target) {
return true; // Path found
}
visited[current] = true;
for (int i = 0; i < adj[current].size(); i++) {
int neighbor = adj[current][i];
if (!visited[neighbor]) {
if (dfs(neighbor, target, adj, visited)) {
return true;
}
}
}
return false;
}
int main() {
int vertices, edges;
cout << "Enter the number of vertices: ";
cin >> vertices;
cout << "Enter the number of edges: ";
cin >> edges;
vector<vector<int> > adj(vertices);
cout << "Enter the edges (from to):" << endl;
for (int i = 0; i < edges; i++) {
int from, to;
cin >> from >> to;
adj[from].push_back(to);
adj[to].push_back(from); // Add this line to make the graph undirected
}
int start, end;
cout << "Enter the start and end vertices: ";
cin >> start >> end;
vector<bool> visited(vertices, false);
USING RECURSION
Aim:
To write a C++ program to count a number of Fibonacci paths present in a binary tree
using recursion
Procedure:
Step 1: Start the program.
Step 4: For each edge, read the endpoints and update the adjacency list.If the graph is
undirected, add edges in both directions.
Step 5: Read the start and end vertices for the path search.
Step 7: Define a recursive Depth First Search (DFS) function. Check if the current vertex
matches the target. Mark the current vertex as visited. Recursively visit all unvisited
neighbors. If a path is found during recursion, return true.
Step 9: If DFS returns true, output that a path exists between the start and end vertices.
Otherwise, output that no path exists.
Program:
#include <iostream>
using namespace std;
struct TreeNode {
int val;
TreeNode *left, *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
int dfs(TreeNode* node, int prev1, int prev2) {
if (!node) return 0;
int count = (node->val == prev1 + prev2) ? 1 : 0;
return count + dfs(node->left, prev1 + prev2, prev1) + dfs(node->right, prev1 +
prev2, prev1);
}
int countFibonacciPaths(TreeNode* root) {
if (!root) return 0;
return dfs(root, 0, root->val) + countFibonacciPaths(root->left) +
countFibonacciPaths(root->right);
}
int main() {
TreeNode* root = new TreeNode(5);
root->left = new TreeNode(3);
root->right = new TreeNode(8);
root->left->left = new TreeNode(2);
root->left->right = new TreeNode(4);
root->right->left = new TreeNode(7);
root->right->right = new TreeNode(10);
cout << "Number of Fibonacci paths: " << countFibonacciPaths(root) << endl;
return 0;
}
Output
6. TO PERFORM PRE-ORDER RECURSIVE TRAVERSAL OF BINARY TREE
Aim:
To write C++ programs that use recursive functions to traverse the given binary tree in
Preorder.
Procedure:
Step 1: Start the program.
Step 2: Define the structure Node to represent a node in the binary tree, with members data,
left, and right.
Step 3: Create a constructor for the Node structure that initializes the node’s value and sets left
and right pointers to NULL.
Step 4: Define the preorderTraversal() function that takes the root of the tree as an argument
and prints the elements in preorder.
Step 5: In preorderTraversal(), first print the root node’s data, then recursively call the
function on the left and right children.
Step 6: In the main() function, create a root node with value 1 and add child nodes to form a
binary tree.
Step 7: Call the preorderTraversal() function to print the tree nodes in preorder.
Program:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* left;
Node* right;
Node(int value) : data(value), left(NULL), right(NULL) {}
};
void preorderTraversal(Node* root) {
if (root == NULL) return;
cout << root->data << " ";
preorderTraversal(root->left);
preorderTraversal(root->right);
}
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 << "Preorder Traversal: ";
preorderTraversal(root);
cout << endl;
return 0;
}
Output:
7(A) TO INSERT AN ELEMENT IN BINARY SEARCH TREE
Aim:
Procedure:
Step 1. Start the program.
Step 2. Define the structure Node to represent the nodes of a binary search tree, which
includes data and pointers to the left and right children.
Step 3. Create a new node if the tree is empty. Recursively insert the value in the left or right
subtree based on its comparison with the current node's data.
Step 4. Traverse the left subtree, print the current node's data, and then traverse the right
subtree to display the tree in in-order.
Step 5. Initialize the root node as NULL.Insert values into the binary search tree using the
insert() function. Display the tree elements in in-order using the inorder() function.
Program:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* left = NULL;
Node* right = NULL;
Node(int value) : data(value) {}
};
Node* insert(Node* root, int value) {
if (!root) return new Node(value);
if (value < root->data) root->left = insert(root->left, value);
else root->right = insert(root->right, value);
return root;
}
void inorder(Node* root) {
if (root) {
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
}
int main() {
Node* root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 70);
cout<<"In-Order:";
inorder(root);
return 0;
}
Output:
7(b) TO DELETE AN ELEMENT IN BINARY SEARCH TREE
Aim:
Procedure:
Step 1: Start the program.
Step 2: Define a structure Node to create nodes of a Binary Search Tree (BST), initializing
data, left, and right pointers.
Step 3: Implement the insert() function to add a value to the BST at the correct position based
on its value.
Step 4: Implement the inorder() function to traverse and print the tree's elements in in-order
(left, root, right).
Step 5: Implement the minValueNode() function to find the smallest node in a given subtree.
Step 6: Implement the deleteNode() function to remove a node with the specified value,
maintaining the BST properties.
Step 8: Accept input values from the user to insert into the BST using the insert() function.
Step 10: Accept a value from the user to delete, remove it using the deleteNode() function,
and display the in-order traversal after deletion.
Program:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* left = NULL;
Node* right = NULL;
Node(int value) : data(value) {}
};
Node* insert(Node* root, int value) {
if (!root) return new Node(value);
if (value < root->data) root->left = insert(root->left, value);
else root->right = insert(root->right, value);
return root;
}
void inorder(Node* root) {
if (root) {
inorder(root->left);
cout << root->data << " ";
inorder(root->right);
}
}
Node* minValueNode(Node* node) {
Node* current = node;
while (current && current->left) current = current->left;
return current;
}
Node* deleteNode(Node* root, int value) {
if (!root) return root;
if (value < root->data) root->left = deleteNode(root->left, value);
else if (value > root->data) root->right = deleteNode(root->right, value);
else {
if (!root->left) {
Node* temp = root->right;
delete root;
return temp;
} else if (!root->right) {
Node* temp = root->left;
delete root;
return temp;
}
Node* temp = minValueNode(root->right);
root->data = temp->data;
root->right = deleteNode(root->right, temp->data);
}
return root;
}
int main() {
Node* root = NULL;
int num, value, deleteValue;
cout << "Enter the number of elements to insert into the BST: ";
cin >> num;
for (int i = 0; i < num; i++) {
cout << "Enter value to insert: ";
cin >> value;
root = insert(root, value);
}
cout << "In-order before deletion: ";
inorder(root);
cout << endl;
cout << "Enter value to delete: ";
cin >> deleteValue;
root = deleteNode(root, deleteValue);
cout << "In-order after deletion of " << deleteValue << ": ";
inorder(root);
cout << endl;
return 0;
}
Output:
7(c) TO SEARCH AN ELEMENT IN BINARY SEARCH TREE
Aim:
Procedure:
Step 1 Start the program.
Step 2 Define a structure Node to represent a binary tree node containin integer Left and right
child pointers.
Step 3: Create a new node if the current root is NULL. Recursively insert the key in the left
subtree if the key is smaller than the root's data. Recursively insert the key in the right subtree
if the key is larger than the root's data.
Step 4: Return false if the root is NULL. Return true if the root's data matches the key.
Recursively search the left subtree if the key is smaller than the root's data. Recursively search
the right subtree if the key is larger than the root's data.
Step 5: Initialize the root node as NULL. Input the number of nodes n. Insert n values into the
binary tree by calling insert(). Input the key to search. Use the search() function to check if the
key exists in the tree and display "Found" or "Not Found".
Program:
#include <iostream>
using namespace std;
struct Node {
int data;
Node* left, *right;
Node(int val) : data(val), left(NULL), right(NULL) {}
};
Node* insert(Node* root, int key) {
if (!root) return new Node(key);
if (key < root->data) root->left = insert(root->left, key);
else root->right = insert(root->right, key);
return root;
}
bool search(Node* root, int key) {
if (!root) return false;
if (root->data == key) return true;
return (key < root->data) ? search(root->left, key) : search(root->right, key);
}
int main() {
Node* root = NULL;
int n, key;
cout << "Enter number of nodes: ";
cin >> n;
cout << "Enter nodes: ";
for (int i = 0; i < n; ++i) {
int val;
cin >> val;
root = insert(root, val);
}
cout << "Enter key to search: ";
cin >> key;
cout << (search(root, key) ? "Found" : "Not Found") << endl;
return 0;
}
Output:
8. TO TRAVERSE A GRAPH USING DEPTH FIRST SEARCH.
Aim:
Procedure:
Step 1: Start the program
Step 2: Define the number of vertices (5 in this case) and create an adjacency list for the
graph.
Step 3: Add edges between vertices in the adjacency list (undirected graph)
Step 4: Define a visited array to track which nodes have been visited during DFS traversal
Step 5: Call the DFS function with the starting node (0 in this case)
Step 6: In the DFS function, mark the current node as visited and print the node
Step 7: For each adjacent node of the current node, if it is not visited, recursively call DFS for
that adjacent node
Program:
#include <iostream>
#include <vector>
using namespace std;
void DFS(int node, vector<int> adj[], bool visited[]) {
visited[node] = true;
cout << node << " ";
for (int i = 0; i < adj[node].size(); i++) {
int adjacent = adj[node][i];
if (!visited[adjacent]) {
DFS(adjacent, adj, visited);
}
}
}
int main() {
int vertices = 5;
vector<int> adj[vertices];
adj[0].push_back(1);
adj[0].push_back(2);
adj[1].push_back(0);
adj[1].push_back(3);
adj[1].push_back(4);
adj[2].push_back(0);
adj[3].push_back(1);
adj[4].push_back(1);
bool visited[vertices] = {false};
cout << "DFS Traversal: ";
DFS(0, adj, visited);
return 0;
}
Output:
9. KRUSKAL’S ALGORITHM
Aim:
To write a C++ Program to find the minimum Spanning Tree Using Kruskal’s Algorithm
Procedure:
Step 1: Start the program.
Step 2: Define a structure Edge to represent a graph edge with attributes u (start vertex), v
(end vertex), and w (weight).
Step 3: Create a comparison function cmp to sort edges based on their weights in ascending
order.
Step 4: Implement a find function to determine the root of a node using path compression.
Step 5: Define the kruskal function Sort all edges based on their weights using cmp. Initialize
a parent array to track the roots of all vertices.Iterate through sorted edges For each edge, find
the roots of its vertices using find. If the roots are different, include the edge in the MST, union
the roots, and add the edge weight to the MST weight. Print the included edge. Print the total
weight of the MST.
Step 6: Initialize the number of vertices n and edges m. Define and populate the list of edges.
Call the kruskal function to compute the MST and display the result.
Step 7: End the program.
Program:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge {
int u, v, w;
};
bool cmp(Edge a, Edge b) {
return a.w < b.w;
}
int find(int x, vector<int>& parent) {
if (parent[x] != x)
parent[x] = find(parent[x], parent);
return parent[x];
}
void kruskal(int n, vector<Edge>& edges) {
sort(edges.begin(), edges.end(), cmp);
vector<int> parent(n);
for (int i = 0; i < n; ++i)
parent[i] = i;
int mstWeight = 0;
for (size_t i = 0; i < edges.size(); ++i) {
Edge e = edges[i];
int uRoot = find(e.u, parent);
int vRoot = find(e.v, parent);
if (uRoot != vRoot) {
mstWeight += e.w;
parent[uRoot] = vRoot;
cout << e.u << " - " << e.v << " (" << e.w << ")\n";
}
}
cout << "Total weight: " << mstWeight << endl;
}
int main() {
int n = 4, m = 5;
vector<Edge> edges;
edges.push_back((Edge){0, 1, 10});
edges.push_back((Edge){0, 2, 6});
edges.push_back((Edge){0, 3, 5});
edges.push_back((Edge){1, 3, 15});
edges.push_back((Edge){2, 3, 4});
kruskal(n, edges);
return 0;
}
Output:
10. TO IMPLEMENT BELLMAN FORD ALGORITHM.
Aim:
Procedure:
Step 1: Start the program.
Step 2: Define the structure Edge with three members: src, dest, and weight.
Step 3: Input the number of vertices (V) and edges (E) from the user.
Step 4: Create an array edges[] to store the edges with their source, destination, and weight.
Step 5: Input the edges (source, destination, and weight) from the user.
Step 6: Input the source vertex for which the shortest path needs to be found.
Step 7: Initialize an array dist[] with all vertices set to INT_MAX, except the source vertex
which is set to 0.
Step 8: Run the relaxation process for (V - 1) iterations, where for each edge, check if a
shorter path exists through the edge and update dist[].
Step 9: After completing the relaxation process, check for negative weight cycles by iterating
through the edges one more time. If any distance can still be reduced, print "Graph contains
negative weight cycle" and end.
Step 10: If no negative weight cycle is found, print the shortest distance from the source
vertex to all other vertices.
Program:
#include <iostream>
#include <vector>
#include <climits>
#include <sstream>
using namespace std;
string toStr(int num) {
stringstream ss;
ss << num;
return ss.str();
}
void bellmanFord(int v, int e, vector<vector<int> >& edges, int src) {
vector<int> dist(v, INT_MAX);
dist[src] = 0;
for (int i = 0; i < v - 1; ++i) {
for (int j = 0; j < e; ++j) {
int u = edges[j][0];
int v = edges[j][1];
int w = edges[j][2];
if (dist[u] != INT_MAX && dist[u] + w < dist[v]) {
dist[v] = dist[u] + w;
}
}
}
for (int j = 0; j < e; ++j) {
int u = edges[j][0];
int v = edges[j][1];
int w = edges[j][2];
if (dist[u] != INT_MAX && dist[u] + w < dist[v]) {
cout << "Negative cycle detected\n";
return;
}
}
for (int i = 0; i < v; ++i) {
cout << "Distance to " << i << ": " << (dist[i] == INT_MAX ? "INF" :
toStr(dist[i])) << "\n";
}
}
int main() {
int v, e, src;
cout << "Enter vertices, edges: ";
cin >> v >> e;
vector<vector<int> > edges(e, vector<int>(3));
cout << "Enter edges (u v w):\n";
for (int i = 0; i < e; ++i)
cin >> edges[i][0] >> edges[i][1] >> edges[i][2];
cout << "Enter source vertex: ";
cin >> src;
bellmanFord(v, e, edges, src);
return 0;
}
Output:
11 TO IMPLEMENT RED-BLACK TREE
Aim:
Procedure:
Step 1: Start the program
Step 4: While inserting a new node, always inserted as Red node after node inserted it satisfy
all properties (i) Recolor (ii) Rotate
Step 5: While deleting a node it will disturb a Red Black tree properties if it disrupt a fixing a
algorithm is used to regain properties
Step 6: Successor node fix the R.B tree properties and refix the insertion and deletion
Step 7: Each node has color, key, left child, right child
Step 8: In rotation operation, the position of the nodes of a subtree are inter changed it is
mainly used to maintain the properties of R.B tree when they violated by other properties
Program:
#include <iostream>
#include <cstdlib>
using namespace std;
enum Color { RED, BLACK };
struct Node {
int data;
Node *left, *right, *parent;
Color color;
Node(int data) {
this->data = data;
left = right = parent = NULL;
color = RED;
}
};
class RedBlackTree {
private:
Node* root;
void leftRotate(Node* &x) {
Node* y = x->right;
x->right = y->left;
if (y->left != NULL) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == NULL) {
root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
void rightRotate(Node* &x) {
Node* y = x->left;
x->left = y->right;
if (y->right != NULL) {
y->right->parent = x;
}
y->parent = x->parent;
if (x->parent == NULL) {
root = y;
} else if (x == x->parent->right) {
x->parent->right = y;
} else {
x->parent->left = y;
}
y->right = x;
x->parent = y;
}
void fixInsertion(Node* &z) {
while (z != root && z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
Node* y = z->parent->parent->right;
if (y != NULL && y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->right) {
z = z->parent;
leftRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(z->parent->parent);
}
} else {
Node* y = z->parent->parent->left;
if (y != NULL && y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->left) {
z = z->parent;
rightRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
leftRotate(z->parent->parent);
}
}
}
root->color = BLACK;
}
void insertNode(int data) {
Node* z = new Node(data);
Node* y = NULL;
Node* x = root;
while (x != NULL) {
y = x;
if (z->data < x->data) {
x = x->left;
} else {
x = x->right;
}
}
z->parent = y;
if (y == NULL) {
root = z;
} else if (z->data < y->data) {
y->left = z;
} else {
y->right = z;
}
fixInsertion(z);
}
void inorderTraversal(Node* root) {
if (root != NULL) {
inorderTraversal(root->left);
cout << "Node: " << root->data << ", Color: " << (root->color == RED ? "RED"
: "BLACK") << endl;
inorderTraversal(root->right);
}
}
public:
RedBlackTree() {
root = NULL;
}
void insert(int data) {
insertNode(data);
}
void inorder() {
inorderTraversal(root);
}
};
int main() {
RedBlackTree tree;
tree.insert(7);
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 Red-Black Tree with Node Colors:" << endl;
tree.inorder();
cout << endl;
return 0;
}
Output:
12. DIJKSTRA'S SINGLE SOURCE SHORTEST PATH ALGORITHM
Aim:
To write a C++ program for Dijkstra's single source shortest path algorithm
Procedure:
Step 1: Start the program.
Step 2: Initialize constants for infinity and the maximum number of vertices.
Step 3: Define the dijkstra () function, which calculates the shortest paths in a graph using
Dijkstra's algorithm.
Step 4: Inside dijkstra (), initialize the arrays for distances, predecessors, and visited nodes.
Step 5: Set the distance to the start node as 0 and mark it as visited.
Step 6: Use a loop to process all nodes and find the minimum distance node that is not visited.
Step 8: After processing all nodes, print the shortest distances and paths from the start node to
each other node.
Step 9: In the main () function, prompt the user for the number of vertices.
Step 10: Accept the adjacency matrix as input and replace any zeros (no direct path) with
infinity.
Step 12: Call the dijkstra() function with the graph, number of nodes, and starting node as
arguments.
Program:
#include <iostream>
using namespace std;
const int INF = 9999;
const int MAX = 10;
void dijkstra(int G[MAX][MAX], int n, int startnode) {
int distance[n], pred[n];
bool visited[n] = {false};
fill(distance, distance + n, INF);
distance[startnode] = 0;
for (int count = 0; count < n - 1; count++) {
int mindistance = INF, nextnode = -1;
for (int i = 0; i < n; i++) {
if (!visited[i] && distance[i] < mindistance) {
mindistance = distance[i];
nextnode = i;
}
}
visited[nextnode] = true;
for (int i = 0; i < n; i++) {
if (!visited[i] && G[nextnode][i] != INF && distance[nextnode] +
G[nextnode][i] < distance[i]) {
distance[i] = distance[nextnode] + G[nextnode][i];
pred[i] = nextnode;
}
}
}
cout << "Shortest distances from source " << startnode << ":\n";
for (int i = 0; i < n; i++) {
if (i != startnode) {
cout << "Distance of node " << i << " = " << distance[i] << "\nPath = ";
for (int j = i; j != startnode; j = pred[j])
cout << j << "<-";
cout << startnode << endl;
}
}
}
int main() {
int n, G[MAX][MAX], startnode;
cout << "Enter number of vertices: ";
cin >> n;
cout << "Enter the adjacency matrix:\n";
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++) {
cin >> G[i][j];
if (G[i][j] == 0) G[i][j] = INF;
}
cout << "Enter the starting node: ";
cin >> startnode;
dijkstra(G, n, startnode);
return 0;
}
Output:
13. HUFFMAN CODING ALGORITHM
Aim:
Procedure:
Step 1: Start the program.
Step 2: Define a Node structure to represent a node in the Huffman tree. Each node contains
an item, frequency, and pointers to left and right child nodes.
Step 3: Define a Compare structure to compare two nodes based on their frequency for the
priority queue.
Step 4: The HuffmanCodes() function initializes a priority queue, where each node (character
and frequency) is pushed into the queue.
Step 5: In the HuffmanCodes() function, the two nodes with the lowest frequencies are popped
from the priority queue, merged into a new node, and pushed back into the queue. Repeat until
only one node remains in the queue.
Step 6: Call printHuffmanCodes() recursively to traverse the Huffman tree and print the
Huffman code for each character.
Step 7: The program outputs the Huffman codes for each character.
Program:
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
struct Node {
char item;
int freq;
Node* left, *right;
};
struct Compare {
bool operator()(Node* a, Node* b) {
return a->freq > b->freq;
}
};
void printHuffmanCodes(Node* root, string str) {
if (root == NULL) return;
if (root->left == NULL && root->right == NULL) {
cout << root->item << ": " << str << endl;
return;
}
printHuffmanCodes(root->left, str + "0");
printHuffmanCodes(root->right, str + "1");
}
void HuffmanCodes(char item[], int freq[], int size) {
priority_queue<Node*, vector<Node*>, Compare> pq;
for (int i = 0; i < size; i++) {
Node* newNode = new Node();
newNode->item = item[i];
newNode->freq = freq[i];
newNode->left = newNode->right = NULL;
pq.push(newNode);
}
while (pq.size() != 1) {
Node* left = pq.top();
pq.pop();
Node* right = pq.top();
pq.pop();
Node* newNode = new Node();
newNode->item = '\0';
newNode->freq = left->freq + right->freq;
newNode->left = left;
newNode->right = right;
pq.push(newNode);
}
printHuffmanCodes(pq.top(), "");
}
int main() {
char item[] = {'A', 'B', 'C', 'D'};
int freq[] = {5, 1, 6, 3};
int size = sizeof(item) / sizeof(item[0]);
cout << "Character | Huffman code" << endl;
HuffmanCodes(item, freq, size);
return 0;
}
Output:
14. TO FIND LONGEST COMMON SUBSEQUENCE
Aim:
To Write a C++ Program to find Longest Common Subsequence for the given two
string using Dynamic Programming Strategy.
Procedure:
Step 1: Start the program.
Step 4: Initialize a 2D vector dp of size (m+1) x (n+1) with all elements set to 0.
Step 5: Use a nested loop:Outer loop iterates over the characters of s1 (from 1 to m).Inner
loop iterates over the characters of s2 (from 1 to n).If characters match
(s1[i-1] == s2[j-1]), set dp[i][j] = dp[i-1][j-1] + 1.Else, set dp[i][j] = max(dp[i-1][j], dp[i][j-1]).
Step 6: After filling the dp table, the value at dp[m][n] contains the length of the longest
common subsequence (LCS).
Step 7: Define two strings s1 and s2. call the LCS function with s1 and s2 as arguments. Print
the length of the LCS.
Program:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int LCS(string s1, string s2) {
int m = s1.length(), n = s2.length();
vector<vector<int> > dp(m + 1, vector<int>(n + 1, 0)); // Added space between '>>'
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (s1[i - 1] == s2[j - 1])
dp[i][j] = dp[i - 1][j - 1] + 1;
else
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
return dp[m][n];
}
int main() {
string s1 = "stone", s2 = "longest";
cout << "Length of LCS: " << LCS(s1, s2) << endl;
return 0;
}
Output:
15. ACTIVITY SELECTION PROBLEM USING GREEDY STRATEGY
Aim:
Procedure:
Step 1: Start the program.
Step 2: Define the activitySelection function, which takes start times, finish times, and the
number of activities as input.
Step 6: Check if the start time of the current activity is greater than or equal to the finish time
of the last selected activity.
Step 7: If the condition is true, select the current activity by printing its index and updating i to
the current index.
Step 8: End the loop after all activities have been checked.
Step 9: In the main function, define the start and finish times of activities and call the
activitySelection function.
Program:
#include <iostream>
using namespace std;
void activitySelection(int start[], int finish[], int n) {
int i = 0;
cout << "Selected activities: " << i << " ";
for (int j = 1; j < n; j++) {
if (start[j] >= finish[i]) {
cout << j << " ";
i = j;
}
}
}
int main() {
int start[] = {1, 3, 0, 5, 8, 5};
int finish[] = {2, 4, 6, 7, 9, 9};
int n = 6;
activitySelection(start, finish, n);
return 0;
}
Output: