目录
1. 关联式容器
在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、 forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面 存储的是元素本身。那什么是关联式容器?它与序列式容器有什么区别?
关联式容器(associative containers)与序列式容器(sequential containers)是C++标准库中的两种不同类型的容器。
序列式容器是一种按照元素在容器中的位置进行存储和访问的容器。它们按照元素的插入顺序进行存储,并且支持顺序访问元素的特性。常见的序列式容器有:vector、deque、list和forward_list。
关联式容器是一种按照键值(key)进行存储和访问的容器。它们通过一对键值对(key-value pair)来存储元素,其中的键(key)用于唯一标识元素,并且支持根据键值进行快速检索的特性。常见的关联式容器有:set、multiset、map和multimap。
2. 键值对pair
用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。比如:现在要建立一个英汉互译的字典,那该字典中必然 有英文单词与其对应的中文含义,而且,英文单词与其中文含义是一一对应的关系,即通过该应该单词,在词典中就可以找到与其对应的中文含义。
SGI-STL中关于键值对的定义:
template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first; //key
T2 second; //value
//构造函数
pair() : first(T1()), second(T2())
{}
pair(const T1& a, const T2& b) : first(a), second(b)
{}
};
所以,C++ 中的键值对是通过 pair 类来表示的。
pair包含两个成员变量first和second,分别表示两个值的类型T1和T2。我们可以使用pair来创建键值对或者存储两个值。
int main()
{
// 创建一个键值对
pair<int, string> student(1, "Alice");
// 访问键值对的值
cout << student.first << ": " << student.second << endl;
// 修改键值对的值
student.first = 2;
student.second = "Bob";
// 创建临时键值对
pair<int, string> temp(3, "Charlie");
// 使用make_pair创建临时键值对
auto temp2 = make_pair(4, "David");
return 0;
}
pair可以用于存储键值对,也可以用于其他需要存储两个不同类型的值的场景。它在C++标准库中被广泛使用,例如在map、unordered_map等容器中存储键值对。
此外,库中还设计了一个函数模板 make_pair, 可以根据传入的参数,去调用 pair 构建对象并返回。
template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& t1, T2&& t2);
make_pair接受两个参数t1和t2,并将它们打包为一个pair对象并返回。make_pair会自动推导出pair对象中的第一个值和第二个值的类型。
以下是使用make_pair创建pair对象的示例:
int main()
{
// 创建pair对象
auto p1 = make_pair(1, "Alice");
// 创建pair对象并指定类型
pair<int, string> p2 = make_pair(2, "Bob");
// 输出pair对象的值
cout << p1.first << ": " << p1.second << endl;
cout << p2.first << ": " << p2.second << endl;
return 0;
}
make_pair可以方便地创建pair对象,无需显式指定类型,编译器会根据参数类型进行类型推导。它常用于在容器中插入键值对或者返回键值对的函数中。
3. 树形结构的关联式容器
根据应用场景的不桶,STL总共实现了两种不同结构的管理式容器:树型结构与哈希结构。树型结 构的关联式容器主要有四种:map、set、multimap、multiset。这四种容器的共同点是:使用平衡搜索树(即红黑树)作为其底层结果,容器中的元素是一个有序的序列。下面一依次介绍每一 个容器。
4. set
4.1 set的介绍
set容器:它是一个关联容器,用于存储唯一的元素,且按照一定的顺序排列。set容器中的元素按照默认的排序顺序存储,或者可以通过自定义的排序函数进行排序。set容器实际上是一个红黑树(red-black tree)实现的。
set容器中的元素会自动按照键的顺序进行排序,保持元素的有序性。同时,set容器中的元素是唯一的,即相同的元素只能出现一次。
4.2 set的构造
set容器可以使用多种方式进行构造,以下是常见的构造方式:
1. 默认构造函数:
set<int> mySet; // 创建一个空的set容器
2. 使用迭代器构造:
vector<int> vec = {1, 2, 3, 4, 5};
set<int> mySet(vec.begin(), vec.end()); // 使用vec容器中的元素构造set容器
3. 使用初始化列表构造:
set<int> mySet = {1, 2, 3, 4, 5}; // 使用初始化列表中的元素构造set容器
4. 拷贝构造函数: