Me - Ads Lab 2022

Download as pdf or txt
Download as pdf or txt
You are on page 1of 39

Ex No.

:1 IMPLEMENTATION OF DICTIONARIES
Date :

Aim:
To write a C++ program for implementation of Dictionaries.
Algorithm:
Step 1: Start the program.
Step 2: Declare the key values.
Step 3: To perform the operations on the map elements like search, remove and insert
pairs have logarithmic complexity.
Step 4: Display the results.
Step 5: Stop the program.
Program:
#include <iostream>
#include <map>
using std::cout; using std::cin;
using std::endl; using std::string;
using std::map; using std::copy;
template<typename Map>
void PrintMap(Map& m)
{
cout << "[ ";
for (auto &item : m) {
cout << item.first << ":" << item.second << " ";
}
cout << "]\n";
}
int main() {
map<int, string> map1 = {{1, "Apple",},
{2, "Banana",},
{3, "Mango",},
{4, "Raspberry",},
{5, "Blackberry",},
{6, "Cocoa",}};
cout << "map1 - ";
PrintMap(map1);
cout << endl;
return EXIT_SUCCESS;
}
Output :
map1 - [ 1:Apple 2:Banana 3:Mango 4:Raspberry 5:Blackberry 6:Cocoa ]
Result:
Thus a C++ program for operations on the map elements like search, remove and
insert pairs have logarithmic complexity was implemented and executed successfully.
Ex No.:2 IMPLEMENTATION OF HASHING
Date :
Aim :
To write a C++ program for implementation of Hashing.
Algorithm:
Step 1 : Start the program.
Step 2 : Choose any element of the array to be the pivot value.
Step 3 : Divide all other elements into two partitions.
All elements less than the pivot must be in the first partitions.
All elements greater than the pivot must be in the second partitions.
Step 4 : Use recursion to sort both partitions.
Step 5 : Join the first sorted partitions the pivot, and the second sorted partitions.
Step 6 : Tables are sorted in linear partitions.
Step 7 : Stop the program.
Program:
#include<bits/stdc++.h>
using namespace std;
class Hash
{
int BUCKET;
list<int> *table;
public:
Hash(int V);
void insertItem(int x);
void deleteItem(int key);
int hashFunction(int x) {
return (x % BUCKET);
}
void displayHash();
};

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

void Hash::insertItem(int key)


{
int index = hashFunction(key);
table[index].push_back(key);
}
void Hash::deleteItem(int key)
{
int index = hashFunction(key);
list <int> :: iterator i;
for (i = table[index].begin();
i != table[index].end(); i++) {
if (*i == key)
break;
}
table[index].erase(i);
}
void Hash::displayHash() {
for (int i = 0; i < BUCKET; i++) {
cout << i;
for (auto x : table[i])
cout << " --> " << x;
cout << endl;
}
}
int main()
{
int a[] = {15, 11, 27, 8, 12};
int n = sizeof(a)/sizeof(a[0]);
Hash h(7);
for (int i = 0; i < n; i++)
h.insertItem(a[i]);
h.deleteItem(12);
h.displayHash();
return 0;
}

OUTPUT:

0
1 --> 15 --> 8
2
3
4 --> 11
5
6--> 27

Result:
Thus a C++ program for Hashing techniques was implemented and executed
successfully.
Ex No.:3 IMPLEMENTATION OF A BINARY SEARCH TREE
Date :
Aim:
To write a C++ program to implement the binary search trees.
Algorithm:
Step 1 : Start the program
Step 2 : Initialize and declare the variables
Step 3 : Construct the tree.
Step 4 : Data values are given which we call a key and a binary search tree.
Step 5 : To search for the key in the given binary search tree, start with the root node
and compare the key with the data value of the root node. If they match,
return the root pointer.
Step 6 : If the key is less than the data value of the root node, repeat the process by using
the left sub tree.
Step 7 : Otherwise repeat the same process with the right sub tree until either a matches
found or the sub tree under consideration becomes an empty tree.
Step 8 : Stop the program.
Program:
#include<iostream>
using namespace std;
//declaration for new bst node
struct bstnode
{
int data;
struct bstnode *left, *right;
};
// create a new BST node
struct bstnode *newNode(int key)
{
struct bstnode *temp = new struct bstnode();
temp->data = key;
temp->left = temp->right = NULL;
return temp;
}
// perform inorder traversal of BST
void inorder(struct bstnode *root)
{
if (root != NULL)
{
inorder(root->left);
cout<<root->data<<" ";
inorder(root->right);
}
}
/* insert a new node in BST with given key */
struct bstnode* insert(struct bstnode* node, int key)
{
//tree is empty;return a new node
if (node == NULL) return newNode(key);
//if tree is not empty find the proper place to insert new node
if (key < node->data)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
//return the node pointer
return node;
}
//returns the node with minimum value
struct bstnode * minValueNode(struct bstnode* node)
{
struct bstnode* current = node;
//search the leftmost tree
while (current && current->left != NULL)
current = current->left;
return current;
}
//function to delete the node with given key and rearrange the root
struct bstnode* deleteNode(struct bstnode* root, int key)
{
// empty tree
if (root == NULL) return root;
// search the tree and if key < root, go for lefmost tree
if (key < root->data)
root->left = deleteNode(root->left, key);
// if key > root, go for rightmost tree
else if (key > root->data)
root->right = deleteNode(root->right, key);
// key is same as root
else
{
// node with only one child or no child
if (root->left == NULL)
{
struct bstnode *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
struct bstnode *temp = root->left;
free(root);
return temp;
}
// node with both children; get successor and then delete the node
struct bstnode* temp = minValueNode(root->right);
// Copy the inorder successor's content to this node
root->data = temp->data;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->data);
}
return root;
}
// main program
int main()
{
/* Let us create following BST
40
/ \
30 60
\
65
\
70*/
struct bstnode *root = NULL;
root = insert(root, 40);
root = insert(root, 30);
root = insert(root, 60);
root = insert(root, 65);
root = insert(root, 70);
cout<<"Binary Search Tree created (Inorder traversal):"<<endl;
inorder(root);
cout<<"\nDelete node 40\n";
root = deleteNode(root, 40);
cout<<"Inorder traversal for the modified Binary Search Tree:"<<endl;
inorder(root);
return 0;
}
Output:
Binary Search Tree created (Inorder traversal):
30 40 60 65 70
Delete node 40
Inorder traversal for the modified Binary Search Tree:
30 60 65 70

