0% found this document useful (0 votes)
12 views27 pages

DS Experiment

The document provides C++ implementations for various data structures and algorithms, including separate chaining and open addressing for hash maps, as well as binary tree operations such as insertion, deletion, and different traversal methods (inorder, preorder, postorder, and level order). It includes code snippets for each implementation, demonstrating how to manage key-value pairs in hash maps and perform operations on binary trees. Additionally, the document covers searching for nodes and handling collisions in hash maps.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views27 pages

DS Experiment

The document provides C++ implementations for various data structures and algorithms, including separate chaining and open addressing for hash maps, as well as binary tree operations such as insertion, deletion, and different traversal methods (inorder, preorder, postorder, and level order). It includes code snippets for each implementation, demonstrating how to manage key-value pairs in hash maps and perform operations on binary trees. Additionally, the document covers searching for nodes and handling collisions in hash maps.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 27

11) Implementation of hashing with (a) Separate Chaining

Aim: C++ implementation of Separate Chaining


#include <iostream>
#include <cstring>
// Linked List node
struct node{
// key is string
char *key;
// value is also string
char *value;
struct node *next;
};
// like constructor
void setNode(struct node *node, char *key, char *value){
node->key = key;
node->value = value;
node->next = NULL;
return;
}
struct hashMap{
// Current number of elements in hashMap
// and capacity of hashMap
int numOfElements, capacity;
// hold base address array of linked list
struct node **arr;
};
// like constructor
void initializeHashMap(struct hashMap *mp){
// Default capacity in this case
mp->capacity = 100;
mp->numOfElements = 0;
// array of size = 1
mp->arr = (struct node **)malloc(sizeof(struct node *) * mp-
>capacity);
return;
}
int hashFunction(struct hashMap *mp, char *key){
int bucketIndex;
int sum = 0, factor = 31;
for (int i = 0; i < strlen(key); i++){
// sum = sum + (ascii value of
// char * (primeNumber ^ x))...
// where x = 1, 2, 3....n
sum = ((sum % mp->capacity) + (((int)key[i]) * factor) %
mp->capacity)%
mp->capacity;
// factor = factor * prime
// number....(prime
// number) ^ x
factor = ((factor % __INT16_MAX__) * (31 %
__INT16_MAX__)) %
__INT16_MAX__;
}
bucketIndex = sum;
return bucketIndex;
}
void insert(struct hashMap *mp, char *key, char *value){
// Getting bucket index for the given
// key - value pair
int bucketIndex = hashFunction(mp, key);
struct node *newNode = (struct node *)malloc(
// Creating a new node
sizeof(struct node));
// Setting value of node
setNode(newNode, key, value);
// Bucket index is empty....no collision
if (mp->arr[bucketIndex] == NULL){
mp->arr[bucketIndex] = newNode;
}
// Collision
else{
// Adding newNode at the head of
// linked list which is present
// at bucket index....insertion at
// head in linked list
newNode->next = mp->arr[bucketIndex];
mp->arr[bucketIndex] = newNode;
}
return;
}
void deleteKey(struct hashMap *mp, char *key){
// Getting bucket index for the
// given key
int bucketIndex = hashFunction(mp, key);
struct node *prevNode = NULL;
// Points to the head of
// linked list present at
// bucket index
struct node *currNode = mp->arr[bucketIndex];
while (currNode != NULL){
// Key is matched at delete this
// node from linked list
if (strcmp(key, currNode->key) == 0){
// Head node
// deletion
if (currNode == mp->arr[bucketIndex]){
mp->arr[bucketIndex] = currNode->next;
}
// Last node or middle node
else{
prevNode->next = currNode->next;
}
free(currNode);
break;
}
prevNode = currNode;
currNode = currNode->next;
}
return;
}
char *search(struct hashMap *mp, char *key){
// Getting the bucket index for the given key
int bucketIndex = hashFunction(mp, key);
// Head of the linked list present at bucket index
struct node *bucketHead = mp->arr[bucketIndex];
while (bucketHead != NULL){
// Key is found in the hashMap
if (strcmp(bucketHead->key, key) == 0){
return bucketHead->value;
}
bucketHead = bucketHead->next;
}
// If no key found in the hashMap equal to the given key
char *errorMssg = (char *)malloc(sizeof(char) * 25);
strcpy(errorMssg, "Oops! No data found.\n");
return errorMssg;
}
// Drivers code
int main(){
// Initialize the value of mp
struct hashMap *mp = (struct hashMap *)malloc(sizeof(struct
hashMap));
initializeHashMap(mp);
insert(mp, "Yogaholic", "Anjali");
insert(mp, "pluto14", "Vartika");
insert(mp, "elite_Programmer", "Manish");
insert(mp, "GFG", "GeeksforGeeks");
insert(mp, "decentBoy", "Mayank");
printf("%s\n", search(mp, "elite_Programmer"));
printf("%s\n", search(mp, "Yogaholic"));
printf("%s\n", search(mp, "pluto14"));
printf("%s\n", search(mp, "decentBoy"));
printf("%s\n", search(mp, "GFG"));
// Key is not inserted
printf("%s\n", search(mp, "randomKey"));
printf("\nAfter deletion : \n");
// Deletion of key
deleteKey(mp, "decentBoy");
// Searching the deleted key
printf("%s\n", search(mp, "decentBoy"));
return 0;
}
OUTPUT:
[aiml2315@Aids ds]$MJ
Apple
Vertex
HYD
GeeksforGeeks

