Open In App

Unordered Multiset in C++ STL

Last Updated : 03 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In C++, unordered multiset is an unordered associative container that works similarly to an unordered set, but it can store multiple copies of the same value. It provides fast insert, delete and search operations using hashing, but the elements are not in any particular order.

Example:

C++
#include <iostream>
#include <unordered_set>
using namespace std;

int main() {
    
    // Creating unordered multiset of
    // integers
    unordered_multiset<int> ums =
                          {5, 1, 3, 4, 1};

    for (auto x : ums)
        cout << x << " ";
    return 0;
}

Output
5 1 1 3 4 

Explanation: In the above program, we create an unordered multiset ums with values: 5, 1, 3, 4 and 1. We can see from the output that there is no order of the elements and we were able to store 1 two times.

Syntax

Unordered multiset is defined as the std::unordered_multiset class template inside the <unordered_multiset> header file.

unordered_multiset<T> ums;

where,

  • T: Type of elements in the unordered multiset.
  • ums: Name assigned to the unordered multiset.

Declaration and Initialization

We can declare and initialize an unordered multiset in different ways as shown in the below example:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    
    // Create an empty unordered multiset
    unordered_multiset<int> ums1;
    
    // Create and initialize elements
    // using initialzer list
    unordered_multiset<int> ums2 =
                          {5, 3, 4, 1, 1};
    
    for(auto x : ums2)
        cout << x << " ";;
    return 0;
}

Output
5 3 4 1 1 

Explanation: In this example, we initialize an unordered multiset in three ways:

  • Statement unordered_multiset<int> ums1 creates an empty unordered multiset.
  • Statement unordered_multiset<int> ums2 = {2, 5, 3, 4, 1, 1} initialize the unordered multiset using initializer list.

Basic Operations

The basic operations of unordered multiset are shown below:

1. Inserting Elements

Elements can be inserted into an unordered multiset using the insert() method. The position of the element is determined by the hashing function so we cannot specify any position while inserting.

Example:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    unordered_multiset<int> ums;
    
    // Insert elements using insert()
    ums.insert(5);
    ums.insert(1);
    ums.insert(3);
    ums.insert(1);
    ums.insert(2);
    ums.insert(4);
    
    for (auto x : ums) cout << x << ' ';
    return 0;
}

Output
4 2 5 1 1 3 

2. Accessing Elements

An unordered multiset does not allow direct access to elements by index as accessing elements is not the primary operation of this container. However, we have to increment or decrement iterator obtained from begin() or end() methods respectively to access the element by position. This can also be done with the help of next() or advance() function.

Example:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    unordered_multiset<int> ums =
                    {5, 1, 3, 2, 4, 1};

    // Accessing element using iterator
    auto it = next(ums.begin(), 2);
    cout << *it;
    return 0;
}

Output
3

Explanation: In the above program, iterator it accesses the third element by advancing begin() by 2 positions using next().

3. Updating Elements

Unordered multiset does allow changing the value of the accessed elements as it may disrupt the container functions.

4. Finding Elements

It is the primary operation for which this container is optimized for. The find() method provides fast search of any element by value. This function returns iterator to the element if found, otherwise returns iterator to the end().

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    unordered_multiset<int> ums =
                     {5, 1, 3, 4, 1};
    
    // Finding 3
    auto it = ums.find(3);
    
    if (it != ums.end()) cout << *it;
    else cout << "Element not Found!";
    return 0;
}

Output
3

5. Traversing

We can traverse unordered multiset either using range-based for loop or using begin() and end() iterator.

Example:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    unordered_multiset<int> ums =
                    {5, 1, 3, 4, 1};
    
    // Using range-based for loop
    for(auto x : ums)
        cout << x << " ";
    cout << "\n";
    
    return 0;
}

Output
5 1 1 3 4 

6. Deleting Elements

We can use erase() method to delete elements from unordered multiset. It deletes all occurrences of an elements if we provide the value of the element. If we provide iterator of the element, it deletes only that value from the unordered multiset.