Result:
Thus the program for Binary Search Tree for in-order traversal sequence was
implemented and executed successfully.
Ex No.:4 RED BLACK TREE IMPLEMENTATION
Date :

Aim:

To write a C++ program to implement Red Black Tree.

Algorithm:
Step 1: Start the program
Step 2: Initialize the variables like root node, left, right, key value, color
Step 3: Let q be the leaf (ie. NULL) and parent be the root of the tree.
Step 4: Check if the tree is empty (ie. Whether parent is NULL). If yes, insert Key as a root
node and color it black.
Step 5: Else, repeat steps following steps until leaf (NULL) is reached.
Compare Key with rootKey, If Key is greater than rootKey, traverse through the
right subtree. Else traverse through the left subtree.
Step 6: Assign the parent of the leaf as a parent of newNode.
Step 7: If leafKey is greater than newKey, make newNode as rightChild.
Else, make newNode as leftChild.
Step 8: Assign NULL to the left and rightChild of newNode and RED color to key.
Step 9: Similarly repeat the steps for delete node
Step 10: Stop the Program

Program:
#include<iostream>
using namespace std;
struct node
{
int key;
node *parent;
char color;
node *left;
node *right;
};
class RBtree
{
node *root;
node *q;
public :
RBtree()
{
q=NULL;
root=NULL;
}
void insert();
void insertfix(node *);
void leftrotate(node *);
void rightrotate(node *);
void del();
node* successor(node *);
void delfix(node *);
void disp();
void display( node *);
void search();
};
void RBtree::insert()
{
int z,i=0;
cout<<"\nEnter key of the node to be inserted: ";
cin>>z;
node *p,*q;
node *t=new node;
t->key=z;
t->left=NULL;
t->right=NULL;
t->color='r';
p=root;
q=NULL;
if(root==NULL)
{
root=t;
t->parent=NULL;
}
else
{
while(p!=NULL)
{
q=p;
if(p->key<t->key)
p=p->right;
else
p=p->left;
}
t->parent=q;
if(q->key<t->key)
q->right=t;
else
q->left=t;
}
insertfix(t);
}
void RBtree::insertfix(node *t)
{
node *u;
if(root==t)
{
t->color='b';
return;
}
while(t->parent!=NULL&&t->parent->color=='r')
{
node *g=t->parent->parent;
if(g->left==t->parent)
{
if(g->right!=NULL)
{
u=g->right;
if(u->color=='r')
{
t->parent->color='b';
u->color='b';
g->color='r';
t=g;
}
}
else
{
if(t->parent->right==t)
{
t=t->parent;
leftrotate(t);
}
t->parent->color='b';
g->color='r';
rightrotate(g);
}
}
else
{
if(g->left!=NULL)
{
u=g->left;
if(u->color=='r')
{
t->parent->color='b';
u->color='b';
g->color='r';
t=g;
}
}
else
{
if(t->parent->left==t)
{
t=t->parent;
rightrotate(t);
}
t->parent->color='b';
g->color='r';
leftrotate(g);
}
}
root->color='b';
}
}