Aim: C++ implementation of Open addressing methods.


#include <bits/stdc++.h>
using namespace std;
// template for generic type
template <typename K, typename V>
// Hashnode class
class HashNode{
public:
V value;
K key;
// Constructor of hashnode
HashNode(K key, V value){
this->value = value;
this->key = key;
}
};
// template for generic type
template <typename K, typename V>
// Our own Hashmap class
class HashMap{
// hash element array
HashNode<K, V> **arr;
int capacity;
// current size
int size;
// dummy node
HashNode<K, V> *dummy;

public:
HashMap(){
// Initial capacity of hash array
capacity = 20;
size = 0;
arr = new HashNode<K, V> *[capacity];
// Initialise all elements of array as NULL
for (int i = 0; i < capacity; i++)
arr[i] = NULL;
// dummy node with value and key -1
dummy = new HashNode<K, V>(-1, -1);
}
// This implements hash function to find index
// for a key
int hashCode(K key) { return key % capacity; }
// Function to add key value pair
void insertNode(K key, V value){
HashNode<K, V> *temp = new HashNode<K, V>(key,
value);
// Apply hash function to find index for given key
int hashIndex = hashCode(key);
// find next free space
while (arr[hashIndex] != NULL && arr[hashIndex]->key !=
key && arr[hashIndex]->key != -1){
hashIndex++;
hashIndex %= capacity;
}
// if new node to be inserted
// increase the current size
if (arr[hashIndex] == NULL || arr[hashIndex]->key == -1)
size++;
arr[hashIndex] = temp;
}
// Function to delete a key value pair
V deleteNode(int key) {
// Apply hash function
// to find index for given key
int hashIndex = hashCode(key);
// finding the node with given key
while (arr[hashIndex] != NULL){
// if node found
if (arr[hashIndex]->key == key){
HashNode<K, V> *temp = arr[hashIndex];
// Insert dummy node here for further use
arr[hashIndex] = dummy;
// Reduce size
size--;
return temp->value;
}
hashIndex++;
hashIndex %= capacity;
}
// If not found return null
return NULL;
}
// Function to search the value for a given key
V get(int key){
// Apply hash function to find index for given key
int hashIndex = hashCode(key);
int counter = 0;
// finding the node with given key
while (arr[hashIndex] != NULL){ // int
counter =0; // BUG!
if (counter++ > capacity) // to avoid infinite loop
return NULL;
// if node found return its value
if (arr[hashIndex]->key == key)
return arr[hashIndex]->value;
hashIndex++;
hashIndex %= capacity;
}
// If not found return null
return NULL;
}
// Return current size
int sizeofMap() { return size; }
// Return true if size is 0
bool isEmpty() { return size == 0; }
// Function to display the stored key value pairs
void display(){
for (int i = 0; i < capacity; i++){
if (arr[i] != NULL && arr[i]->key != -1)
cout << "key = " << arr[i]->key
<< " value = " << arr[i]->value
<< endl;
}
}
};
// Driver method to test map class
int main(){
HashMap<int, int> *h = new HashMap<int, int>;
h->insertNode(1, 1);
h->insertNode(2, 2);
h->insertNode(2, 3);
h->display();
cout << h->sizeofMap() << endl;
cout << h->deleteNode(2) << endl;
cout << h->sizeofMap() << endl;
cout << h->isEmpty() << endl;
cout << h->get(2);
return 0;
}

Output:
key = 1 value = 1
key = 2 value = 3
2
3
1
0
0

12) Implementation of recursive and iterative traversals on