Example:

C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    unordered_multiset<int> ums =
                       {5, 1, 3, 2, 4, 1};

    // Delete all occurrences of element 1
    ums.erase(1);
    
    // Delete 2 using iterator
    ums.erase(ums.find(2));
    
   for (auto x: ums) cout << x << " ";
    return 0;
}

Output
4 3 5 

Explanation: In the above program,

  • ums.erase(1) deletes all occurrences of the element 1 from the set.
  • ums.erase(ums.find(2)) deletes one occurrence of the element 2 by using an iterator returned from find(2).

Time Complexity

The below table lists the time complexity of the above operations on unordered multiset:

OperationTime Complexity
Inserting elementsO(1) average
Deleting elementsO(1) average
Finding elements by valueO(1) average
Accessing elements by positionO(n)
Traverse the multisetO(n)

Other Common Operations

Unordered multiset is used in many situations for different purposes. The following examples’ aim is to help you master unordered multiset beyond the basics:

Internal Working

In C++, unordered multiset container provides the built-in implementation of a hash table data structure. Each element is hashed to a bucket and elements with the same hash value are stored in the same bucket. These buckets are generally implemented as linked lists. This allows for fast access and insertion, basically with constant time complexity (O(1)) for operations like insert(), erase(), and find(). However, due to hash collisions, the time complexity can degrade to O(n) in the worst case.

Unordered Multiset vs Multiset

Primary difference between unordered multiset and multiset is shown below:

  • Unordered multiset allows multiple occurrences of the same element and does not maintain the order of the elements. Elements are stored based on their hash values.
  • Multiset allows multiple occurrences of the same element and also elements store in sorted way either ascending or descending.

All Member Functions

Following is the list of all member functions of std::unordered_multiset class in C++:

FunctionDescription
insert()Inserts new elements in the unordered multiset.
begin()Returns an iterator pointing to the first element in the container or the first element in one of its buckets.
end()Returns an iterator pointing to the position immediately after the last element in the container or to the position immediately after the last element in one of its buckets.
empty()It returns true if the unordered multiset container is empty. Otherwise, it returns false.
find()Returns an iterator that points to the position which has the element.
cbegin()Returns a constant iterator pointing to the first element in the container or the first element in one of its buckets.
cend()Returns a constant iterator pointing to the position immediately after the last element in the container or immediately after the last element in one of its buckets.
equal_range()Returns the range in which all the elements are equal to a given value.
emplace()Inserts a new element in the unordered multiset container.
clear()Clears the contents of the unordered multiset container.
count()Returns the count of elements in the unordered multiset container which is equal to a given value.
size()The size() method of unordered multiset is used to count the number of elements of unordered set it is called with.
max_sizeThe max_size() of unordered multiset takes the maximum number of elements that the unordered multiset container is able to hold.
swap()Swaps the contents of two unordered multiset containers.
erase()Used to remove either a single element or, all elements with a definite value or, a range of elements ranging from the start(inclusive) to the end(exclusive).
bucket()Returns the bucket number in which a given element is. Bucket size varies from 0 to bucket_count-1.
bucket_size()Returns the number of elements in the bucket that has the element val.
reserve()The reverse() function of unordered multiset sets the number of buckets in the container (bucket count) to the most appropriate to contain at least n elements.
max_bucket_count()Returns the maximum number of buckets that the unordered multiset container can have.
load_factor()Returns the current load factor in the unordered multiset container.
max_load_factor()Returns the maximum load factor of the unordered multiset container.
bucket_count()Returns the total number of buckets in the unordered multiset container.
hash_function()This hash function is a unary function that takes a single argument only and returns a unique value of type size_t based on it.
rehash()Sets the number of buckets in the container to N or more.
key_eq()Returns a boolean value according to the comparison.
emplace_hint()Inserts a new element in the unordered multiset container.
get_allocatorThis function gets the stored allocator object and returns the allocator object used to construct the container.


Practice Tags :

Similar Reads