void RBtree::del()
{
if(root==NULL)
{
cout<<"\nEmpty Tree." ;
return ;
}
int x;
cout<<"\nEnter the key of the node to be deleted: ";
cin>>x;
node *p;
p=root;
node *y=NULL;
node *q=NULL;
int found=0;
while(p!=NULL&&found==0)
{
if(p->key==x)
found=1;
if(found==0)
{
if(p->key<x)
p=p->right;
else
p=p->left;
}
}
if(found==0)
{
cout<<"\nElement Not Found.";
return ;
}
else
{
cout<<"\nDeleted Element: "<<p->key;
cout<<"\nColour: ";
if(p->color=='b')
cout<<"Black\n";
else
cout<<"Red\n";

if(p->parent!=NULL)
cout<<"\nParent: "<<p->parent->key;
else
cout<<"\nThere is no parent of the node. ";
if(p->right!=NULL)
cout<<"\nRight Child: "<<p->right->key;
else
cout<<"\nThere is no right child of the node. ";
if(p->left!=NULL)
cout<<"\nLeft Child: "<<p->left->key;
else
cout<<"\nThere is no left child of the node. ";
cout<<"\nNode Deleted.";
if(p->left==NULL||p->right==NULL)
y=p;
else
y=successor(p);
if(y->left!=NULL)
q=y->left;
else
{
if(y->right!=NULL)
q=y->right;
else
q=NULL;
}
if(q!=NULL)
q->parent=y->parent;
if(y->parent==NULL)
root=q;
else
{
if(y==y->parent->left)
y->parent->left=q;
else
y->parent->right=q;
}
if(y!=p)
{
p->color=y->color;
p->key=y->key;
}
if(y->color=='b')
delfix(q);
}
}

void RBtree::delfix(node *p)


{
node *s;
while(p!=root&&p->color=='b')
{
if(p->parent->left==p)
{
s=p->parent->right;
if(s->color=='r')
{
s->color='b';
p->parent->color='r';
leftrotate(p->parent);
s=p->parent->right;
}
if(s->right->color=='b'&&s->left->color=='b')
{
s->color='r';
p=p->parent;
}
else
{
if(s->right->color=='b')
{
s->left->color=='b';
s->color='r';
rightrotate(s);
s=p->parent->right;
}
s->color=p->parent->color;
p->parent->color='b';
s->right->color='b';
leftrotate(p->parent);
p=root;
}
}
else
{
s=p->parent->left;
if(s->color=='r')
{
s->color='b';
p->parent->color='r';
rightrotate(p->parent);
s=p->parent->left;
}
if(s->left->color=='b'&&s->right->color=='b')
{
s->color='r';
p=p->parent;
}
else
{
if(s->left->color=='b')
{
s->right->color='b';
s->color='r';
leftrotate(s);
s=p->parent->left;
}
s->color=p->parent->color;
p->parent->color='b';
s->left->color='b';
rightrotate(p->parent);
p=root;
}
}
p->color='b';
root->color='b';
}
}

void RBtree::leftrotate(node *p)


{
if(p->right==NULL)
return ;
else
{
node *y=p->right;
if(y->left!=NULL)
{
p->right=y->left;
y->left->parent=p;
}
else
p->right=NULL;
if(p->parent!=NULL)
y->parent=p->parent;
if(p->parent==NULL)
root=y;
else
{
if(p==p->parent->left)
p->parent->left=y;
else
p->parent->right=y;
}
y->left=p;
p->parent=y;
}
}
void RBtree::rightrotate(node *p)
{
if(p->left==NULL)
return ;
else
{
node *y=p->left;
if(y->right!=NULL)
{
p->left=y->right;
y->right->parent=p;
}
else
p->left=NULL;
if(p->parent!=NULL)
y->parent=p->parent;
if(p->parent==NULL)
root=y;
else
{
if(p==p->parent->left)
p->parent->left=y;
else
p->parent->right=y;
}
y->right=p;
p->parent=y;
}
}

node* RBtree::successor(node *p)


{
node *y=NULL;
if(p->left!=NULL)
{
y=p->left;
while(y->right!=NULL)
y=y->right;
}
else
{
y=p->right;
while(y->left!=NULL)
y=y->left;
}
return y;
}

