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
- We need ordered data.
- We would have to print/access the data (in sorted order).
- We need predecessor/successor of elements.
- Since set is ordered, we can use functions like binary_search(), lower_bound() and upper_bound() on set elements. These functions cannot be used on unordered_set().
- See advantages of BST over Hash Table for more cases.
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
// Program to print elements of set #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; } |
Elements of set in sorted order: 1 2 3 5 6 7
Implementation:
CPP
// Program to print elements of set #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; } |
Elements 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
// Program to print inorder predecessor and inorder successor #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); // get iterator of key // If iterator is at first position // Then, it doesn't have predecessor if (it == s.begin()) { cout << "No predecessor\n" ; return ; } --it; // get previous element 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); // get iterator of key ++it; // get next element // Iterator points to NULL (Element does // not exist) 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; } |
predecessor 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. |
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!