C++ STL中set与unordered_set对比
| 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
- 我们需要有序的数据。
- 我们必须(按顺序)打印/访问这些数据。
- 我们需要元素的前身/继承者。
- 因为set是有序的,所以可以对set元素使用binary_search()、lower_bound()和upper_bound()等函数。这些函数不能用于unordered_set()。
使用unordered_set
- 我们需要保留一组不同的元素,不需要排序。
- 我们需要单元素访问i.e。没有遍历。
例子:
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
如果你想查看c++ STL中set和unordered_set的实现细节,请参阅set Vs Map。Set允许按有序顺序遍历元素,而Unordered_set不允许按有序顺序遍历元素。
// 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
// 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 5 1 6 3
前任/继任者 : Set可以修改为查找前任或继任者,而Unordered_set不允许查找前任/继任者。
// 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
让我们用表格的形式来看看它们的区别:
No. | set | unordered_set |
---|---|---|
1. | 它用于存储独特的元素。 | 它用于存储独特的元素。 |
2. | 集合是用二叉搜索树实现的。 | 它是用哈希表实现的 |
3. | 它按递增顺序存储元素。 | 它不按顺序存储元素。 |
4. | 我们可以使用迭代器遍历集合。 | 可以使用迭代器遍历unordered_set。 |
5. | 它包含在#include <set> 头文件中。 |
它包含在#include <unordered_set> 头文件中。 |