void RBtree::disp()
{
display(root);
}
void RBtree::display(node *p)
{
if(root==NULL)
{
cout<<"\nEmpty Tree.";
return ;
}
if(p!=NULL)
{
cout<<"\n\t NODE: ";
cout<<"\n Key: "<<p->key;
cout<<"\n Colour: ";
if(p->color=='b')
cout<<"Black";
else
cout<<"Red";
if(p->parent!=NULL)
cout<<"\n Parent: "<<p->parent->key;
else
cout<<"\n There is no parent of the node. ";
if(p->right!=NULL)
cout<<"\n Right Child: "<<p->right->key;
else
cout<<"\n There is no right child of the node. ";
if(p->left!=NULL)
cout<<"\n Left Child: "<<p->left->key;
else
cout<<"\n There is no left child of the node. ";
cout<<endl;
if(p->left)
{
cout<<"\n\nLeft:\n";
display(p->left);
}
/*else cout<<"\nNo Left Child.\n";*/
if(p->right)
{
cout<<"\n\nRight:\n";
display(p->right);
}
/*else
cout<<"\nNo Right Child.\n"*/
}
}
void RBtree::search()
{
if(root==NULL)
{
cout<<"\nEmpty Tree\n" ;
return ;
}
int x;
cout<<"\n Enter key of the node to be searched: ";
cin>>x;
node *p=root;
int found=0;
while(p!=NULL&& found==0)
{
if(p->key==x)
found=1;
if(found==0)
{
if(p->key<x)
p=p->right;
else
p=p->left;
}
}
if(found==0)
cout<<"\nElement Not Found.";
else
{
cout<<"\n\t FOUND NODE: ";
cout<<"\n Key: "<<p->key;
cout<<"\n Colour: ";
if(p->color=='b')
cout<<"Black";
else
cout<<"Red";
if(p->parent!=NULL)
cout<<"\n Parent: "<<p->parent->key;
else
cout<<"\n There is no parent of the node. ";
if(p->right!=NULL)
cout<<"\n Right Child: "<<p->right->key;
else
cout<<"\n There is no right child of the node. ";
if(p->left!=NULL)
cout<<"\n Left Child: "<<p->left->key;
else
cout<<"\n There is no left child of the node. ";
cout<<endl;
}
}
int main()
{
int ch,y=0;
RBtree obj;
do
{
cout<<"\n\t RED BLACK TREE " ;
cout<<"\n 1. Insert in the tree ";
cout<<"\n 2. Delete a node from the tree";
cout<<"\n 3. Search for an element in the tree";
cout<<"\n 4. Display the tree ";
cout<<"\n 5. Exit " ;
cout<<"\nEnter Your Choice: ";
cin>>ch;
switch(ch)
{
case 1 : obj.insert();
cout<<"\nNode Inserted.\n";
break;
case 2 : obj.del();
break;
case 3 : obj.search();
break;
case 4 : obj.disp();
break;
case 5 : y=1;
break;
default : cout<<"\nEnter a Valid Choice.";
}
cout<<endl;

}while(y!=1);
return 1;
}
Output:
1. Insert in the tree

2. Delete a node from the tree

3. Search for an element in tree

4. Display the tree

5. Exit

Enter your choice: 1

Enter key to be inserted : 8

Node Inserted

Result:
Thus the C++ program for Red Black tree was implemented and executed
successfully.
Ex No.:5 AVL TREE IMPLEMENTATION
Date :

Aim:
To write a C++ program to implement AVL tree in data structures.
Algorithm:

Step 1: Start the program.


Step 2: Initialize the variables like root node, left, right, key value, height.
Step 3: A newNode is always inserted as a leaf node with balance factor equal to 0.
Step 4: Compare newKey with rootKey of the current tree. If newKey < rootKey, call
insertion algorithm on the left subtree of the current node.
Step 5: Else if newKey > rootKey, call insertion algorithm on the right subtree of current
node. Compare leafKey obtained from the above steps with newKey:
Step 6: If newKey < leafKey, make newNode as the leftChild of leafNode.
Step 7: Else, make newNode as rightChild of leafNode and update balanceFactor of the
Nodes .If the nodes are unbalanced, then rebalance the node.
Step 8: If balanceFactor > 1, it means the height of the left subtree is greater than that of the
right subtree. So, do a right rotation or left-right rotation.
Step 9: If newNodeKey < leftChildKey do right rotation. Else, do left-right rotation
Step 10: If balanceFactor < -1, it means the height of the right subtree is greater than that of
the left subtree. So, do right rotation or right-left rotation.
Step 11: If newNodeKey > rightChildKey do left rotation. Else, do right-left rotation and
Similarly check the conditions for delete operation .
Step 12: Stop the program.

Program:
#include<bits/stdc++.h>
using namespace std;
// An AVL tree node
class Node
{
public:
int key;
Node *left;
Node *right;
int height;
};
// A utility function to get maximum
// of two integers
int max(int a, int b);
// A utility function to get the
// height of the tree
int height(Node *N)
{
if (N == NULL)
return 0;
return N->height;
}

// A utility function to get maximum


// of two integers
int max(int a, int b)
{
return (a > b)? a : b;
}
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
Node* newNode(int key)
{
Node* node = new Node();
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially
// added at leaf
return(node);
}
// A utility function to right
// rotate subtree rooted with y
// See the diagram given above.
Node *rightRotate(Node *y)
{
Node *x = y->left;
Node *T2 = x->right;

// Perform rotation
x->right = y;
y->left = T2;

// Update heights
y->height = max(height(y->left),
height(y->right)) + 1;
x->height = max(height(x->left),
height(x->right)) + 1;

// Return new root


return x;
}
// A utility function to left
// rotate subtree rooted with x
// See the diagram given above.
Node *leftRotate(Node *x)
{
Node *y = x->right;
Node *T2 = y->left;

// Perform rotation
y->left = x;
x->right = T2;

// Update heights
x->height = max(height(x->left),
height(x->right)) + 1;
y->height = max(height(y->left),
height(y->right)) + 1;

// Return new root


return y;
}

