一篇搞懂C++ STL 关联容器std::set


前言

C++ 标准模板库(STL)提供了多种容器类,用于高效地处理各种数据。std::set 是 STL 中的一种关联容器,用于存储唯一的有序元素。它利用平衡二叉树结构(如红黑树)来实现高效的元素查找、插入和删除操作。本文将详细介绍 std::set 的构造函数、成员函数、以及如何使用它。我们还将解释什么是关联容器,并提供示例代码以演示 std::set 的用法。


关联容器概述

关联容器 是 STL 中的一类容器,它们通过某种数据结构(通常是平衡树)来实现高效的元素查找、插入和删除。与顺序容器(如 std::vectorstd::deque)不同,关联容器不保证元素的存储顺序,而是按照特定的规则(如排序或哈希)组织元素。常见的关联容器包括 std::setstd::map

std::set 概述

std::set 是一个关联容器,用于存储唯一的、有序的元素。它的元素按照键值自动排序,且不允许重复。std::set 通过内部的平衡二叉树实现高效的查找、插入和删除操作。

std::set 的构造函数

  1. 默认构造函数

    函数原型

    set();
    

    作用:创建一个空的 std::set

    返回值:无返回值。

    示例代码

    std::set<int> s;
    
  2. 初始化列表构造函数

    函数原型

    set(std::initializer_list<value_type> init, const Compare& comp = Compare(), const Allocator& alloc = Allocator());
    

    作用:使用初始化列表创建 std::set

    参数

    • init:用于初始化 std::set 的元素列表。
    • comp:用于排序的比较器。
    • alloc:分配器。

    返回值:无返回值。

    示例代码

    std::set<int> s = {1, 2, 3, 4, 5};
    
  3. 拷贝构造函数

    函数原型

    set(const set& other);
    

    作用:使用另一个 std::set 对象初始化新对象。新对象将是原对象的副本。

    参数

    • other:另一个 std::set 对象。

    返回值:无返回值。

    示例代码

    std::set<int> s1 = {1, 2, 3};
    std::set<int> s2(s1);
    
  4. 移动构造函数

    函数原型

    set(set&& other) noexcept;
    

    作用:使用另一个 std::set 对象的资源初始化新对象,并将原对象置于有效但未指定的状态。

    参数

    • other:另一个 std::set 对象(右值)。

    返回值:无返回值。

    示例代码

    std::set<int> s1 = {1, 2, 3};
    std::set<int> s2(std::move(s1));
    
  5. 范围构造函数

    函数原型

    template <class InputIterator>
    set(InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& alloc = Allocator());
    

    作用:通过指定范围的迭代器创建 std::set

    参数

    • first:起始迭代器。
    • last:结束迭代器。
    • comp:用于排序的比较器。
    • alloc:分配器。

    返回值:无返回值。

    示例代码

    std::vector<int> v = {1, 2, 3, 4, 5};
    std::set<int> s(v.begin(), v.end());
    

std::set 的成员函数

1. std::set::insert

函数原型

std::pair<iterator, bool> insert(const value_type& value);
iterator insert(iterator hint, const value_type& value);
template <class InputIterator>
void insert(InputIterator first, InputIterator last);

作用:插入元素到 std::set 中。如果元素已存在,则插入操作失败。

参数

  • value:要插入的元素。
  • hint:一个迭代器,用于提示插入的位置(仅用于重载版本)。
  • first, last:迭代器范围,用于批量插入(仅用于重载版本)。

返回值

  • 插入成功时,返回一个包含插入位置的迭代器和一个布尔值(表示是否插入成功)。

示例代码

std::set<int> s;
s.insert(10); // 插入单个元素
s.insert(s.begin(), 20); // 插入元素到指定位置
std::vector<int> v = {30, 40};
s.insert(v.begin(), v.end()); // 批量插入

2. std::set::erase

函数原型

size_type erase(const value_type& value);
iterator erase(iterator pos);
iterator erase(iterator first, iterator last);

作用:删除指定元素或范围内的元素。

参数

  • value:要删除的元素。
  • pos:要删除元素的位置。
  • first, last:要删除元素的范围。

返回值

  • 删除成功的元素数量(单个元素删除),或删除的迭代器范围(范围删除)。

示例代码

std::set<int> s = {1, 2, 3, 4, 5};
s.erase(3); // 删除单个元素
s.erase(s.begin()); // 删除指定位置的元素
s.erase(s.begin(), s.end()); // 删除范围内的元素

3. std::set::find

函数原型

iterator find(const value_type& value);
const_iterator find(const value_type& value) const;

作用:查找 std::set 中是否包含指定的元素。

参数

  • value:要查找的元素。

返回值:指向元素的迭代器。如果未找到,返回 end() 迭代器。

示例代码

std::set<int> s = {1, 2, 3, 4, 5};
auto it = s.find(3); // 查找元素
if (it != s.end()) {
    std::cout << "Element found: " << *it << std::endl;
}

4. std::set::count

函数原型

size_type count(const value_type& value) const;

作用:返回 std::set 中指定元素的数量。由于 std::set 不允许重复元素,返回值为 0 或 1。

参数

  • value:要计数的元素。

返回值:指定元素的数量(0 或 1)。

示例代码

std::set<int> s = {1, 2, 3, 4, 5};
std::cout << "Count of 3: " << s.count(3) << std::endl; // 输出 1
std::cout << "Count of 10: " << s.count(10) << std::endl; // 输出 0

5. std::set::clear

函数原型

void clear();

作用:清空 std::set 中的所有元素。

返回值:无返回值。

示例代码

std::set<int> s = {1, 2, 3, 4, 5};
s.clear(); // 清空 set

6. std::set::empty

函数原型

bool empty() const;

作用:检查 std::set 是否为空。

返回值:如果容器为空,返回 true;否则返回 false

示例代码

std::set<int> s = {1, 2, 3};
if (s.empty()) {


    std::cout << "Set is empty." << std::endl;
} else {
    std::cout << "Set is not empty." << std::endl;
}

7. std::set::size

函数原型

size_type size() const;

作用:返回 std::set 中的元素数量。

返回值:容器中元素的数量。

示例代码

std::set<int> s = {1, 2, 3, 4, 5};
std::cout << "Size of set: " << s.size() << std::endl; // 输出 5

8. std::set::beginstd::set::end

函数原型

iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;

作用:返回指向容器第一个元素和最后一个元素之后的迭代器。

返回值:指向容器第一个元素和最后一个元素之后的迭代器。

示例代码

std::set<int> s = {1, 2, 3, 4, 5};
for (auto it = s.begin(); it != s.end(); ++it) {
    std::cout << *it << " "; // 输出 1 2 3 4 5
}
std::cout << std::endl;

9. std::set::rbeginstd::set::rend

函数原型

reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;

作用:返回指向容器最后一个元素和第一个元素之前的反向迭代器。

返回值:指向容器最后一个元素和第一个元素之前的反向迭代器。

示例代码

std::set<int> s = {1, 2, 3, 4, 5};
for (auto rit = s.rbegin(); rit != s.rend(); ++rit) {
    std::cout << *rit << " "; // 输出 5 4 3 2 1
}
std::cout << std::endl;

总结

std::set 是一种高效的关联容器,用于存储唯一的、有序的元素。它通过内部的平衡树实现快速的查找、插入和删除操作。std::set 不允许重复元素,且大小在运行时不可调整。了解 std::set 的各种构造函数和成员函数,可以帮助你在需要存储有序且唯一元素的场景中选择合适的容器。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人才程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值