binary tree.
Aim: C++ Program for Implementing Binary Tree
#include <iostream>
#include <queue>
using namespace std;
// Template class for the Node of a Binary Tree
template <typename T>
class Node{
public:
// Data held by the node
T data;
// Pointer to the left child
Node *left;
// Pointer to the right child
Node *right;
// Constructor to initialize the node with a value
Node(T value) : data(value), left(nullptr), right(nullptr) {}
};
// Template class for a Binary Tree
template <typename T>
class BinaryTree{
private:
// Pointer to the root of the tree
Node<T> *root;
// Recursive Function to delete a node from the tree
Node<T> *deleteRecursive(Node<T> *current, T value){
if (current == nullptr)
return nullptr;
if (current->data == value){
if (current->left == nullptr && current->right ==
nullptr){
delete current;
return nullptr;
}
if (current->left == nullptr){
Node<T> *temp = current->right;
delete current;
return temp;
}
if (current->right == nullptr){
Node<T> *temp = current->left;
delete current;
return temp;
}
Node<T> *successor = findMin(current->right);
current->data = successor->data;
current->right = deleteRecursive(current->right,
successor->data);
}
else{
current->left = deleteRecursive(current->left, value);
current->right = deleteRecursive(current->right, value);
}
return current;
}
// Helper Function to find the minimum value node
Node<T> *findMin(Node<T> *node){
while (node->left != nullptr)
node = node->left;
return node;
}
// Recursive Function to search for a value in the tree
bool searchRecursive(Node<T> *current, T value){
if (current == nullptr)
return false;
if (current->data == value)
return true;
return searchRecursive(current->left, value) ||
searchRecursive(current->right, value);
}
// Function for Recursive inorder traversal of the tree
void inorderRecursive(Node<T> *node){
if (node != nullptr){
inorderRecursive(node->left);
cout << node->data << " ";
inorderRecursive(node->right);
}
}
// Function for Recursive preorder traversal of the tree
void preorderRecursive(Node<T> *node){
if (node != nullptr){
cout << node->data << " ";
preorderRecursive(node->left);
preorderRecursive(node->right);
}
}
// Function for Recursive postorder traversal of the tree
void postorderRecursive(Node<T> *node){
if (node != nullptr){
postorderRecursive(node->left);
postorderRecursive(node->right);
cout << node->data << " ";
}
}

public:
// Constructor to initialize the tree
BinaryTree() : root(nullptr) {}
// Function to insert a node in the binary tree
void insertNode(T value){
Node<T> *newNode = new Node<T>(value);
if (root == nullptr){
root = newNode;
return;
}
queue<Node<T> *> q;
q.push(root);
while (!q.empty()){
Node<T> *current = q.front();
q.pop();
if (current->left == nullptr){
current->left = newNode;
return;
}
else{
q.push(current->left);
}
if (current->right == nullptr){
current->right = newNode;
return;
}
else{
q.push(current->right);
}
}
}
// Function to delete a node from the tree
void deleteNode(T value){
root = deleteRecursive(root, value);
}
// Function to search for a value in the tree
bool search(T value){
return searchRecursive(root, value);
}
// Function to perform inorder traversal of the tree
void inorder(){
inorderRecursive(root);
cout << endl;
}
// Function to perform preorder traversal of the tree
void preorder(){
preorderRecursive(root);
cout << endl;
}
// Function to perform postorder traversal of the tree
void postorder(){
postorderRecursive(root);
cout << endl;
}
// Function to perform level order traversal of the tree
void levelOrder(){
if (root == nullptr)
return;
queue<Node<T> *> q;
q.push(root);
while (!q.empty()){
Node<T> *current = q.front();
q.pop();
cout << current->data << " ";
if (current->left != nullptr)
q.push(current->left);
if (current->right != nullptr)
q.push(current->right);
}
cout << endl;
}
};
int main(){
BinaryTree<int> tree;
// Insert the nodes into the tree
tree.insertNode(1);
tree.insertNode(2);
tree.insertNode(3);
tree.insertNode(4);
tree.insertNode(5);
tree.insertNode(6);
cout << "Inorder traversal: ";
tree.inorder();
cout << "Preorder traversal: ";
tree.preorder();
cout << "Postorder traversal: ";
tree.postorder();
cout << "Level order traversal: ";
tree.levelOrder();
cout << "Searching for 7: " << (tree.search(7) ? "Found" :
"Not Found") << endl;
cout << "Searching for 6: " << (tree.search(6) ? "Found" :
"Not Found") << endl;
tree.deleteNode(3);
cout << "Inorder traversal after removing 3: ";
tree.inorder();
return 0;
}