// Get Balance factor of node N


int getBalance(Node *N)
{
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
// Recursive function to insert a key
// in the subtree rooted with node and
// returns the new root of the subtree.
Node* insert(Node* node, int key)
{
/* 1. Perform the normal BST insertion */
if (node == NULL)
return(newNode(key));

if (key < node->key)


node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else // Equal keys are not allowed in BST
return node;
/* 2. Update height of this ancestor node */
node->height = 1 + max(height(node->left),
height(node->right));
/* 3. Get the balance factor of this ancestor node to check whether this node became unbalanced */
int balance = getBalance(node);
// If this node becomes unbalanced, then
// there are 4 cases
// Left Left Case
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node->left->key)
{
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
// A utility function to print preorder
// traversal of the tree.
// The function also prints height
// of every node
void preOrder(Node *root)
{
if(root != NULL)
{
cout << root->key << " ";
preOrder(root->left);
preOrder(root->right);
}
}
// Driver Code
int main()
{
Node *root = NULL;
/* Constructing tree given in
the above figure */
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
root = insert(root, 40);
root = insert(root, 50);
root = insert(root, 25);
/* The constructed AVL Tree would be
30
/\
20 40
/\\
10 25 50
*/
cout << "Preorder traversal of the "
"constructed AVL tree is \n";
preOrder(root);
return 0;
}

Output:
Preorder traversal of the constructed AVL tree is
30 20 10 25 40 50

Result:
Thus the C++ program for AVL tree was implemented and executed successfully.
Ex No.:6 IMPLEMENTATION OF BOYER MOORE ALGORITHMS
Date :

Aim:
Write a c++ program for implementing Boyer Moore Algorithm.
Algorithm:
Step 1 : Start the program.
Step 2 : For Good suffix approach calculates a preprocessing table.Let T be the substring of
text that matches with any substring in the pattern. Then shift the pattern until:
Step 3 : Then shift the pattern until:
Case i. Another occurrence of T in P matches with T in the Text.
Case ii. A prefix of Pattern P that matches the suffix of T.
Case iii. P moves past T.
Step 4 : Preprocessing For The Good String Suffix -Create an array shift. Shift[i] will
contain the distance our pattern will shift if there is a mismatch at (i-1)th position.
As a part of preprocessing an array bopos (border position) is calculated. Each
entry bopos[i] contains the starting index of the border for the suffix starting at
index i in given pattern P.
Step 4 : Using these above cases the pattern has been found.
Step 5 : Stop the program.

Program:
#include <stdio.h>
#include <string.h>

// preprocessing for strong good suffix rule


void preprocess_strong_suffix(int *shift, int *bpos,
char *pat, int m)
{
// m is the length of pattern
int i=m, j=m+1;
bpos[i]=j;
while(i>0)
{
/*if character at position i-1 is not equivalent to
character at j-1, then continue searching to right
of the pattern for border */
while(j<=m && pat[i-1] != pat[j-1])
{
/* the character preceding the occurrence of t in
pattern P is different than the mismatching character in P,
we stop skipping the occurrences and shift the pattern
from i to j */
if (shift[j]==0)
shift[j] = j-i;
//Update the position of next border
j = bpos[j];
}
/* p[i-1] matched with p[j-1], border is found.
store the beginning position of border */
i--;j--;
bpos[i] = j;
}
}

//Preprocessing for case 2


void preprocess_case2(int *shift, int *bpos,
char *pat, int m)
{
int i, j;
j = bpos[0];
for(i=0; i<=m; i++)
{
/* set the border position of the first character of the pattern
to all indices in array shift having shift[i] = 0 */
if(shift[i]==0)
shift[i] = j;

/* suffix becomes shorter than bpos[0], use the position of


next widest border as value of j */
if (i==j)
j = bpos[j];
}
}
/*Search for a pattern in given text using
Boyer Moore algorithm with Good suffix rule */
void search(char *text, char *pat)
{
// s is shift of the pattern with respect to text
int s=0, j;
int m = strlen(pat);
int n = strlen(text);

int bpos[m+1], shift[m+1];

//initialize all occurrence of shift to 0


for(int i=0;i<m+1;i++) shift[i]=0;

//do preprocessing
preprocess_strong_suffix(shift, bpos, pat, m);
preprocess_case2(shift, bpos, pat, m);
while(s <= n-m)
{
j = m-1;

/* Keep reducing index j of pattern while characters of


pattern and text are matching at this shift s*/
while(j >= 0 && pat[j] == text[s+j])
j--;

/* If the pattern is present at the current shift, then index j


will become -1 after the above loop */
if (j<0)
{
printf("pattern occurs at shift = %d\n", s);
s += shift[0];
}
else
/*pat[i] != pat[s+j] so shift the pattern
shift[j+1] times */
s += shift[j+1];
}
}
//Driver
int main()
{
char text[] = "ABAAAABAACD";
char pat[] = "ABA";
search(text, pat);
return 0;
}

Output:
pattern occurs at shift = 0
pattern occurs at shift = 5

Result:
Thus the C++ program Boyer Moore algorithm was implemented and executed
successfully.
Ex No.:7 HUFFMEN CODING ALGORITHM IMPLEMENTATION
Date :
Aim:
Write a c++ program for implementing Huffmen Coding Algorithm.
Algorithm:
Step 1: Start the program.
Step 2: Calculate the frequency of each character in the string.
Step 3: Sort the characters in increasing order of the frequency. These are
stored in a priority queue Q.
Step 4: Make each unique character as a leaf node.
Step 5: Create an empty node z. Assign the minimum frequency to the left child of z and
assign the second minimum frequency to the right child of z. Set the value
of the z as the sum of the above two minimum frequencies. Getting the sum of
the least numbers.
Step 6: Remove these two minimum frequencies from Q and add the sum into the list of
Frequencies.
Step 7: Insert node z into the tree.
Step 8: Repeat steps 3 to 5 for all the characters.
Step 9: For each non-leaf node, assign 0 to the left edge and 1 to the right edge.Assign
0 to the left edge and 1 to the right edge.
Step 10:For sending the above string over a network, we have to send the tree as well as the
compressed-code.
Step 11: For decoding the code, we can take the code and traverse through the tree to find the
character.
Program:
#include <iostream>
#include <cstdlib>
using namespace std;
// This constant can be avoided by explicitly
// calculating height of Huffman Tree
#define MAX_TREE_HT 100
// A Huffman tree node
struct MinHeapNode {
// One of the input characters char data;
// Frequency of the character unsigned freq;
// Left and right child of this node
struct MinHeapNode *left, *right;
};
// A Min Heap: Collection of
// min-heap (or Huffman tree) nodes
struct MinHeap {
// Current size of min heap unsigned size;
// capacity of min heap unsigned capacity;
// Attay of minheap node pointers
struct MinHeapNode** array;
};
// A utility function allocate a new
// min heap node with given character
// and frequency of the character
struct MinHeapNode* newNode(char data, unsigned freq)
{
struct MinHeapNode* temp
= (struct MinHeapNode*)malloc
(sizeof(struct MinHeapNode));
temp->left = temp->right = NULL;
temp->data = data;
temp->freq = freq;
return temp;
}
// A utility function to create
// a min heap of given capacity
struct MinHeap* createMinHeap(unsigned capacity)
{
struct MinHeap* minHeap = (struct MinHeap*)malloc(sizeof(struct MinHeap));
// current size is 0
minHeap->size = 0;
minHeap->capacity = capacity;
minHeap->array = (struct MinHeapNode**)malloc(minHeap->capacity * sizeof(struct
MinHeapNode*));
return minHeap;
}
// A utility function to
// swap two min heap nodes
void swapMinHeapNode(struct MinHeapNode** a, struct MinHeapNode** b)
{
struct MinHeapNode* t = *a;
*a = *b;
*b = t;
}
// The standard minHeapify function.
void minHeapify(struct MinHeap* minHeap, int idx)
{
int smallest = idx;
int left = 2 * idx + 1;
int right = 2 * idx + 2;
if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq)
smallest = left;
if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq)
smallest = right;
if (smallest != idx)
{
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}
// A utility function to check
// if size of heap is 1 or not
int isSizeOne(struct MinHeap* minHeap)
{
return (minHeap->size == 1);
}
// A standard function to extract
// minimum value node from heap
struct MinHeapNode* extractMin(struct MinHeap* minHeap)
{
struct MinHeapNode* temp = minHeap->array[0];
minHeap->array[0] = minHeap->array[minHeap->size - 1];
--minHeap->size;
minHeapify(minHeap, 0);
return temp;
}
// A utility function to insert
// a new node to Min Heap
void insertMinHeap(struct MinHeap* minHeap, struct MinHeapNode* minHeapNode)
{
++minHeap->size;
int i = minHeap->size - 1;
while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq)
{
minHeap->array[i] = minHeap->array[(i - 1) / 2];
i = (i - 1) / 2;
}
minHeap->array[i] = minHeapNode;
}
// A standard function to build min heap
void buildMinHeap(struct MinHeap* minHeap)
{
int n = minHeap->size - 1;
int i;
for (i = (n - 1) / 2; i >= 0; --i)
minHeapify(minHeap, i);
}
// A utility function to print an array of size n
void printArr(int arr[], int n)
{
int i;
for (i = 0; i < n; ++i)
cout<< arr[i];
cout<<"\n";
}
// Utility function to check if this node is leaf
int isLeaf(struct MinHeapNode* root)
{
return !(root->left) && !(root->right);
}
// Creates a min heap of capacity
// equal to size and inserts all character of
// data[] in min heap. Initially size of
// min heap is equal to capacity
struct MinHeap* createAndBuildMinHeap(char data[], int freq[], int size)
{
struct MinHeap* minHeap = createMinHeap(size);
for (int i = 0; i < size; ++i)
minHeap->array[i] = newNode(data[i], freq[i]);
minHeap->size = size;
buildMinHeap(minHeap);
return minHeap;
}
// The main function that builds Huffman tree
struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size)
{ struct MinHeapNode *left, *right, *top;
// Step 1: Create a min heap of capacity
// equal to size. Initially, there are
// modes equal to size.
struct MinHeap* minHeap = createAndBuildMinHeap(data, freq, size);
// Iterate while size of heap doesn't become 1
while (!isSizeOne(minHeap))
{
// Step 2: Extract the two minimum
// freq items from min heap
left = extractMin(minHeap);
right = extractMin(minHeap);
// Step 3: Create a new internal
// node with frequency equal to the
// sum of the two nodes frequencies.
// Make the two extracted node as
// left and right children of this new node.
// Add this node to the min heap
// '$' is a special value for internal nodes, not used
top = newNode('$', left->freq + right->freq);
top->left = left;
top->right = right;
insertMinHeap(minHeap, top);
}
// Step 4: The remaining node is the
// root node and the tree is complete.
return extractMin(minHeap);
}
// Prints huffman codes from the root of Huffman Tree.
// It uses arr[] to store codes
void printCodes(struct MinHeapNode* root, int arr[], int top)
{
// Assign 0 to left edge and recur
if (root->left) {
arr[top] = 0;
printCodes(root->left, arr, top + 1);
}
// Assign 1 to right edge and recur
if (root->right) {
arr[top] = 1;
printCodes(root->right, arr, top + 1);
}
// If this is a leaf node, then
// it contains one of the input
// characters, print the character
// and its code from arr[]
if (isLeaf(root)) {
cout<< root->data <<": ";
printArr(arr, top);
}
}
// The main function that builds a
// Huffman Tree and print codes by traversing
// the built Huffman Tree
void HuffmanCodes(char data[], int freq[], int size)
{
// Construct Huffman Tree
struct MinHeapNode* root
= buildHuffmanTree(data, freq, size);

// Print Huffman codes using


// the Huffman tree built above
int arr[MAX_TREE_HT], top = 0;
printCodes(root, arr, top);
}
// Driver program to test above functions
int main()
{
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
int freq[] = { 5, 9, 12, 13, 16, 45 };
int size = sizeof(arr) / sizeof(arr[0]);
HuffmanCodes(arr, freq, size);
return 0;
}
Output:
f: 0
c: 100
d: 101
a: 1100
b: 1101
e: 111

