map/set 和 unordered_map/unordered_set 有什么区别与联系?
1、他们都可以实现key和key/value的搜索场景,并且·使用功能和使用基本一样·。
2、map/set的底层是使用红黑树实现的,遍历出来是有序的,增删查改的时间复杂度是O(logN)
3、unordered_map/unordered_set 的底层是使用哈希表实现的,遍历出来是无序的,增删查改的时间复杂度是O(1)
4、map和set是双向迭代器, unordered_map/unordered_set是单向迭代器。
代码实现证明
一、去重和是否有排序证明
二、时间复杂度对比
void test_unordered_map_set2()
{
unordered_set<int> us;
set<int> s;
const int n = 1000000;
vector<int> v;
v.reserve(n);
srand(time(0));
for (size_t i = 0; i < n; ++i)
{
v.push_back(rand());
}
size_t begin1 = clock();
for (size_t i = 0; i < n; i++)
{
us.insert(v[i]);
}
size_t end1 = clock();
cout << "unordered_set insert:" << end1 - begin1 << endl;
size_t begin2 = clock();
for (size_t i = 0; i < n; i++)
{
s.insert(v[i]);
}
size_t end2 = clock();
cout << "set insert:" << end2 - begin2 << endl;
size_t begin3 = clock();
for (size_t i = 0; i < n; i++)
{
us.find(v[i]);
}
size_t end3 = clock();
cout << "unordered_set find:" << end3 - begin3 << endl;
size_t begin4 = clock();
for (size_t i = 0; i < n; i++)
{
s.find(v[i]);
}
size_t end4 = clock();
cout << "set find:" << end4 - begin4 << endl;
size_t begin5 = clock();
for (size_t i = 0; i < n; i++)
{
us.erase(v[i]);
}
size_t end5 = clock();
cout << "unordered_set erase:" << end5 - begin5 << endl;
size_t begin6 = clock();
for (size_t i = 0; i < n; i++)
{
s.erase(v[i]);
}
size_t end6 = clock();
cout << "set erase:" << end6 - begin6 << endl;
}
可以看出,总体来说 unordered_map/unordered_set的速度较快,但对大的数据来说几乎没有太大差别。
对比性能来说,实际上,如果我们使用的环境支持C++11;那么 unordered_map/unordered_set效率还是高一些。