Differences :
| set | unordered_set
---------------------------------------------------------
Ordering | increasing order | no ordering
| (by default) |
Implementation | Self balancing BST | Hash Table
| like Red-Black Tree |
search time | log(n) | O(1) -> Average
| | O(n) -> Worst Case
Insertion time | log(n) + Rebalance | Same as search
Deletion time | log(n) + Rebalance | Same as search
Use set when
Use unordered_set when
- We need to keep a set of distinct elements and no ordering is required.
- We need single element access i.e. no traversal.
Examples:
set:
Input : 1, 8, 2, 5, 3, 9
Output : 1, 2, 3, 5, 8, 9
Unordered_set:
Input : 1, 8, 2, 5, 3, 9
Output : 9 3 1 8 2 5
If you want to look at implementation details of set and unordered_set in c++ STL, see Set Vs Map. Set allows to traverse elements in sorted order whereas Unordered_set doesn’t allow to traverse elements in sorted order.
Implementation:
CPP
#include <bits/stdc++.h>
using namespace std;
int main()
{
set< int > s;
s.insert(5);
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(7);
s.insert(2);
cout << "Elements of set in sorted order: \n" ;
for ( auto it : s)
cout << it << " " ;
return 0;
}
|
OutputElements of set in sorted order:
1 2 3 5 6 7
Implementation:
CPP
#include <bits/stdc++.h>
using namespace std;
int main()
{
unordered_set< int > s;
s.insert(5);
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(7);
s.insert(2);
cout << "Elements of unordered_set: \n" ;
for ( auto it : s)
cout << it << " " ;
return 0;
}
|
OutputElements of unordered_set:
2 7 3 6 5 1
Predecessor/Successor in Set: Set can be modified to find predecessor or successor whereas Unordered_set doesn’t allow to find predecessor/Successor.
Implementation:
CPP
#include <bits/stdc++.h>
using namespace std;
set< int > s;
void inorderPredecessor( int key)
{
if (s.find(key) == s.end()) {
cout << "Key doesn't exist\n" ;
return ;
}
set< int >::iterator it;
it = s.find(key);
if (it == s.begin()) {
cout << "No predecessor\n" ;
return ;
}
--it;
cout << "predecessor of " << key << " is=" ;
cout << *(it) << "\n" ;
}
void inorderSuccessor( int key)
{
if (s.find(key) == s.end()) {
cout << "Key doesn't exist\n" ;
return ;
}
set< int >::iterator it;
it = s.find(key);
++it;
if (it == s.end())
{
cout << "No successor\n" ;
return ;
}
cout << "successor of " << key << " is=" ;
cout << *(it) << "\n" ;
}
int main()
{
s.insert(1);
s.insert(5);
s.insert(2);
s.insert(9);
s.insert(8);
inorderPredecessor(5);
inorderPredecessor(1);
inorderPredecessor(8);
inorderSuccessor(5);
inorderSuccessor(2);
inorderSuccessor(9);
return 0;
}
|
Outputpredecessor of 5 is=2
No predecessor
predecessor of 8 is=5
successor of 5 is=8
successor of 2 is=5
No successor
Let us see the differences in a tabular form -:
| set | unordered_set |
1. | It is used to store the unique elements. | It is used to store the unique elements. |
2. | Sets are implemented using Binary search trees. | It is implemented using hash table |
3. | It stores the elements in increasing order. | It stores the element with no order. |
4. | We can traverse sets using iterators. | We can traverse unordered_set using iterators. |
5. | It is included in #include <set> header file. | It is included in #include <unordered_set> header file. |