Result:
Thus the C++ program Huffmen coding algorithm was implemented and executed
successfully.
Ex No.:8 KNUTH- MORRIS- PRATT ALGORITHMS
Date :
Aim:
Write a c++ program for implementing Knuth- Morris- Pratt Algorithm .
Algorithm:
Step 1 : Start the program
Step 2: To create LPS Table (prefix table) and define a one dimensional array with the size
equal to the length of the Pattern. (LPS[size])
Step 3: Define variables i & j. Set i = 0, j = 1 and LPS[0] = 0.
Step 4: Compare the characters at Pattern[i] and Pattern[j].
Step 5: If both are matched then set LPS[j] = i+1 and increment both i & j values by one.
goto to Step 4.
Step 6: If both are not matched then check the value of variable 'i'. If it is '0' then set LPS[j]
= 0 and increment 'j' value by one, if it is not '0' then set i = LPS[i-1]. Goto Step 4.
Step 7 : Repeat above steps until all the values of LPS[] are filled.
Step 8 : Patterns and text are given. Start comparing first character of pattern with first
character of text from left to right.
Step 9 : Likewise compare all the character in the pattern with the text. If mismatch occurs
shift the pattern using LPS Table.
Step 10: At last all the characters of pattern matched with substring in T which is starting
from some specific index value.
Step11: Stop the program.

