C++进阶 —— multiset

本文详细介绍了C++标准库中的multiset容器,它是一个存储重复元素并保持排序的集合。multiset基于红黑树实现,提供快速的查找和迭代器遍历。文章列举了multiset的主要操作函数,包括插入、删除、查找等,并通过一个示例展示了如何使用multiset插入元素、遍历和删除元素。同时,还讨论了multiset与set的区别以及其时间复杂度特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一,multiset介绍

二,multiset使用


一,multiset介绍

  • multiset是按照特定顺序存储元素的容器,其中元素可以重复;
  • multiset中本身存储的就是<value,value>组成的键值对,value就是key,key就是value,类型为T;
  • multi元素的值不能在容器中进行修改(因为元素总是const的),但可以从容器中插入或删除;
  • multiset中的元素总是按照其内部比较规则(类型比较)所指示的特定严格弱排序准则进行排序;
  • multiset容器通过key访问单个元素的速度通常比unordered_multiset容器慢,但当使用迭代器遍历时会得到一个有序序列;
  • multiset底层结构为二叉搜索树(红黑树);

注:

  • multiset中在底层中存储的是<value,value>键值对;
  • multiset的插入接口中value即可;
  • 与set区别是,multiset中的元素可以重复,set中的value是唯一的;
  • 使用迭代器对multiset中的元素进行遍历,可得到有序序列;
  • multiset不能修改元素;
  • 在multiset中查找某个元素,时间复杂度O(logN);
  • multiset的作用是可以对元素进行排序;

二,multiset使用

构造函数

操作函数

//迭代器
      iterator begin() noexcept;
const_iterator begin() const noexcept;
      iterator end() noexcept;
const_iterator end() const noexcept;
      reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
      reverse_iterator rend() nothrow;
const_reverse_iterator rend() const nothrow;

//插入
single element (1)	
    iterator insert (const value_type& val);
    iterator insert (value_type&& val);
with hint (2)	
    iterator insert (const_iterator position, const value_type& val);
    iterator insert (const_iterator position, value_type&& val);
range (3)	
    template <class InputIterator>
    void insert (InputIterator first, InputIterator last);
initializer list (4)	
    void insert (initializer_list<value_type> il);

//删除
iterator  erase (const_iterator position);
size_type erase (const value_type& val);
iterator  erase (const_iterator first, const_iterator last);

//查找
const_iterator find (const value_type& val) const;
      iterator find (const value_type& val);

bool empty() const noexcept;
size_type size() const noexcept;
size_type count (const value_type& val) const;
void swap (multiset& x);
void clear() noexcept;
key_compare key_comp() const;
value_compare value_comp() const;

const_iterator lower_bound (const value_type& val) const;
      iterator lower_bound (const value_type& val);
const_iterator upper_bound (const value_type& val) const;
      iterator upper_bound (const value_type& val);

pair<const_iterator,const_iterator> equal_range (const value_type& val) const;
            pair<iterator,iterator> equal_range (const value_type& val);
int main()
{
	int arr[] = { 5,3,4,1,7,8,2,6,0,9,1,5 };
	int sz = sizeof(arr) / sizeof(int);

	multiset<int> s(arr, arr + sz);
	cout << s.size() << endl;
	s.insert(10);
	s.erase(1);

	for (auto& e : s)
	{
		cout << e << " "; //不去重
	}
	cout << endl;

	for (auto it = s.rbegin(); it != s.rend(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;

	cout << s.count(5) << endl;

	s.empty();
	s.clear();
	return 0;
}

### Multiset 数据结构实现和用法 #### 定义与特性 `std::multiset` 是 C++ 标准模板库 (STL) 提供的一种关联容器,其内部采用红黑树(一种自平衡二叉查找树)作为底层数据结构[^2]。这种设计确保了 `multiset` 能够高效地支持插入、删除以及查找操作。 #### 关键属性 - **允许重复元素**:不同于 `set` 只能保存唯一值,`multiset` 支持同一数值多次出现。 - **自动排序功能**:所有成员函数均保持集合有序排列,默认按升序组织;可通过定制比较器改变顺序逻辑。 #### 自定义类型的支持 对于复杂的数据类型如结构体或类对象,为了能够在 `multiset` 中正常工作并维持特定次序关系,需重载小于运算符 (`<`) 或者提供外部比较谓词给定构造参数。例如,在给出的例子中: ```cpp struct rec { int x, y; }; struct cmp { bool operator()(const rec& a, const rec& b) const { return a.x < b.x || (a.x == b.x && a.y < b.y); } }; ``` 这里定义了一个名为 `rec` 的简单记录类型及其对应的比较规则 `cmp`,之后可以创建基于此类型的多集实例: ```cpp #include <set> // ... multiset<rec, cmp> h; ``` 上述代码片段展示了如何利用用户定义的比较方式初始化一个多集中存储 `rec` 类型的对象,并依据指定条件进行排序[^1]。 #### 基本操作方法概览 - 插入新项:使用 `insert()` 成员函数向容器添加元素; - 删除现有条目:调用 `erase()` 方法移除单个或者全部匹配项; - 查找目标位置:借助迭代器遍历访问各节点,亦可运用 `find()` 函数快速定位某关键字所在之处; - 获取大小统计:通过 `size()` 查询当前容纳了多少实体单元。 综上所述,`multiset` 不仅继承了标准关联容器的优势特点——即高效的检索性能及稳定的内存管理机制,还进一步放宽了关于唯一性的约束限制,使之成为处理含有冗余信息场景下的理想选择之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值