📜  C++ STL-Multiset(1)

📅  最后修改于: 2023-12-03 15:29:50.522000             🧑  作者: Mango

C++ STL-Multiset

Multiset 是 C++ STL (Standard Template Library) 中的一种容器,它可以存储相同类型的元素,不同的是 Multiset 中的元素可以重复出现。Multiset 实现了一个红黑树(Red-Black Tree),用于对元素进行排序,因此访问元素的速度非常快。Multiset 具有以下特点:

  • 允许重复元素。
  • 元素默认按升序排序,也可以通过传入比较函数改为自定义排序。
  • 插入、删除元素的时间复杂度均为 O(log n)。
定义 Multiset

定义 Multiset 与定义其他 STL 容器相似,使用时需包含头文件 #include <set>

std::multiset<int> s; // 定义一个空的 multiset,元素为 int 类型,默认按升序排序
插入元素

Multiset 中插入元素使用 insert 函数,该函数的返回值为插入的迭代器。

std::multiset<int> s;
s.insert(3);
s.insert(2);
s.insert(5);
// s 中元素为 {2, 3, 5}
删除元素

Multiset 中删除元素可使用 erase 函数,该函数有多种重载形式。

  • 删除指定元素:传入需要删除的元素值。
  • 删除指定范围内的元素:传入范围的起始迭代器和结束迭代器。
  • 删除指定迭代器指向的元素。
std::multiset<int> s = {1, 2, 2, 3, 4, 5};
s.erase(2); // 删除元素 2
// s 中元素为 {1, 3, 4, 5}

auto iter = s.find(3);
s.erase(iter); // 删除迭代器指向的元素 3
// s 中元素为 {1, 4, 5}

s.erase(s.begin(), s.find(4)); // 删除范围 [begin(), find(4)) 中的元素
// s 中元素为 {4, 5}
访问元素

Multiset 中访问元素可使用迭代器,因为 Multiset 其本质是一个红黑树,因此元素默认按照升序排序。若需要访问第一个元素或最后一个元素,可使用 begin()end() 函数返回的迭代器,也可使用 front()back() 函数返回的元素。

std::multiset<int> s = {2, 3, 5, 5, 6};
auto iter = s.find(5);
std::cout << "第一个元素为 " << *s.begin() << '\n'; // 输出 "第一个元素为 2"
std::cout << "最后一个元素为 " << *s.rbegin() << '\n'; // 输出 "最后一个元素为 6"
std::cout << "查找元素 5 出现次数为 " << s.count(5) << '\n'; // 输出 "查找元素 5 出现次数为 2"
s.erase(iter); // 删除第一个出现的元素 5
std::cout << "第一个元素为 " << *s.begin() << '\n'; // 输出 "第一个元素为 2"
std::cout << "查找元素 5 出现次数为 " << s.count(5) << '\n'; // 输出 "查找元素 5 出现次数为 1"
自定义排序

Multiset 中元素的排序默认为升序排序,如果需要自定义排序方式,可以通过传入比较函数实现。比较函数需要满足严格弱序(Strict Weak Ordering)的条件。

  • 反自然排序:通过构造函数传入左闭右开的反迭代器作为比较函数,可以实现降序排序。
struct compare {
    bool operator()(const int& a, const int& b) {
        return a > b;
    }
};
std::multiset<int, compare> s = {2, 3, 5, 5, 6};
// s 中元素为 {6, 5, 5, 3, 2}
总结

Multiset 是 C++ STL 中一个有用的容器,可用于存储重复元素并自动进行排序,访问速度快效率高。Multiset 的使用方式与其他 STL 容器大同小异,只需注意元素重复和排序相关的特性即可。