Program:

#include <bits/stdc++.h>
void computeLPSArray(char* pat, int M, int* lps);
// Prints occurrences of txt[] in pat[]
void KMPSearch(char* pat, char* txt)
{
int M = strlen(pat);
int N = strlen(txt);
// create lps[] that will hold the longest prefix suffix
// values for pattern
int lps[M];
// Preprocess the pattern (calculate lps[] array)
computeLPSArray(pat, M, lps);
int i = 0; // index for txt[]
int j = 0; // index for pat[]
while (i < N)
{
if (pat[j] == txt[i])
{
j++;
i++;
}
if (j == M)
{
printf("Found pattern at index %d ", i - j);
j = lps[j - 1];
}
// mismatch after j matches
else if (i < N && pat[j] != txt[i]) {
// Do not match lps[0..lps[j-1]] characters,
// they will match anyway
if (j != 0)
j = lps[j - 1];
else
i = i + 1;
}
}
}
// Fills lps[] for given patttern pat[0..M-1]
void computeLPSArray(char* pat, int M, int* lps)
{
// length of the previous longest prefix suffix
int len = 0;
lps[0] = 0; // lps[0] is always 0
// the loop calculates lps[i] for i = 1 to M-1
int i = 1;
while (i < M) {
if (pat[i] == pat[len]) {
len++;
lps[i] = len;
i++;
}
else // (pat[i] != pat[len])
{
// This is tricky. Consider the example.
// AAACAAAA and i = 7. The idea is similar
// to search step.
if (len != 0) {
len = lps[len - 1];
// Also, note that we do not increment
// i here
}
else // if (len == 0)
{
lps[i] = 0;
i++;
}
}
}
}

