Cp4161 Ads Lab Manual
Cp4161 Ads Lab Manual
Semester - I
Regulation 2021
0042
OBJECTIVES:
To acquire the knowledge of using advanced tree structures
To learn the usage of heap structures
To understand the usage of graph structures and spanning trees
To understand the problems such as matrix chain multiplication, activity selection
and Huffman coding
To understand the necessary mathematical abstraction to solve problems.
LIST OF EXPERIMENTS:
1: Implementation of recursive function for tree traversal and Fibonacci
2: Implementation of iteration function for tree traversal and Fibonacci
3: Implementation of Merge Sort and Quick Sort
4: Implementation of a Binary Search Tree
5: Red-Black Tree Implementation
6: Heap Implementation
7: Fibonacci Heap Implementation
8: Graph Traversals
9: Spanning Tree Implementation
10: Shortest Path Algorithms (Dijkstra's algorithm, Bellman Ford Algorithm)
11: Implementation of Matrix Chain Multiplication
12: Activity Selection and Huffman Coding Implementation
HARDWARE/SOFTWARE REQUIREMENTS
1. 64-bit Open source Linux or its derivative
2. Open Source C++ Programming tool like G++/GCC
TOTAL : 60 PERIODS
COURSE OUTCOMES:
CO1: Design and implement basic and advanced data structures extensively
CO2: Design algorithms using graph structures
CO3: Design and develop efficient algorithms with minimum complexity using design
techniques
CO4: Develop programs using various algorithms.
CO5: Choose appropriate data structures and algorithms, understand the ADT/libraries, and
use it to design algorithms for a specific problem.
REFERENCES:
1. Lipschutz Seymour, “Data Structures Schaum's Outlines Series”, Tata McGraw Hill, 3rd Edition,
2014.
2. Alfred V. Aho, John E. Hopcroft, Jeffrey D. Ullman, “Data Structures and Algorithms”, Pearson
Education, Reprint 2006.
3. http://www.coursera.org/specializations/data-structures-algorithms
4. http://www.tutorialspoint.com/data_structures_algorithms
5. http://www.geeksforgeeks.org/data-structures
1.a : Recursive Function for Tree traversal
Aim:
To Traverse a Binary Search Tree using Recursive Function
Algorithm:
There are three ways which we use to traverse a tree −
1. In-order Traversal
2. Pre-order Traversal
3. Post-order Traversal
1. In-order Traversal
Algorithm
Until all nodes are traversed −
Step 1 − Recursively traverse left subtree.
Step 2 − Visit root node.
Step 3 − Recursively traverse right subtree.
2. Pre-order Traversal
Algorithm
Until all nodes are traversed −
Step 1 − Visit root node.
Step 2 − Recursively traverse left subtree.
Step 3 − Recursively traverse right subtree.
3. Post-order Traversal
Algorithm
Until all nodes are traversed −
Step 1 − Recursively traverse left subtree.
Step 2 − Recursively traverse right subtree.
Step 3 − Visit root node.
Program
#include<iostream>
using namespace std;
struct node {
int data;
struct node *left;
struct node *right;
};
struct node *createNode(int val) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = val;
temp->left = temp->right = NULL;
return temp;
}
void inorder(struct node *root) {
if (root != NULL) {
inorder(root->left);
cout<<root->data<<" ";
inorder(root->right);
}
}
struct node* insertNode(struct node* node, int val) {
if (node == NULL) return createNode(val);
if (val < node->data)
node->left = insertNode(node->left, val);
else if (val > node->data)
node->right = insertNode(node->right, val);
return node;
}
int main() {
struct node *root = NULL;
root = insertNode(root, 4);
insertNode(root, 5);
insertNode(root, 2);
insertNode(root, 9);
insertNode(root, 1);
insertNode(root, 3);
cout<<"In-Order traversal of the Binary Search Tree is: ";
inorder(root);
return 0;
}
Output
In-Order traversal of the Binary Search Tree is: 1 2 3 4 5 9
1.b : Recursive Function for Fibonacci
Aim
To implement a Fibonacci Series using Recursive Function
Algorithm
Step 1 : Start
Step 2 : int f0, f1, fib
Step 3 : f0 = 0
Step 4 : f1 = 1
Step 5 : display f0, f1
Step 6 : for int i := 1 to n:
Step 7 : fib := f0 + f1
Step 8 : f0 := f1
Step 9 : f1 := fib
Step 10 : display fib
Step 11 : END for loop
Step : END
Program
#include <iostream>
using namespace std;
int fib(int x) {
if((x==1)||(x==0)) {
return(x);
}else {
return(fib(x-1)+fib(x-2));
}
}
int main() {
int x , i=0;
cout << "Enter the number of terms of series : ";
cin >> x;
cout << "\nFibonnaci Series : ";
while(i < x) {
cout << " " << fib(i);
i++;
}
return 0;
}
Output
Enter the number of terms of series : 15
Fibonnaci Series : 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
2.a : Iteration Function for Tree Traversal
Aim
To implement a Tree Traversal using Iteration
Algorithm
1) Create an empty stack S.
2) Initialize current node as root
3) Push the current node to S and set current = current->left until current is NULL
4) If current is NULL and stack is not empty then
a) Pop the top item from stack.
b) Print the popped item, set current = popped_item->right
c) Go to step 3.
5) If current is NULL and stack is empty then we are done.
Program
#include <iostream>
using namespace std;
Node(int data)
{
this->data = data;
this->left = this->right = nullptr;
}
};
// Recursive function to perform inorder traversal on the tree
void inorder(Node* root)
{
// return if the current node is empty
if (root == nullptr) {
return;
}
int main()
{
/* Construct the following tree
1
/ \
/ \
2 3
/ / \
/ / \
4 5 6
/\
/ \
7 8
*/
inorder(root);
return 0;
}
OUTPUT
Inorder
4 2 1 7 5 8 3 6
2.b : Iteration Function for Fibonacci
Aim
To implement a Fibonacci Series using Iteration Function
Algorithm
Step 1 : Start
Step 2 : int f0, f1, fib
Step 3 : f0 = 0
Step 4 : f1 = 1
Step 5 : display f0, f1
Step 6 : for int i := 1 to n:
Step 7 : fib := f0 + f1
Step 8 : f0 := f1
Step 9 : f1 := fib
Step 10 : display fib
Step 11 : END for loop
Step 12: END
Program
#include <iostream>
using namespace std;
void fib(int num) {
int x = 0, y = 1, z = 0;
for (int i = 0; i < num; i++) {
cout << x << " ";
z = x + y;
x = y;
y = z;
}
}
int main() {
int num;
cout << "Enter the number : ";
cin >> num;
cout << "\nThe fibonacci series : " ;
fib(num);
return 0;
}
Output
Enter the number : 10
The fibonacci series : 0 1 1 2 3 5 8 13 21 34
3a. Implementation of Merge Sort analysis
AIM:
ALGORITHM:
1. If the list has only one element, return the list and terminate.
2. Split the list into two halves that are as equal in length as possible
3. Using recursion, sort both lists using mergesort.
4. Merge the two sorted lists and return the result.
5. Stop the program.
PROGRAM :
#include <iostream>
int main()
{
int n, i;
cout<<"\nEnter the number of data element to be sorted: ";
cin>>n;
int arr[n];
for(i = 0; i < n; i++)
{
cout<<"Enter element "<<i+1<<": ";
cin>>arr[i];
}
MergeSort(arr, 0, n-1);
return 0;
}
3b. Implementation of Quick Sort analysis
AIM:
ALGORITHM:
1. An array is divided into subarrays by selecting a pivot element (element selected from
the array).
While dividing the array, the pivot element should be positioned in such a way that
elements less than pivot are kept on the left side and elements greater than pivot are on
the right side of the pivot.
2. The left and right subarrays are also divided using the same approach. This process
continues until each subarray contains a single element.
3. At this point, elements are already sorted. Finally, elements are combined to form a
sorted array.
PROGRAM :
// Quick sort in C++
#include <iostream>
using namespace std;
// function to swap elements
void swap(int *a, int *b) {
int t = *a;
*a = *b;
*b = t;
}
// function to print the array
void printArray(int array[], int size) {
int i;
for (i = 0; i < size; i++)
cout << array[i] << " ";
cout << endl;
}
// function to rearrange array (find the partition point)
int partition(int array[], int low, int high) {
// select the rightmost element as pivot
int pivot = array[high];
AIM:
ALGORITHM:
1. Read the search element from the user
2. Compare, the search element with the value of root node in the tree.
3. If both are matching, then display "Given node found!!!" and terminate the function
4. If both are not matching, then check whether search element is smaller or larger than that
node value.
5. If search element is smaller, then continue the search process in left subtree.
6. If search element is larger, then continue the search process in right subtree.
7. Repeat the same until we found exact element or we completed with a leaf node
8. If we reach to the node with search value, then display "Element is found" and terminate
the function.
9. If we reach to a leaf node and it is also not matching, then display "Element not found"
and terminate the function.
PROGRAM :
// Binary Search Tree operations in C++
#include <iostream>
using namespace std;
struct node {
int key;
struct node *left, *right;
};
// Create a node
struct node *newNode(int item) {
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
// Inorder Traversal
void inorder(struct node *root) {
if (root != NULL) {
// Traverse left
inorder(root->left);
// Traverse root
cout << root->key << " -> ";
// Traverse right
inorder(root->right);
}
}
// Insert a node
struct node *insert(struct node *node, int key) {
// Return a new node if the tree is empty
if (node == NULL) return newNode(key);
return node;
}
return current;
}
// Deleting a node
struct node *deleteNode(struct node *root, int key) {
// Return if the tree is empty
if (root == NULL) return root;
AIM:
To write a java program to implement Red-Black Tree.
ALGORITHM:
1. Check whether tree is Empty.
2. If tree is Empty then insert the newNode as Root node with color Black and exit from the
operation.
3. If tree is not Empty then insert the newNode as a leaf node with Red color.
4. If the parent of newNode is Black then exit from the operation.
5. If the parent of newNode is Red then check the color of parent node's sibling of newNode.
6. If it is Black or NULL node then make a suitable Rotation and Recolor it.
7. If it is Red colored node then perform Recolor and Recheck it. Repeat the same until tree
becomes Red Black Tree.
PROGRAM:
// Implementing Red-Black Tree in C++
#include <iostream>
using namespace std;
struct Node {
int data;
Node *parent;
Node *left;
Node *right;
int color;
};
typedef Node *NodePtr;
class RedBlackTree {
private:
NodePtr root;
NodePtr TNULL;
void initializeNULLNode(NodePtr node, NodePtr parent) {
node->data = 0;
node->parent = parent;
node->left = nullptr;
node->right = nullptr;
node->color = 0;
}
// Preorder
void preOrderHelper(NodePtr node) {
if (node != TNULL) {
cout << node->data << " ";
preOrderHelper(node->left);
preOrderHelper(node->right);
}
}
// Inorder
void inOrderHelper(NodePtr node) {
if (node != TNULL) {
inOrderHelper(node->left);
cout << node->data << " ";
inOrderHelper(node->right);
}
}
// Post order
void postOrderHelper(NodePtr node) {
if (node != TNULL) {
postOrderHelper(node->left);
postOrderHelper(node->right);
cout << node->data << " ";
}
}
s->color = x->parent->color;
x->parent->color = 0;
s->right->color = 0;
leftRotate(x->parent);
x = root;
}
} else {
s = x->parent->left;
if (s->color == 1) {
s->color = 0;
x->parent->color = 1;
rightRotate(x->parent);
s = x->parent->left;
}
s->color = x->parent->color;
x->parent->color = 0;
s->left->color = 0;
rightRotate(x->parent);
x = root;
}
}
}
x->color = 0;
}
if (z == TNULL) {
cout << "Key not found in the tree" << endl;
return;
}
y = z;
int y_original_color = y->color;
if (z->left == TNULL) {
x = z->right;
rbTransplant(z, z->right);
} else if (z->right == TNULL) {
x = z->left;
rbTransplant(z, z->left);
} else {
y = minimum(z->right);
y_original_color = y->color;
x = y->right;
if (y->parent == z) {
x->parent = y;
} else {
rbTransplant(y, y->right);
y->right = z->right;
y->right->parent = y;
}
rbTransplant(z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
delete z;
if (y_original_color == 0) {
deleteFix(x);
}
}
if (u->color == 1) {
u->color = 0;
k->parent->color = 0;
k->parent->parent->color = 1;
k = k->parent->parent;
} else {
if (k == k->parent->right) {
k = k->parent;
leftRotate(k);
}
k->parent->color = 0;
k->parent->parent->color = 1;
rightRotate(k->parent->parent);
}
}
if (k == root) {
break;
}
}
root->color = 0;
}
public:
RedBlackTree() {
TNULL = new Node;
TNULL->color = 0;
TNULL->left = nullptr;
TNULL->right = nullptr;
root = TNULL;
}
void preorder() {
preOrderHelper(this->root);
}
void inorder() {
inOrderHelper(this->root);
}
void postorder() {
postOrderHelper(this->root);
}
NodePtr searchTree(int k) {
return searchTreeHelper(this->root, k);
}
NodePtr successor(NodePtr x) {
if (x->right != TNULL) {
return minimum(x->right);
}
NodePtr y = x->parent;
while (y != TNULL && x == y->right) {
x = y;
y = y->parent;
}
return y;
}
NodePtr predecessor(NodePtr x) {
if (x->left != TNULL) {
return maximum(x->left);
}
NodePtr y = x->parent;
while (y != TNULL && x == y->left) {
x = y;
y = y->parent;
}
return y;
}
void leftRotate(NodePtr x) {
NodePtr y = x->right;
x->right = y->left;
if (y->left != TNULL) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == nullptr) {
this->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(NodePtr x) {
NodePtr y = x->left;
x->left = y->right;
if (y->right != TNULL) {
y->right->parent = x;
}
y->parent = x->parent;
if (x->parent == nullptr) {
this->root = y;
} else if (x == x->parent->right) {
x->parent->right = y;
} else {
x->parent->left = y;
}
y->right = x;
x->parent = y;
}
// Inserting a node
void insert(int key) {
NodePtr node = new Node;
node->parent = nullptr;
node->data = key;
node->left = TNULL;
node->right = TNULL;
node->color = 1;
NodePtr y = nullptr;
NodePtr x = this->root;
while (x != TNULL) {
y = x;
if (node->data < x->data) {
x = x->left;
} else {
x = x->right;
}
}
node->parent = y;
if (y == nullptr) {
root = node;
} else if (node->data < y->data) {
y->left = node;
} else {
y->right = node;
}
if (node->parent == nullptr) {
node->color = 0;
return;
}
if (node->parent->parent == nullptr) {
return;
}
insertFix(node);
}
NodePtr getRoot() {
return this->root; }
void deleteNode(int data) {
deleteNodeHelper(this->root, data);
}
void printTree() {
if (root) {
printHelper(this->root, "", true); }
}
};
int main() {
RedBlackTree bst;
bst.insert(55);
bst.insert(40);
bst.insert(65);
bst.insert(60);
bst.insert(75);
bst.insert(57);
bst.printTree();
cout << endl
<< "After deleting" << endl;
bst.deleteNode(40);
bst.printTree(); }
6. HEAP IMPLEMENTATION
AIM:
To write a java program for heap implement
ALGORITHM:
1. Call the buildMaxHeap() function on the list. Also referred to as heapify(), this builds a
heap from a list in O(n) operations.
2. Swap the first element of the list with the final element. Decrease the considered range of
the list by one.
3. Call the siftDown() function on the list to sift the new first element to its appropriate index
in the heap.
4. Go to step (2) unless the considered range of the list is one element.
5. The buildMaxHeap() operation is run once, and is O(n) in performance. The siftDown()
function is O(log n), and is called n times. Therefore, the performance of this algorithm is
O(n + n log n) = O(n log n).
PROGRAM :
Heapify(array, size, i)
set i as largest
leftChild = 2i + 1
rightChild = 2i + 2
#include <iostream>
#include <vector>
using namespace std;
if (largest != i)
{
swap(&hT[i], &hT[largest]);
heapify(hT, largest);
}
}
void insert(vector<int> &hT, int newNum)
{
int size = hT.size();
if (size == 0)
{
hT.push_back(newNum);
}
else
{
hT.push_back(newNum);
for (int i = size / 2 - 1; i >= 0; i--)
{
heapify(hT, i);
}
}
}
void deleteNode(vector<int> &hT, int num)
{
int size = hT.size();
int i;
for (i = 0; i < size; i++)
{
if (num == hT[i])
break;
}
swap(&hT[i], &hT[size - 1]);
hT.pop_back();
for (int i = size / 2 - 1; i >= 0; i--)
{
heapify(hT, i);
}
}
void printArray(vector<int> &hT)
{
for (int i = 0; i < hT.size(); ++i)
cout << hT[i] << " ";
cout << "\n";
}
int main()
{
vector<int> heapTree;
insert(heapTree, 3);
insert(heapTree, 4);
insert(heapTree, 9);
insert(heapTree, 5);
insert(heapTree, 2);
deleteNode(heapTree, 4);
printArray(heapTree);
}
7. FIBONACCI HEAP IMPLEMENTATION
AIM:
To write a java program for Fibonacci heap implement.
ALGORITHM:
1. Call the buildMinHeap() function on the list.
2. insert(x) inserts a node x into the heap.
3. minimum() returns the node in the heap with minimum key.
4. extractMin() deletes the node with minimum key from the heap.
5. union(H) merge heap H and create a new one.
6. decreaseKey(x,k) assigns to node x within the heap the new key value k, which is assumed
to be no greater than its current key value.
7. delete(x) deletes node x from the heap.
PROGRAM :
// Operations on a Fibonacci heap in C++
#include <cmath>
#include <cstdlib>
#include <iostream>
// Node creation
struct node {
int n;
int degree;
node *parent;
node *child;
node *left;
node *right;
char mark;
char C;
};
public:
node *InitializeHeap();
int Fibonnaci_link(node *, node *, node *);
node *Create_node(int);
node *Insert(node *, node *);
node *Union(node *, node *);
node *Extract_Min(node *);
int Consolidate(node *);
int Display(node *);
node *Find(node *, int);
int Decrease_key(node *, int, int);
int Delete_key(node *, int);
int Cut(node *, node *, node *);
int Cascase_cut(node *, node *);
FibonacciHeap() { H = InitializeHeap(); }
};
// Initialize heap
node *FibonacciHeap::InitializeHeap() {
node *np;
np = NULL;
return np;
}
// Create node
node *FibonacciHeap::Create_node(int value) {
node *x = new node;
x->n = value;
return x;
}
// Insert node
node *FibonacciHeap::Insert(node *H, node *x) {
x->degree = 0;
x->parent = NULL;
x->child = NULL;
x->left = x;
x->right = x;
x->mark = 'F';
x->C = 'N';
if (H != NULL) {
(H->left)->right = x;
x->right = H;
x->left = H->left;
H->left = x;
if (x->n < H->n)
H = x;
} else {
H = x;
}
nH = nH + 1;
return H;
}
// Create linking
int FibonacciHeap::Fibonnaci_link(node *H1, node *y, node *z) {
(y->left)->right = y->right;
(y->right)->left = y->left;
if (z->right == z)
H1 = z;
y->left = y;
y->right = y;
y->parent = z;
if (z->child == NULL)
z->child = y;
y->right = z->child;
y->left = (z->child)->left;
((z->child)->left)->right = y;
(z->child)->left = y;
// Union Operation
node *FibonacciHeap::Union(node *H1, node *H2) {
node *np;
node *H = InitializeHeap();
H = H1;
(H->left)->right = H2;
(H2->left)->right = H;
np = H->left;
H->left = H2->left;
H2->left = np;
return H;
}
do {
cout << p->n;
p = p->right;
if (p != H) {
cout << "-->";
}
} while (p != H && p->right != NULL);
cout << endl;
}
// Extract min
node *FibonacciHeap::Extract_Min(node *H1) {
node *p;
node *ptr;
node *z = H1;
p = z;
ptr = z;
if (z == NULL)
return z;
node *x;
node *np;
x = NULL;
if (z->child != NULL)
x = z->child;
if (x != NULL) {
ptr = x;
do {
np = x->right;
(H1->left)->right = x;
x->right = H1;
x->left = H1->left;
H1->left = x;
if (x->n < H1->n)
H1 = x;
x->parent = NULL;
x = np;
} while (np != ptr);
}
(z->left)->right = z->right;
(z->right)->left = z->left;
H1 = z->right;
else {
H1 = z->right;
Consolidate(H1);
}
nH = nH - 1;
return p;
}
// Consolidation Function
int FibonacciHeap::Consolidate(node *H1) {
int d, i;
float f = (log(nH)) / (log(2));
int D = f;
node *A[D];
node *x = H1;
node *y;
node *np;
node *pt = x;
do {
pt = pt->right;
d = x->degree;
{
y = A[d];
{
np = x;
x = y;
y = np;
}
if (y == H1)
H1 = x;
Fibonnaci_link(H1, y, x);
if (x->right == x)
H1 = x;
A[d] = NULL;
d = d + 1;
}
A[d] = x;
x = x->right;
while (x != H1);
H = NULL;
for (int j = 0; j <= D; j++) {
if (A[j] != NULL) {
A[j]->left = A[j];
A[j]->right = A[j];
if (H != NULL) {
(H->left)->right = A[j];
A[j]->right = H;
A[j]->left = H->left;
H->left = A[j];
if (A[j]->n < H->n)
H = A[j];
} else {
H = A[j];
}
if (H == NULL)
H = A[j];
else if (A[j]->n < H->n)
H = A[j];
}
}
}
if (ptr->n < k) {
cout << "Entered key greater than current key" << endl;
return 0;
}
ptr->n = k;
y = ptr->parent;
if (y != NULL && ptr->n < y->n) {
Cut(H1, ptr, y);
Cascase_cut(H1, y);
}
return 0;
}
// Cutting Function
int FibonacciHeap::Cut(node *H1, node *x, node *y)
{
if (x == x->right)
y->child = NULL;
(x->left)->right = x->right;
(x->right)->left = x->left;
if (x == y->child)
y->child = x->right;
y->degree = y->degree - 1;
x->right = x;
x->left = x;
(H1->left)->right = x;
x->right = H1;
x->left = H1->left;
H1->left = x;
x->parent = NULL;
x->mark = 'F';
}
// Cascade cut
int FibonacciHeap::Cascase_cut(node *H1, node *y) {
node *z = y->parent;
if (z != NULL) {
if (y->mark == 'F') {
y->mark = 'T';
} else
{
Cut(H1, y, z);
Cascase_cut(H1, z);
}
}
}
// Search function
node *FibonacciHeap::Find(node *H, int k) {
node *x = H;
x->C = 'Y';
node *p = NULL;
if (x->n == k) {
p = x;
x->C = 'N';
return p;
}
if (p == NULL) {
if (x->child != NULL)
p = Find(x->child, k);
if ((x->right)->C != 'Y')
p = Find(x->right, k);
}
x->C = 'N';
return p;
}
// Deleting key
int FibonacciHeap::Delete_key(node *H1, int k) {
node *np = NULL;
int t;
t = Decrease_key(H1, k, -5000);
if (!t)
np = Extract_Min(H);
if (np != NULL)
cout << "Key Deleted" << endl;
else
cout << "Key not Deleted" << endl;
return 0;
}
int main() {
int n, m, l;
FibonacciHeap fh;
node *p;
node *H;
H = fh.InitializeHeap();
p = fh.Create_node(7);
H = fh.Insert(H, p);
p = fh.Create_node(3);
H = fh.Insert(H, p);
p = fh.Create_node(17);
H = fh.Insert(H, p);
p = fh.Create_node(24);
H = fh.Insert(H, p);
fh.Display(H);
p = fh.Extract_Min(H);
if (p != NULL)
cout << "The node with minimum key: " << p->n << endl;
else
cout << "Heap is empty" << endl;
m = 26;
l = 16;
fh.Decrease_key(H, m, l);
m = 16;
fh.Delete_key(H, m);
}
8. GRAPH TRAVERSALS
AIM:
To write a java program to implement Graph Traversals using Depth First Search tree
algorithm.
ALGORITHM:
1. Start at some node, and is now our current node.
2. State that our current node is ‘visited’.
3. Now look at all nodes adjacent to our current node.
4. If we see an adjacent node that has not been ‘visited’, add it to the stack.
5. Then pop of the top node on the stack and traverse to it.
6. And go back to step 1.
PROGRAM :
// BFS algorithm in C++
#include <iostream>
#include <list>
class Graph {
int numVertices;
list<int>* adjLists;
bool* visited;
public:
Graph(int vertices);
void addEdge(int src, int dest);
void BFS(int startVertex);
};
// BFS algorithm
void Graph::BFS(int startVertex) {
visited = new bool[numVertices];
for (int i = 0; i < numVertices; i++)
visited[i] = false;
list<int> queue;
visited[startVertex] = true;
queue.push_back(startVertex);
list<int>::iterator i;
while (!queue.empty()) {
int currVertex = queue.front();
cout << "Visited " << currVertex << " ";
queue.pop_front();
for (i = adjLists[currVertex].begin(); i != adjLists[currVertex].end(); ++i) {
int adjVertex = *i;
if (!visited[adjVertex]) {
visited[adjVertex] = true;
queue.push_back(adjVertex); } } } }
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);
g.addEdge(3, 3);
g.BFS(2);
return 0;
}}
9a. SPANNING TREE IMPLEMENTATION (KRUSKAL’S)
AIM:
To write a java program to implement Spanning tree implementation using kruskal’s
algorithm.
ALGORITHM:
1. Create a graph F (a set of trees), where each vertex in the graph is a separate tree.
2. Step:create a set S containing all the edges in the graph.
3. While S is nonempty and F is not yet spanning.
3.1. Remove an edge with minimum weight from S.
`3.2. If the removed edge connects two different trees then add it to the forest F,
combining two trees into a single tree.
PROGRAM :
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;
public class KruskalAlgorithm
{
private List<Edge> edges;
private int numberOfVertices;
public static final int MAX_VALUE = 999;
private int visited[];
private int spanning_tree[][];
public KruskalAlgorithm(int numberOfVertices)
{
this.numberOfVertices = numberOfVertices;
edges = new LinkedList<Edge>();
visited = new int[this.numberOfVertices + 1];
spanning_tree = new int[numberOfVertices + 1][numberOfVertices + 1];
}
public void kruskalAlgorithm(int adjacencyMatrix[][])
{
boolean finished = false;
for (int source = 1; source <= numberOfVertices; source++)
{
for (int destination = 1; destination <= numberOfVertices; destination++)
{
if (adjacencyMatrix[source][destination] != MAX_VALUE && source != destination)
{
Edge edge = new Edge();
edge.sourcevertex = source;
edge.destinationvertex = destination;
edge.weight = adjacencyMatrix[source][destination];
adjacencyMatrix[destination][source] = MAX_VALUE;
edges.add(edge);
}
}
}
Collections.sort(edges, new EdgeComparator());
CheckCycle checkCycle = new CheckCycle();
for (Edge edge : edges)
{
spanning_tree[edge.sourcevertex][edge.destinationvertex] = edge.weight;
spanning_tree[edge.destinationvertex][edge.sourcevertex] = edge.weight;
if (checkCycle.checkCycle(spanning_tree, edge.sourcevertex))
{
spanning_tree[edge.sourcevertex][edge.destinationvertex] = 0;
spanning_tree[edge.destinationvertex][edge.sourcevertex] = 0;
edge.weight = -1;
continue;
}
visited[edge.sourcevertex] = 1;
visited[edge.destinationvertex] = 1;
for (int i = 0; i < visited.length; i++)
{
if (visited[i] == 0)
{
finished = false;
break;
} else
{
finished = true;
}
}
if (finished)
break;
}
System.out.println("The spanning tree is ");
for (int i = 1; i <= numberOfVertices; i++)
System.out.print("\t" + i);
System.out.println();
for (int source = 1; source <= numberOfVertices; source++)
{
System.out.print(source + "\t");
for (int destination = 1; destination <= numberOfVertices; destination++)
{
System.out.print(spanning_tree[source][destination] + "\t");
}
System.out.println();
}
}
public static void main(String... arg)
{
int adjacency_matrix[][];
int number_of_vertices;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of vertices");
number_of_vertices = scan.nextInt();
adjacency_matrix = new int[number_of_vertices + 1][number_of_vertices + 1];
System.out.println("Enter the Weighted Matrix for the graph");
for (int i = 1; i <= number_of_vertices; i++)
{
for (int j = 1; j <= number_of_vertices; j++)
{
adjacency_matrix[i][j] = scan.nextInt();
if (i == j)
{
adjacency_matrix[i][j] = 0;
continue;
}
if (adjacency_matrix[i][j] == 0)
{
adjacency_matrix[i][j] = MAX_VALUE;
}
}
}
KruskalAlgorithm kruskalAlgorithm = new KruskalAlgorithm(number_of_vertices);
kruskalAlgorithm.kruskalAlgorithm(adjacency_matrix);
scan.close();
}
}
class Edge
{
int sourcevertex;
int destinationvertex;
int weight;
}
class EdgeComparator implements Comparator<Edge>
{
@Override
public int compare(Edge edge1, Edge edge2)
{
if (edge1.weight < edge2.weight)
return -1;
if (edge1.weight > edge2.weight)
return 1;
return 0;
}
}
class CheckCycle
{
private Stack<Integer> stack;
private int adjacencyMatrix[][];
public CheckCycle()
{
stack = new Stack<Integer>();
}
public boolean checkCycle(int adjacency_matrix[][], int source)
{
boolean cyclepresent = false;
int number_of_nodes = adjacency_matrix[source].length - 1;
adjacencyMatrix = new int[number_of_nodes + 1][number_of_nodes + 1];
for (int sourcevertex = 1; sourcevertex <= number_of_nodes; sourcevertex++)
{
for (int destinationvertex = 1; destinationvertex <= number_of_nodes; destinationvertex++)
{
adjacencyMatrix[sourcevertex][destinationvertex] = adjacency_matrix[sourcevertex]
[destinationvertex];
}
}
int visited[] = new int[number_of_nodes + 1];
int element = source;
int i = source;
visited[source] = 1;
stack.push(source);
while (!stack.isEmpty())
{
element = stack.peek();
i = element;
while (i <= number_of_nodes)
{
if (adjacencyMatrix[element][i] >= 1 && visited[i] == 1)
{
if (stack.contains(i))
{
cyclepresent = true;
return cyclepresent;
}
}
if (adjacencyMatrix[element][i] >= 1 && visited[i] == 0)
{
stack.push(i);
visited[i] = 1;
adjacencyMatrix[element][i] = 0;// mark as labelled;
adjacencyMatrix[i][element] = 0;
element = i;
i = 1;
continue;
}
i++;
}
stack.pop();
}
return cyclepresent;
}
9b SPANNING TREE IMPLEMENTATION(PRIM’S)
AIM:
To write a java program to implement Spanning tree implementation using Prim’s algorithm.
ALGORITHM:
1. Create a set mstSet that keeps track of vertices already included in MST.
2. Assign a key value to all vertices in the input graph. Initialize all key values as INFINITE.
Assign key value as 0 for the first vertex so that it is picked first.
3. While mstSet doesn’t include all vertices
3.1. Pick a vertex u which is not there in mstSet and has minimum key value.
3.2. Include u to mstSet.
3.3. Update key value of all adjacent vertices of u. To update the key values, iterate through all
adjacent vertices. For every adjacent vertex v, if weight of edge u-v is less than the previous key
value of v, update the key value as weight of u-v.
PROGRAM :
// Prim's Algorithm in C++
#include <cstring>
#include <iostream>
using namespace std;
#define INF 9999999
// number of vertices in grapj
#define V 5
// create a 2d array of size 5x5
//for adjacency matrix to represent graph
int G[V][V] = {
{0, 9, 75, 0, 0},
{9, 0, 95, 19, 42},
{75, 95, 0, 51, 66},
{0, 19, 51, 0, 31},
{0, 42, 66, 31, 0}};
int main() {
int no_edge; // number of edge
ALGORITHM:
1.Initialization of all nodes with distance "infinite"; initialization of the starting node with 0
2.Marking of the distance of the starting node as permanent, all other distances as temporarily.
3.Setting of starting node as active.
4.Calculation of the temporary distances of all neighbour nodes of the active node by summing
up its distance with the weights of the edges.
5.If such a calculated distance of a node is smaller as the current one, update the distance and
set the current node as antecessor. This step is also called update and is Dijkstra's central idea.
6.Setting of the node with the minimal temporary distance as active. Mark its distance as
permanent.
Repeating of steps 4 to 7 until there aren't any nodes left with a permanent distance, which
neighbours still have temporary distance
PROGRAM:
int printSolution(int dist[], int n)
{
printf("Vertex Distance from Source\n");
for (int i = 0; i < V; i++)
printf("%d \t\t %d\n", i, dist[i]);
}
AIM:
To write a java program to implement quick sort.
ALGORITHM:
1. Start with the weighted graph
2.Choose the starting vertex and assign infinity path values to all other vertex
3.Visit each edge and relax the path distance if they are inaccurate
4.We need to do this V times because in the worst case the vertex path length might need to
be readjusted V times
5.Notice how the vertex at the top right corner had its path length adjusted
6.After all vertices have their path lengths we check if a negative cycle is present
#include <bits/stdc++.h>
//edge 3 --> 2
graph->edge[4].u = 3;
graph->edge[4].v = 2;
graph->edge[4].w = 2;
return 0;
}
11. IMPLEMENTATION OF MATRIX CHAIN MULTIPLICATION
AIM:
To write a java program to implement Matrix Chain Multiplication.
ALGORITHM:
1. A chain of matrices to be multiplied is given as input.
2. For a sequence A1,A2,A3,A4 of 4 matrices, there are 5 different orderings=5 different
parethesization.
i) (A1,(A2(A3 A4)))
ii) (A1((A2 A3)A4))
iii) ((A1 A2)(A3 A4))
iv) ((A1(A2 A3))A4)
v) (((A1 A2)A3)A4)
3. Matrix_Multiply(A,B)
If coloumns[A]!=rows[B]
Then error “incomplete dimensions”
Else for i <- 1 to rows[A]
Do for j <- 1 to columns[B]
Do c[I,j] <- 0
For k<- 1 to columns[A]
Do c[i,j]=C[i,j]+A[i,k]+B[i,j]
Return c
4. A parenthesizing of the chain of the matrices is obtained as output.
PROGRAM :
#include<stdio.h>
#include<limits.h>
// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
int MatrixChainMultiplication(int p[], int n)
{
int m[n][n];
int i, j, k, L, q;
for (i=1; i<n; i++)
m[i][i] = 0; //number of multiplications are 0(zero) when there is only one matrix
//Here L is chain length. It varies from length 2 to length n.
for (L=2; L<n; L++) {
for (i=1; i<n-L+1; i++) {
j = i+L-1;
m[i][j] = INT_MAX; //assigning to maximum value
for (k=i; k<=j-1; k++) {
q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if (q < m[i][j])
{
m[i][j] = q; //if number of multiplications found less that number will be updated.
}
} } }
return m[1][n-1]; //returning the final answer which is M[1][n]
}
int main()
{
int n,i;
printf("Enter number of matrices\n");
scanf("%d",&n);
n++;
int arr[n];
printf("Enter dimensions \n");
for(i=0;i<n;i++)
{
printf("Enter d%d :: ",i);
scanf("%d",&arr[i]);
}
return 0;
}
Output
Enter number of matrices
4
Enter dimensions
Enter d0 :: 10
Enter d1 :: 100
Enter d2 :: 20
Enter d3 :: 5
Enter d4 :: 80
Minimum number of multiplications is 19000
12 a. IMPLEMENTATION OF ACTIVITY SELECTION
AIM:
To write a java program to implement Activity Selection.
ALGORITHM:
1.Sort the activities as per finishing time in ascending order
2.Select the first activity
3.Select the new activity if its starting time is greater than or equal to the previously selected
activity
4.REPEAT step 3 till all activities are checked
PROGRAM :
#include<bits/stdc++.h>
using namespace std;
//store the elements in ascending order on the basis of finishing time
bool comp(pair<int,int>i,pair<int,int>j){
return i.second<j.second;
}
int main() {
int n;
cout<<"enter the number of elements:"<<endl;
cin>>n;
map<pair<int,int>,int>m;
vector<pair<int,int> >vec(n);
cout<<" Enter the starting time of activity:"<<endl;
//store starting time
for(int i=0;i<n;i++){
cin>>vec[i].first;
}
cout<<"Enter the finishing time of activity:"<<endl;
//store finishing time
for(int i=0;i<n;i++){
cin>>vec[i].second;
}
for(int i=0;i<n;i++){
m[vec[i]]=i;
}
//sorting
sort(vec.begin(),vec.end(),comp);
//store the activity
vector<int>v;
vector<int>::iterator i;
v.push_back(m[vec[0]]);
pair<int,int>current=vec[0];
for(int j=1;j<n;j++){
if(vec[j].first>current.second){
v.push_back(m[vec[j]]);
current=vec[j];
}
}
cout<<"Order in ehich the activity take place"<<endl;
for(i=v.begin();i!=v.end();i++){
cout<<*i+1<<" ";
}
cout<<endl;
return 0;
}
OUTPUT
enter the number of elements:
6
Enter the starting time of activity:
130585
Enter the finishing time of activity:
246799
Order in ehich the activity take place
1245
12 b IMPLEMENTATION OF HUFFMAN CODING
AIM:
To write a java program to implement Huffman Coding
ALGORITHM:
1.Sort the message ensemble by decreasing probability.
2. N is the cardinal of the message ensemble (number of different messages).
3.Compute the integer n_0 such as 2<=n_0<=D and (N-n_0)/(D-1) is integer.
4. Select the n_0 least probable messages, and assign them each a digit code.
5. Substitute the selected messages by a composite message summing their probability, and
re-order it.
6.While there remains more than one message, do steps thru 8.
7. Select D least probable messages, and assign them each a digit code.
8. Substitute the selected messages by a composite message summing their probability,
and re-order it.
9. The code of each message is given by the concatenation of the code digits of the aggregate
they've been put in.
PROGRAM :
// Huffman Coding in C++
#include <iostream>
using namespace std;
#define MAX_TREE_HT 50
struct MinHNode {
unsigned freq;
char item;
struct MinHNode *left, *right;
};
struct MinH {
unsigned size;
unsigned capacity;
struct MinHNode **array;
};
return temp;
}
// Swap function
void swapMinHNode(struct MinHNode **a, struct MinHNode **b) {
struct MinHNode *t = *a;
*a = *b;
*b = t;
}
// Heapify
void minHeapify(struct MinH *minHeap, int idx) {
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (smallest != idx) {
swapMinHNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
// Check if size if 1
int checkSizeOne(struct MinH *minHeap) {
return (minHeap->size == 1);
}
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
// Insertion
void insertMinHeap(struct MinH *minHeap, struct MinHNode *minHeapNode) {
++minHeap->size;
int i = minHeap->size - 1;
minHeap->array[i] = minHeapNode;
}
minHeap->size = size;
buildMinHeap(minHeap);
return minHeap;
}
while (!checkSizeOne(minHeap)) {
left = extractMin(minHeap);
right = extractMin(minHeap);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
return extractMin(minHeap);
}
void printHCodes(struct MinHNode *root, int arr[], int top) {
if (root->left) {
arr[top] = 0;
printHCodes(root->left, arr, top + 1);
}
if (root->right) {
arr[top] = 1;
printHCodes(root->right, arr, top + 1);
}
if (isLeaf(root)) {
cout << root->item << " | ";
printArray(arr, top);
}
}
// Wrapper function
void HuffmanCodes(char item[], int freq[], int size) {
struct MinHNode *root = buildHfTree(item, freq, size);
int main() {
char arr[] = {'A', 'B', 'C', 'D'};
int freq[] = {5, 1, 6, 3};