OUTPUT:
[aiml2341@Aids ds]$ Inorder traversal: 4 2 5 1 6 3
Preorder traversal: 1 2 4 5 3 6
Postorder traversal: 4 5 2 6 3 1
Level order traversal: 1 2 3 4 5 6
Searching for 7: Not Found
Searching for 6: Found
Inorder traversal after removing 3: 4 2 5 1 6

13) Implementation of operations on binary tree (delete entire


tree, copy entire tree, mirror image, level order, search for a
node etc.)
// C++ program to illustrate the level order traversal
#include "bits/stdc++.h"
using namespace std;
// Structure of the Binary Tree
struct treenode {
int info;
struct treenode *left, *right;
};
// Function to create the Binary Tree
struct treenode* create(){
int data;
struct treenode* tree;
// Dynamically allocating memory for the tree-node
tree = new treenode;
cout << "\nEnter data to be inserted "<< "or type -1 for no
insertion : ";
// Input from the user
cin >> data;
// Termination Condition
if (data == -1)
return 0;
// Assign value from user into tree
tree->info = data;
// Recursively Call to create the left and the right sub tree
cout << "Enter left child of : "<< data;
tree->left = create();
cout << "Enter right child of : "<< data;
tree->right = create();
// Return the created Tree
return tree;
};
// Function to perform the level-order traversal
void levelorder(struct treenode* root){
// If the root is NULL
if (root == NULL)
return;
// Use queue for traversal
queue<treenode*> q;
// Print the root's value and push it into the queue
cout << root->info << " ";
q.push(root);
// Iterate until queue is non-empty
while (!q.empty()) {
// Get the front node
root = q.front();
q.pop();
// If the root has the left child
if (root->left) {
cout << root->left->info<< " ";
q.push(root->left);
}
// If the root has the right child
if (root->right) {
cout << root->right->info<< " ";
q.push(root->right);
}
}
cout << endl;
}
// Driver Code
int main(){
// Root Node
struct treenode* root = NULL;
// Function Call
root = create();
// Perform Inorder Traversal
levelorder(root);
return 0;
}

Will be creating tree:


2
/ \
7 5
/ \ \
2 6 9
Output:
// C++ program to implement Mirror of Tree
#include <iostream>
using namespace std;
// structure of the binary tree
struct treenode {
// data part
int info;
// left and right node
struct treenode *left, *right;
};
// create function for binary tree creation
struct treenode* create(){
int data;
// variable of the structure
struct treenode* tree;
// dynamically allocating memory for tree-node
tree = new treenode;
cout << "\nEnter data to be inserted or type -1 for no
insertion : ";
// input from the user
cin >> data;
// condition for termination
if (data == -1)
return 0;
// assigning value from user into tree.
tree->info = data;
// recursively calling create function for left and right sub tree
cout << "Enter left child of : " << data;
tree->left = create();
cout << "Enter right child of : " << data;
tree->right = create();
// returning the created tree
return tree;
};
/*With the simple logic of recursion and swapping, we can create mirror tree. We
will swap the left-node and right-node of root node. We will use recursion and
start swapping from the bottom of the tree.*/
// function to form mirror image a tree
void mirrortree(struct treenode* root){
if (root != NULL) {
mirrortree(root->left);
mirrortree(root->right);
struct treenode* temp;
temp = root->left;
root->left = root->right;
root->right = temp;
}
return;
}
// function for the inorder traversal
void inorder(struct treenode* root){
if (root == NULL)
return;
inorder(root->left);
cout << root->info << " ";
inorder(root->right);
}
// Driver code
int main(){
// creating variable of the structure
struct treenode* root = NULL;
// calling create function to create tree
root = create();
mirrortree(root);
cout << "\nInorder of the mirror tree is = ";
inorder(root);
return 0;
}
Will be creating tree:
2
/ \
7 5
/ \ \
2 6 9
OUTPUT:

// C++ program for Searching for an Element