// Driver program to test above function


int main()
{
char txt[] = "ABABDABACDABABCABAB";
char pat[] = "ABABCABAB";
KMPSearch(pat, txt);
return 0;
}

Output:
Found pattern at index 10

Result:
Thus the C++ program for Knuth-moris-Pratt algorithm was implemented and
executed successfully.
Ex No.:9 IMPLEMENTATION OF LONGEST COMMON
Date : SUBSEQUENCES PROBLEM

Aim:
Write a c++ program for implementing Longest Common Subsequences Problem.
Algorithm:
Step 1 : Start the program
Step 2 : Create a table of dimension n+1*m+1 where n and m are the lengths
Of X and Y respectively. The first row and the first column are filled with zeros.
Initialize a table. Fill each cell of the table using the following logic.
Step 3: If the character corresponding to the current row and current column are matching,
then fill the current cell by adding one to the to the diagonal element. Point
an arrow cell.
Step 4 : Else take the maximum value from the previous column and previous row element
for filling the current cell. Point an arrow to the cell with maximum value. If they are
equal, point to any of them. Fill the values
Step 5 : Step 2 is repeated until the table is filled. Fill all the values.The value in the last row
and the last column is the length of the longest common subsequence The bottom
right corner is the length of the LCS.
Step 6: In order to find the longest common subsequence, start from the last element and
follow the direction of the arrow. The elements corresponding to () symbol form the
longest common subsequence. Create a path according to the arrows.
Step 7: Stop the program.

Program:
/* Dynamic Programming C++ implementation of LCS problem */
#include <bits/stdc++.h>
int max(int a, int b);
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int lcs(char* X, char* Y, int m, int n)
{
int L[m + 1][n + 1];
int i, j;
/* Following steps build L[m+1][n+1] in bottom up fashion. Note
that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if (X[i - 1] == Y[j - 1])
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = max(L[i - 1][j], L[i][j - 1]);
} }
/* L[m][n] contains length of LCS for X[0..n-1] and Y[0..m-1] */
return L[m][n];
}
/* Utility function to get max of 2 integers */
int max(int a, int b)
{
return (a > b) ? a : b;
}
/* Driver program to test above function */
int main()
{
char X[] = "AGGTAB";
char Y[] = "GXTXAYB";
int m = strlen(X);
int n = strlen(Y);
printf("Length of LCS is %d\n", lcs(X, Y, m, n));
return 0;
}

Output:
Length of LCS is 4

Result:
Thus the C++ program for longest subsequences problem was implemented and
executed successfully.
Ex No.:10 PRIORITY SEARCH TREE IMPLEMENTATION
Date :
Aim:
Write a c++ program for implementing Priority Search Tree.

Algorithm:
Step 1 : Start the program.
Step 2 :Declare and initialize the variables.
Step 3 :Using Push(), insert the elements in the queue.
Step 4 :Increment the top variable by one .
Step 5 : Using Pop(),delete the element from the queue.
Step 6 : Stop the program.

Program:
#include <iostream>
#include <queue>
using namespace std;
void showpq(priority_queue <int, vector<int>, greater<int>> gq)
{
priority_queue <int, vector<int>, greater<int>> g = gq;
while (!g.empty())
{
cout << '\t' << g.top();
g.pop();
}
cout << '\n';
}
int main ()
{
priority_queue <int, vector<int>, greater<int>> gquiz;
gquiz.push(10);
gquiz.push(30);
gquiz.push(20);
gquiz.push(5);
gquiz.push(1);
cout << "The priority queue gquiz is : ";
showpq(gquiz);
cout << "\ngquiz.size() : " << gquiz.size();
cout << "\ngquiz.top() : " << gquiz.top();
cout << "\ngquiz.pop() : ";
gquiz.pop();
showpq(gquiz);
return 0;
}
Output:
The priority queue gquiz is : 1 5 10 20 30
gquiz.size() : 5
gquiz.top() : 1
gquiz.pop() : 5 10 20 30

Result:
Thus the C++ program for priority search tree was implemented and executed
successfully.