Build a custom Map using Header file in C++
Last Updated :
03 Apr, 2023
Maps are associative containers that store elements in a mapped fashion. Each element has a key value and a mapped value. No two mapped values can have the same key values. Maps are implemented by self-balancing search trees. In C++ STL it uses Red-Black Tree.
Here we are going to implement a custom Map class which has an integer value as the key and the value stored corresponding to any key is also of integer type.
We will implement it using the AVL tree. To implement the map, we will first create a header file which will incorporate the functionalities of a map class. Below is the basic structure of the Map class:
Structure of Map class:
The structure of the AVL tree depends upon the structure of the node:
- Each node has pointers for the left child, the right child, and the parent.
- Each node has three values first (which is the key), second (which is the value to the corresponding key) and depth (height of the subtree for the node).
- The map class also has a static value cnt which stores the number of elements present in the map and a static node root, which is the root of the tree.
Store this in a header file (say map.h)
C++
class Map {
static class Map* root;
// Number of elements in the map
static int cnt;
// Left child, right child and parent
Map *left, *right, *par;
// First is key, second is value
// and depth is height of the subtree
// for the given node
int first, second, depth;
};
Functions/Operations To Be Implemented Using Custom Map
We will cover the following functionalities and methods in our map:
- insert()
- find()
- update()
- accessing any key
- erase()
- count()
- size()
- empty()
- clear()
- iterate the map
The methods and functionalities are discussed below:
1. insert():
This method is used to insert a key-value pair in the map. There are two insert() methods used here.
One is made public and it takes two parameters:
- first - It is the key
- second - It is the respective value of the key
Syntax:
map.insert(first, second);
Below is the implementation of this method
C++
void insert(int first, int second)
{
Map* temp = iterator(first);
// If element doesnot exist already
if (temp == nullptr)
insert(first)->second = second;
// If element exists already update it
else
temp->second = second;
}
Time Complexity: O(logN) where N is the size of map
The other one is made private. This method is called inside the operator overloading function of [].
- It takes only one parameter: first (It is the key).
- Creates the new node with "first" as the key and returns the instance of the node.
Syntax:
map[first] = second;
Below is the implementation of this method:
C++
Map* insert(int first)
{
// Increase the number of elements
cnt++;
Map* newnode = create(first);
// If empty tree simply create the root
if (root == nullptr) {
root = newnode;
return root;
}
Map *temp = root, *prev = nullptr;
while (temp != nullptr) {
prev = temp;
if (first < temp->first)
temp = temp->left;
else if (first > temp->first)
temp = temp->right;
else {
free(newnode);
// If element already exists
// decrease the count
cnt--;
// If the key is found then it is
// returned by reference so that it is
// updatable
return temp;
}
}
if (first < prev->first)
prev->left = newnode;
else
prev->right = newnode;
newnode->par = prev;
// Once inserted Check and balance the tree
// at every node in path from "newnode" to "root"
balance(newnode);
// New object is inserted and returned to
// initialize in the main during assignment
return newnode;
}
int& operator[](int key) {
return insert(key)->second;
}
Time Complexity: O(logN) where N is the size of the map
2. find():
It is used to find an element. This is a public method. It takes one parameter: first (which is the key) and returns the reference associated with the key. Internally it calls the private method iterator() to find the key
Syntax:
map.find(first);
Below is the implementation of the method
C++
Map* iterator(int first)
{
Map* temp = root;
while (temp != nullptr && temp->first != first) {
if (first < temp->first) {
temp = temp->left;
}
else {
temp = temp->right;
}
}
return temp;
}
Map* find(int first) {
return iterator(first);
}
Time Complexity: O(logN) where N is the size of the map.
3. update():
This value is used to update the value associated with a key. This is a public method. It takes two parameters:
- first: It is the key to be found.
- second: It is the new value of the key.
The function calls the iterator() function to get the instance of the key and updates the value associated to that key. If no such key exists then no operation is performed.
Syntax:
map.update(first, second);
Below is the implementation of the method.
C++
void update(int first, int second)
{
Map* temp = iterator(first);
if (temp != nullptr) {
temp->second = second;
}
}
Time Complexity: O(logN) where N is the size of the map
4. Accessing any key:
Any value can be accessed using the subscript operator[]. The concept of method overloading is used to implement the functionality. It is a public method and the search() function is called inside the overloading function. It takes one parameter: first (it is the value of the key)
Syntax:
map[first];
Below is the implementation of the method.
C++
const Map* iterator(int first) const
{
Map* temp = root;
while (temp != nullptr
&& temp->first != first) {
if (first < temp->first)
temp = temp->left;
else
temp = temp->right;
}
return temp;
}
const int search(int first) const
{
const Map* temp = iterator(first);
// If element exists with the given key
// return its value
if (temp != nullptr)
return temp->second;
// If element doesn't exist
// return default value of 0
return 0;
}
const int operator[](int key) const
{
// Search method is also qualified with const
return search(key);
}
Time Complexity: O(logN) where N is the size of the map.
5. erase():
It deletes the node with the given key and replaces it with either its in-order predecessor or in-order successor. It is a public method. It takes one parameter: first (it is the key whose value needs to be deleted). At the end of the function, it calls balance() method on the parent of that node which replaced the deleted node to balance the AVL tree.
Syntax:
map.erase(first);
Below is the implementation of the method.
C++
void erase(int first, Map* temp = root)
{
Map* prev = 0;
cnt--;
while (temp != 0 && temp->first != first) {
prev = temp;
if (first < temp->first) {
temp = temp->left;
}
else if (first > temp->first) {
temp = temp->right;
}
}
if (temp == nullptr) {
cnt++;
return;
}
if (cnt == 0 && temp == root) {
free(temp);
root = nullptr;
return;
}
Map* l = inorderPredecessor(temp->left);
Map* r = inorderSuccessor(temp->right);
if (l == 0 && r == 0) {
if (prev == 0) {
root = 0;
}
else {
if (prev->left == temp) {
prev->left = 0;
}
else {
prev->right = 0;
}
free(temp);
balance(prev);
}
return;
}
Map* start;
if (l != 0) {
if (l == temp->left) {
l->right = temp->right;
if (l->right != 0) {
l->right->par = l;
}
start = l;
}
else {
if (l->left != 0) {
l->left->par = l->par;
}
start = l->par;
l->par->right = l->left;
l->right = temp->right;
l->par = 0;
if (l->right != 0) {
l->right->par = l;
}
l->left = temp->left;
temp->left->par = l;
}
if (prev == 0) {
root = l;
}
else {
if (prev->left == temp) {
prev->left = l;
l->par = prev;
}
else {
prev->right = l;
l->par = prev;
}
free(temp);
}
balance(start);
return;
}
else {
if (r == temp->right) {
r->left = temp->left;
if (r->left != 0) {
r->left->par = r;
}
start = r;
}
else {
if (r->right != 0) {
r->right->par = r->par;
}
start = r->par;
r->par->left = r->right;
r->left = temp->left;
r->par = 0;
if (r->left != 0) {
r->left->par = r;
}
r->right = temp->right;
temp->right->par = r;
}
if (prev == 0) {
root = r;
}
else {
if (prev->right == temp) {
prev->right = r;
r->par = prev;
}
else {
prev->left = r;
r->par = prev;
}
free(temp);
}
balance(start);
return;
}
}
Time Complexity: O(logN) where N is the size of the map.
6. count():
This method returns the count of a key in the map. This is a public method. It takes one parameter: first(which is the key of value whose count should be found). This method calls the iterator() method internally and if no node is found then count is 0. Otherwise, count returns 1.
Syntax:
map.count(first);
Below is the implementation of the method.
C++
int count(int first)
{
Map* temp = iterator(first);
// If key is found
if (temp != nullptr)
return 1;
// If key is not found
return 0;
}
Time Complexity: O(logN) where N is the size of the map.
7. size():
This method returns the size of the map. This is a public method. This method does not take any parameter.
Syntax:
map.size();
Below is the implementation of the method.
C++
int size(void) {
return cnt;
}
Time Complexity: O(1)
8. empty():
This method checks if the map is empty or not. This is a public method. It returns true if the map is empty, else false. This method does not take any parameter.
Syntax:
map.empty();
Below is the implementation of the method.
C++
bool empty(void)
{
if (root == 0)
return true;
return false;
}
Time Complexity: O(1)
9. clear():
This method is used to delete the whole map in. This is a public method. It does not take any parameter. It takes the erase() method internally.
Syntax:
map.clear();
Below is the implementation of the method.
C++
void clear(void)
{
while (root != nullptr) {
erase(root->first);
}
}
Time Complexity: O(N * logN) where N is the size of the map
10. iterate():
This method is used to traverse the whole map. This is a public method. It also does not take any parameter. The nodes are printed in the sorted manner of key.
Syntax:
map.iterate();
Below is the implementation of the method.
C++
void iterate(Map* head = root)
{
if (root == 0)
return;
if (head->left != 0) {
iterate(head->left);
}
cout << head->first << ' ';
if (head->right != 0) {
iterate(head->right);
}
}
Time Complexity: O(N) where N is the size of the map
Creation of Custom Map Header
C++
// map.h
// C++ Program to implement Map class(using AVL tree)
// This is a header file map.h and doesnot contain main()
#include <iostream>
using namespace std;
// Custom Map Class
class Map {
private:
Map* iterator(int first)
{
// A temporary variable created
// so that we do not
// lose the "root" of the tree
Map* temp = root;
// Stop only when either the key is found
// or we have gone further the leaf node
while (temp != nullptr &&
temp->first != first) {
// Go to left if key is less than
// the key of the traversed node
if (first < temp->first) {
temp = temp->left;
}
// Go to right otherwise
else {
temp = temp->right;
}
}
// If there doesn't exist any element
// with first as key, nullptr is returned
return temp;
}
// Returns the pointer to element
// whose key matches first.
// Specially created for search method
// (because search() is const qualified).
const Map* iterator(int first) const
{
Map* temp = root;
while (temp != nullptr
&& temp->first != first) {
if (first < temp->first) {
temp = temp->left;
}
else {
temp = temp->right;
}
}
return temp;
}
// The const property is used to keep the
// method compatible with the method "const
// int&[]operator(int) const"
// Since we are not allowed to change
// the class attributes in the method
// "const int&[]operator(int) const"
// we have to assure the compiler that
// method called(i.e "search") inside it
// doesn't change the attributes of class
const int search(int first) const
{
const Map* temp = iterator(first);
if (temp != nullptr) {
return temp->second;
}
return 0;
}
// Utility function to return the Map* object
// with its members initialized
// to default values except the key
Map* create(int first)
{
Map* newnode = (Map*)malloc(sizeof(Map));
newnode->first = first;
newnode->second = 0;
newnode->left = nullptr;
newnode->right = nullptr;
newnode->par = nullptr;
// Depth of a newnode shall be 1
// and not zero to differentiate
// between no child (which returns
// nullptr) and having child(returns 1)
newnode->depth = 1;
return newnode;
}
// All the rotation operation are performed
// about the node itself
// Performs all the linking done when there is
// clockwise rotation performed at node "x"
void right_rotation(Map* x)
{
Map* y = x->left;
x->left = y->right;
if (y->right != nullptr) {
y->right->par = x;
}
if (x->par != nullptr && x->par->right == x) {
x->par->right = y;
}
else if (x->par != nullptr && x->par->left == x) {
x->par->left = y;
}
y->par = x->par;
y->right = x;
x->par = y;
}
// Performs all the linking done when there is
// anti-clockwise rotation performed at node "x"
void left_rotation(Map* x)
{
Map* y = x->right;
x->right = y->left;
if (y->left != nullptr) {
y->left->par = x;
}
if (x->par != nullptr && x->par->left == x) {
x->par->left = y;
}
else if (x->par != nullptr && x->par->right == x) {
x->par->right = y;
}
y->par = x->par;
y->left = x;
x->par = y;
}
// Draw the initial and final graph of each
// case(take case where every node has two child)
// and update the nodes depth before any rotation
void helper(Map* node)
{
// If left skewed
if (depthf(node->left)
- depthf(node->right) > 1) {
// If "depth" of left subtree of
// left child of "node" is
// greater than right
// subtree of left child of "node"
if (depthf(node->left->left)
> depthf(node->left->right)) {
node->depth
= max(depthf(node->right) + 1,
depthf(node->left->right) + 1);
node->left->depth
= max(depthf(node->left->left) + 1,
depthf(node) + 1);
right_rotation(node);
}
// If "depth" of right subtree
// of left child of "node" is
// greater than
// left subtree of left child
else {
node->left->depth = max(
depthf(node->left->left) + 1,
depthf(node->left->right->left)
+ 1);
node->depth
= max(depthf(node->right) + 1,
depthf(node->left->right->right) + 1);
node->left->right->depth
= max(depthf(node) + 1,
depthf(node->left) + 1);
left_rotation(node->left);
right_rotation(node);
}
}
// If right skewed
else if (depthf(node->left)
- depthf(node->right) < -1) {
// If "depth" of right subtree of right
// child of "node" is greater than
// left subtree of right child
if (depthf(node->right->right)
> depthf(node->right->left)) {
node->depth
= max(depthf(node->left) + 1,
depthf(node->right->left) + 1);
node->right->depth
= max(depthf(node->right->right) + 1,
depthf(node) + 1);
left_rotation(node);
}
// If "depth" of left subtree
// of right child of "node" is
// greater than that of right
// subtree of right child of "node"
else {
node->right->depth = max(
depthf(node->right->right) + 1,
depthf(node->right->left->right) + 1);
node->depth = max(
depthf(node->left) + 1,
depthf(node->right->left->left) + 1);
node->right->left->depth
= max(depthf(node) + 1,
depthf(node->right) + 1);
right_rotation(node->right);
left_rotation(node);
}
}
}
// Balancing the tree about the "node"
void balance(Map* node)
{
while (node != root) {
int d = node->depth;
node = node->par;
if (node->depth < d + 1) {
node->depth = d + 1;
}
if (node == root
&& depthf(node->left)
- depthf(node->right) > 1) {
if (depthf(node->left->left)
> depthf(node->left->right)) {
root = node->left;
}
else {
root = node->left->right;
}
helper(node);
break;
}
else if (node == root
&& depthf(node->left)
- depthf(node->right)
< -1) {
if (depthf(node->right->right)
> depthf(node->right->left)) {
root = node->right;
}
else {
root = node->right->left;
}
helper(node);
break;
}
helper(node);
}
}
// Utility method to return the
// "depth" of the subtree at the "node"
int depthf(Map* node)
{
if (node == nullptr)
// If it is null node
return 0;
return node->depth;
}
// Function to insert a value in map
Map* insert(int first)
{
cnt++;
Map* newnode = create(first);
if (root == nullptr) {
root = newnode;
return root;
}
Map *temp = root, *prev = nullptr;
while (temp != nullptr) {
prev = temp;
if (first < temp->first) {
temp = temp->left;
}
else if (first > temp->first) {
temp = temp->right;
}
else {
free(newnode);
cnt--;
return temp;
}
}
if (first < prev->first) {
prev->left = newnode;
}
else {
prev->right = newnode;
}
newnode->par = prev;
balance(newnode);
return newnode;
}
// Returns the previous node in
// inorder traversal of the AVL Tree.
Map* inorderPredecessor(Map* head)
{
if (head == nullptr)
return head;
while (head->right != nullptr) {
head = head->right;
}
return head;
}
// Returns the next node in
// inorder traversal of the AVL Tree.
Map* inorderSuccessor(Map* head)
{
if (head == nullptr)
return head;
while (head->left != nullptr) {
head = head->left;
}
return head;
}
public:
// Root" is kept static because it's a class
// property and not an instance property
static class Map* root;
static int cnt;
// "first" is key and "second" is value
Map *left, *right, *par;
int first, second, depth;
// overloaded [] operator for assignment or
// inserting a key-value pairs in the map
// since it might change the members of
// the class therefore this is
// invoked when any assignment is done
int& operator[](int key) {
return insert(key)->second;
}
// Since we have two methods with
// the same name "[]operator(int)" and
// methods/functions cannot be
// distinguished by their return types
// it is mandatory to include a const
// qualifier at the end of any of the methods
// This method will be called from a const
// reference to the object of Map class
// It will not be called for assignment
// because it doesn't allow to change
// member variables
// We cannot make it return by reference
// because the variable "temp" returned
// by the "search" method is
// statically allocated and therefore
// it's been destroyed when it is called out
const int operator[](int key) const
{
return search(key);
}
// Count returns whether an element
// exists in the Map or not
int count(int first)
{
Map* temp = iterator(first);
if (temp != nullptr) {
return 1;
}
return 0;
}
// Returns number of elements in the map
int size(void) {
return cnt;
}
// Removes an element given its key
void erase(int first, Map* temp = root)
{
Map* prev = nullptr;
cnt--;
while (temp != nullptr &&
temp->first != first) {
prev = temp;
if (first < temp->first) {
temp = temp->left;
}
else if (first > temp->first) {
temp = temp->right;
}
}
if (temp == nullptr) {
cnt++;
return;
}
if (cnt == 0 && temp == root) {
free(temp);
root = nullptr;
return;
}
Map* l
= inorderPredecessor(temp->left);
Map* r
= inorderSuccessor(temp->right);
if (l == nullptr && r == nullptr) {
if (prev == nullptr) {
root = nullptr;
}
else {
if (prev->left == temp) {
prev->left = nullptr;
}
else {
prev->right = nullptr;
}
free(temp);
balance(prev);
}
return;
}
Map* start;
if (l != nullptr) {
if (l == temp->left) {
l->right = temp->right;
if (l->right != nullptr) {
l->right->par = l;
}
start = l;
}
else {
if (l->left != nullptr) {
l->left->par = l->par;
}
start = l->par;
l->par->right = l->left;
l->right = temp->right;
l->par = nullptr;
if (l->right != nullptr) {
l->right->par = l;
}
l->left = temp->left;
temp->left->par = l;
}
if (prev == nullptr) {
root = l;
}
else {
if (prev->left == temp) {
prev->left = l;
l->par = prev;
}
else {
prev->right = l;
l->par = prev;
}
free(temp);
}
balance(start);
return;
}
else {
if (r == temp->right) {
r->left = temp->left;
if (r->left != nullptr) {
r->left->par = r;
}
start = r;
}
else {
if (r->right != nullptr) {
r->right->par = r->par;
}
start = r->par;
r->par->left = r->right;
r->left = temp->left;
r->par = nullptr;
if (r->left != nullptr) {
r->left->par = r;
}
r->right = temp->right;
temp->right->par = r;
}
if (prev == nullptr) {
root = r;
}
else {
if (prev->right == temp) {
prev->right = r;
r->par = prev;
}
else {
prev->left = r;
r->par = prev;
}
free(temp);
}
balance(start);
return;
}
}
// Returns if the map is empty or not
bool empty(void)
{
if (root == nullptr)
return true;
return false;
}
// Given the key of an element it updates
// the value of the key
void update(int first, int second)
{
Map* temp = iterator(first);
if (temp != nullptr) {
temp->second = second;
}
}
// Deleting the root of
// the tree each time until the map
// is not empty
void clear(void)
{
while (root != nullptr) {
erase(root->first);
}
}
// Inorder traversal of the AVL tree
void iterate(Map* head = root)
{
if (root == nullptr)
return;
if (head->left != nullptr) {
iterate(head->left);
}
cout << head->first << ' ';
if (head->right != nullptr) {
iterate(head->right);
}
}
// Returns a pointer/iterator to the element
// whose key is first
Map* find(int first) {
return iterator(first);
}
// Overloaded insert method,
// takes two parameters - key and value
void insert(int first, int second)
{
Map* temp = iterator(first);
if (temp == nullptr) {
insert(first)->second = second;
}
else {
temp->second = second;
}
}
};
Map* Map::root = nullptr;
int Map::cnt = 0;
Now save it as a header file say map.h to include it in other codes and implement the functionalities.
How to Execute the built Custom Map
Mentioned below is the procedure to be followed for implementing the map:
- First create a header file for map (map.h)
- Then store the header in the same folder in which the files implementing the map are stored.
- Include the map header in the files which will implement the map class.
- Compile and run the files implementing map.
Examples to show the use of Custom Map
The following programmes demonstrate the execution for the Map class by creating its functionalities.
Example 1: Programs to demonstrate the use of insert(), accessing any key and update() methods:
C++
#include "map.h"
#include <iostream>
using namespace std;
int main()
{
Map map;
// 1st way of insertion
map[132] = 3;
map[34] = 5;
map[42] = -97;
map[22] = 10;
map[12] = 42;
// 2nd way of insertion
map.insert(-2,44);
map.insert(0,90);
// accessing elements
cout<<"Value at key 42 before updating = "
<<map[42]<<endl;
cout<<"Value at key -2 before updating = "
<<map[-2]<<endl;
cout<<"Value at key 12 before updating = "
<<map[12]<<endl;
// Updating value at key 42
map[42] = -32;
// Updating value at key -2
map.insert(-2,8);
// Updating value at key 12
map.update(12,444);
// accessing elements
cout<<"Value at key 42 after updating = "
<<map[42]<<endl;
cout<<"Value at key -2 after updating = "
<<map[-2]<<endl;
cout<<"Value at key 12 after updating = "
<<map[12]<<endl;
cout<<"Value at key 0 = "<<map[0]<<endl;
return 0;
}
Output:
Example 2: Programme to demonstrate the use of erase(), clear() and iterate() methods:
C++
#include "map.h"
#include <iostream>
using namespace std;
int main()
{
Map map;
map[132] = 3;
map[34] = 5;
map[42] = -97;
map[22] = 10;
map[12] = 42;
// Iterating the Map elements before erasing 22
map.iterate();
map.erase(22);
// Iterating the Map elements after erasing 22
map.iterate();
// Deleting the whole map
map.clear();
// Now since there are zero elements
// in the Map the output is blank
cout<<"\nElements in Map after clear operation: ";
map.iterate();
return 0;
}
Output:
Example 3: Programme to demonstrate the use of find(), count(), empty() and size() methods:
C++
#include "map.h"
#include <iostream>
using namespace std;
int main()
{
Map map;
map[132] = 3;
map[34] = 5;
map[42] = -97;
cout<<"Value at 132 before updating = "
<<map[132]<<endl;
// Find method returns pointer to element
// whose key matches given key
Map *it = map.find(132);
// Updating the value at key 132
it->second = 98;
cout<<"Value at 132 after updating = "
<<map[132]<<endl;
// Count of an element which is not present
// in the map is 0
cout<<"Count of 77 = "<<map.count(77)<<endl;
// Count of an element which is present
// in the map is 1
cout<<"Count of 34 = "<<map.count(34)<<endl;
// Size of map/number of elements in map
cout<<"Map size = "<<map.size()<<endl;
// Map is not empty therefore returned 0
cout<<"Is map empty: "<<map.empty()<<endl;
// Clearing the map
map.clear();
// Map is empty therefore return 1
cout<<"Is map empty: "<<map.empty()<<endl;
return 0;
}
Output:
Similar Reads
Header Files in C++
C++ offers its users a variety of functions, one of which is included in header files. In C++, all the header files may or may not end with the ".h" extension unlike in C, Where all the header files must necessarily end with the ".h" extension. Header files in C++ are basically used to declare an in
6 min read
Implement a Dictionary using Trie
Implement a dictionary using Trie such that if the input is a string representing a word, the program prints its meaning from the prebuilt dictionary. Examples: Input: str = "map" Output: a diagrammatic representation of an area Input: str = "language" Output: the method of human communication Appro
9 min read
Searching in a Map Using std::map Functions in C++
In C++, map container is defined as std::map class template that also contains member function to search for an element on the bases of the keys. In this article, we will learn different methods to search for an element with the given key in C++.The recommended method to search for the given key in
4 min read
Default values in a Map in C++ STL
Prerequisite: Map in STLA map is a container which is used to store a key-value pair. By default, In Primitive datatypes such as int, char, bool, float in C/C++ are undefined if variables are not initialized, But a Map is initially empty when it is declared. When this map is accessed with the [ ] (e
2 min read
Set Position with seekg() in C++ File Handling
seekg() is a function in the iostream library that allows you to seek an arbitrary position in a file. It is included in the <fstream> header file and is defined for istream class. It is used in file handling to sets the position of the next character to be extracted from the input stream from
3 min read
How to create an unordered_map of pairs in C++?
Unordered Map does not contain a hash function for a pair like it has for int, string, etc, So if we want to hash a pair then we have to explicitly provide it with a hash function that can hash a pair. unordered_map can takes upto 5 arguments: Key : Type of key valuesValue : Type of value to be stor
3 min read
Why can templates only be implemented in the header file?
Templates are a powerful feature in C++ that allows for the creation of generic functions and classes. They provide a way to write code that works with different data types without sacrificing type safety. However, one notable restriction when working with templates is that their implementation is o
4 min read
Implementation on Map or Dictionary Data Structure in C
C programming language does not provide any direct implementation of Map or Dictionary Data structure. However, it doesn't mean we cannot implement one. In C, a simple way to implement a map is to use arrays and store the key-value pairs as elements of the array. How to implement Map in C? One appro
3 min read
Sorting a Hashmap according to values
Given the marks scored out of 100 by a student in subjects where the name of the subject is key and marks scored is the value. A HashMap is created using the subject name and respective marks as key-value pairs. The task is to sort the HashMap according to values i.e. according to marks.Example: Inp
9 min read
Check if a key is present in a C++ map or unordered_map
A C++ map and unordered_map are initialized to some keys and their respective mapped values. Examples: Input : Map : 1 -> 4, 2 -> 6, 4 -> 6Check1 : 5, Check2 : 4Output : 5 : Not present, 4 : PresentC++ implementation : map // CPP code to check if a // key is present in a map #include <bi
3 min read