#include "bits/stdc++.h"
using namespace std;
// Structure of the Binary Tree
struct treenode{
int info;
struct treenode *left, *right;
};
// Function to create the Binary Tree
struct treenode* create(){
int data;
struct treenode* tree;
// Dynamically allocating memory for the tree-node
tree = new treenode;
cout << "\nEnter data to be inserted "<< "or type -1 for no
insertion : ";
// Input from the user
cin >> data;
// Termination Condition
if (data == -1)
return 0;
// Assign value from user into tree
tree->info = data;
// Recursively Call to create the left and the right sub tree
cout << "Enter left child of : " << data;
tree->left = create();
cout << "Enter right child of : " << data;
tree->right = create();
// Return the created Tree
return tree;
};
// Function to search an element in the given Binary Tree
int FindElement(struct treenode* root,int data){
// If the root is NULL
if (root == NULL)
return 0;
queue<treenode*> q;
struct treenode* temp;
if (!root)
return 0;
else {
// Push the root
q.push(root);
// Perform the level-order traversal
while (!q.empty()) {
// Get the root
root = q.front();
temp = root;
q.pop();
// If the node with value data exists then return 1
if (data == temp->info)
return 1;
// Recursively push the left and the right child of the
node
if (root->left)
q.push(root->left);
if (root->right)
q.push(root->right);
}
// Otherwise, not found
return 0;
}
}
// Driver Code
int main(){
int data;
// Root of the tree
struct treenode* root = NULL;
// Create the Tree
root = create();
cout << "\nEnter element to searched : ";
cin >> data;
// Function Call
if (FindElement(root, data) == 1)
cout << "\nElement is found";
else
cout << "Element is not found";
return 0;
}
/* Will be creating tree:
2
/ \
7 5
/ \ \
2 6 9
*/
OUTPUT:
14) Implementation of the following operations on binary search
tree (BST):
(a) Minimum key (b) Maximum key (c) Search for a given key (d)
Delete a node with given key
// C++ Program to implement binary search tree
#include <iostream>
using namespace std;
// Node structure for a Binary Search Tree
struct Node{
int data;
Node *left;
Node *right;
};
// Function to create a new Node
Node *createNode(int data){
Node *newNode = new Node();
newNode->data = data;
newNode->left = newNode->right = nullptr;
return newNode;
}
// Function to insert a node in the BST
Node *insertNode(Node *root, int data){
if (root == nullptr)// If the tree is empty, return a
return createNode(data);
// Otherwise, recur down the tree
if (data < root->data)
root->left = insertNode(root->left, data);
else if (data > root->data)
root->right = insertNode(root->right, data);
// return the (unchanged) node pointer
return root;
}
// Function to do inorder traversal of BST
void inorderTraversal(Node *root){
if (root != nullptr){
inorderTraversal(root->left);
cout << root->data << " ";
inorderTraversal(root->right);
}
}
// Function to search a given key in a given BST
Node *searchNode(Node *root, int key){
// Base Cases: root is null or key is present at root
if (root == nullptr || root->data == key)
return root;
// Key is greater than root's key
if (root->data < key)
return searchNode(root->right, key);
// Key is smaller than root's key
return searchNode(root->left, key);
}
// Function to find the inorder successor
Node *minValueNode(Node *node){
Node *current = node;
// loop down to find the leftmost leaf
while (current && current->left != nullptr)
current = current->left;
return current;
}
// Function to delete a node
Node *deleteNode(Node *root, int data){
if (root == nullptr)
return root;
// If the data to be deleted is smaller than the root's
// data, then it lies in the left subtree
if (data < root->data)
root->left = deleteNode(root->left, data);
// If the data to be deleted is greater than the root's
// data, then it lies in the right subtree
else if (data > root->data)
root->right = deleteNode(root->right, data);
// if data is same as root's data, then This is the node
// to be deleted
else{
// node with only one child or no child
if (root->left == nullptr){
Node *temp = root->right;
delete root;
return temp;
}
else if (root->right == nullptr){
Node *temp = root->left;
delete root;
return temp;
}
// node with two children: Get the inorder successor
// (smallest in the right subtree)
Node *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 function to demonstrate the operations of BST
int main(){
Node *root = nullptr;
// create a BST
root = insertNode(root, 50);
root = insertNode(root, 30);
root = insertNode(root, 20);
root = insertNode(root, 40);
root = insertNode(root, 70);
root = insertNode(root, 60);
root = insertNode(root, 80);
// Print the inorder traversal of a BST
cout << "Inorder traversal of the given Binary Search "
"Tree is: ";
inorderTraversal(root);
cout << endl;
// delete a node in BST
root = deleteNode(root, 20);
cout << "After deletion of 20: ";
inorderTraversal(root);
cout << endl;
// Insert a node in BST
root = insertNode(root, 25);
cout << "After insertion of 25: ";
inorderTraversal(root);
cout << endl;
// Search a key in BST
Node *found = searchNode(root, 25);
// check if the key is found or not
if (found != nullptr)
cout << "Node 25 found in the BST." << endl;
else
cout << "Node 25 not found in the BST." << endl;
return 0;
}

OUTPUT:
[aiml2315@Aids ds]$ Inorder traversal of the given Binary
Search Tree is: 20 30 40 50 60 70 80
After deletion of 20: 30 40 50 60 70 80
After insertion of 25: 25 30 40 50 60 70 80
Node 25 found in the BST.

You might also like