C++关联容器概念,相关操作和代码示例

发布时间:2023年12月22日

关联容器类型

map

std::map 是一个基于红黑树的有序关联容器,它存储的是键值对。每个键都是唯一的,并且容器会根据键来排序元素。在 std::map 中,查找、插入和删除操作的时间复杂度通常是 O(log n),其中 n 是容器中元素的数量。由于它是基于红黑树实现的,所以元素始终是有序的。

set

std::set 也是一个基于红黑树的有序关联容器,但它只存储唯一的键,没有与键相关联的值。和 std::map 一样,std::set 中的元素按照键排序,且查找、插入和删除操作的时间复杂度也是 O(log n)。

unordered_map

std::unordered_map 是一个基于哈希表的无序关联容器,它存储键值对,但不按任何特定顺序排序元素。在哈希表中,元素的位置由其键的哈希值决定。理想情况下,std::unordered_map 中的查找、插入和删除操作的平均时间复杂度是 O(1)。但在最坏的情况下(例如当哈希冲突非常频繁时),这些操作的时间复杂度可能退化到 O(n)。

unordered_set

std::unordered_set 是一个基于哈希表的无序关联容器,它只存储唯一的键。与 std::unordered_map 类似,std::unordered_set 不保持元素的顺序,查找、插入和删除操作的平均时间复杂度也是 O(1),但在最坏情况下可能退化到 O(n)。
在这里插入图片描述

补充:pair类型

std::pair 在关联容器(如 std::mapstd::multimap)中扮演着重要角色。在这些容器中,元素是以键值对的形式存储的,其中键和值分别对应 std::pairfirstsecond 成员。例如,std::map 容器的元素类型就是 std::pair<const Key, T>,其中 Key 是键的类型,T 是值的类型。

当你向 std::map 插入元素时,通常会提供一个 std::pair 对象,或者使用 std::make_pair

std::map<int, std::string> myMap;
myMap.insert(std::make_pair(1, "One"));
myMap[2] = "Two";

当你从 std::map 获取元素时,也会得到一个 std::pair 类型的对象:

for (const auto& kv : myMap) {
    std::cout << "Key: " << kv.first << ", Value: " << kv.second << std::endl;
}

在这里插入图片描述

关联容器操作

insert 方法

insert 方法用于向关联容器中添加新元素。它有几种重载形式:

  • 单个元素插入:可以插入一个由 std::pair 构成的键值对。如果键已经存在,插入将不会进行,因为 mapset 的键是唯一的。
std::map<int, std::string> m;
m.insert(std::make_pair(10, "ten"));
  • 初始化列表插入:可以插入一个初始化列表中的多个元素。
m.insert({{1, "one"}, {2, "two"}});
  • 范围插入:可以插入另一个相同类型容器的元素范围。
std::map<int, std::string> m2;
m2.insert(m.begin(), m.end()); // 将 m 中的所有元素插入 m2

erase 方法

erase 方法用于从关联容器中删除元素,也有几种重载形式:

  • 通过迭代器删除:删除指定迭代器位置的元素。
auto it = m.find(10);
if (it != m.end()) {
    m.erase(it);
}
  • 通过键删除:删除具有特定键的元素(对于 multimapmultiset,会删除所有具有该键的元素)。
m.erase(10); // 删除键为 10 的元素
  • 通过迭代器范围删除:删除指定迭代器范围内的所有元素。
m.erase(m.begin(), m.find(10)); // 删除到键为 10 的元素之前的所有元素

find 方法

find 方法根据键来查找元素,如果找到,则返回指向该元素的迭代器;否则,返回指向容器 end 的迭代器。

auto it = m.find(10);
if (it != m.end()) {
    // 找到了键为 10 的元素
}

count 方法

count 方法返回具有特定键的元素数量。对于 setmap,结果要么是 0(未找到),要么是 1(找到)。对于 multisetmultimap,可以是任何非负整数,表示键出现的次数。

size_t numItems = m.count(10); // 返回键为 10 的元素数量

lower_bound 和 upper_bound 方法

这两个方法用于在有序关联容器(如 mapset)中查找特定键的边界。

  • lower_bound 返回指向第一个不小于给定键的元素的迭代器。
  • upper_bound 返回指向第一个大于给定键的元素的迭代器。
auto lb = m.lower_bound(10);
auto ub = m.upper_bound(10);

equal_range 方法

equal_range 返回一个由两个迭代器组成的 pair,表示特定键的范围。第一个迭代器等同于 lower_bound 的结果,第二个迭代器等同于 upper_bound 的结果。

auto range = m.equal_range(10);
// range.first -> lower_bound
// range.second -> upper_bound

下标操作符 []

对于 std::mapstd::unordered_map,可以使用下标操作符 [] 来访问元素。如果键不存在,将会插入一个具有该键的新元素,并返回其值的引用。

std::map<int, std::string> m;
m[10] = "ten"; // 如果键 10 不存在,将创建新元素
std::string value = m[10]; // 访问键为 10 的元素的值

下标操作符不能用于 std::setstd::multiset,因为这些容器不存储键值对,只存储单一的键。

文章来源:https://blog.csdn.net/qq_46348508/article/details/135147838
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。