STL标准模板库之set
一、关联式容器
关联式容器依据特定的排序准则,自动为其元素排序。排序准则以函数形式呈现,用来比较元素值(value)或元素键(key)。缺省情况下以operator<进行 比较,不过你也可以提供自己的比较函数,定义出不同的排序准则。
通常关联式容器由二叉树(binary tree)实现。在二叉树中,每个元素(节 点)都有一个父节点和两个子节点;左子树的所有元素都比自己小,右子树的所有元素都比自己大。关联式容器的差别主要在于元素的类型以及处理重复元素时的方式。
STL预先定义好的关联式容器有:集合(set)、多重集合(multiset)、映射(map)和多重映射(multimap)。
二、什么是set?
集合(set)简而言之是一种包含已排序对象的关联容器,不允许有重复元素。
一个集合通过一个链表来组织,在插入操作和删除操作上比向量(vector)快,但查找或添加末尾的元素时会有些慢。具体实现采用了红黑树的平衡二叉树的数据结构。
特点
- set中的元素都是排好序的。
- set中没有重复的元素。
- map和set的插入删除效率比用其他序列容器高,因为对于关联容器来说,不需要做内存拷贝和内存移动。
优缺点和适用场景:
优点:使用平衡二叉树实现,便于元素查找,且保持了元素的唯一性,以及能自动排序。
缺点:每次插入值的时候,都需要调整红黑树,效率有一定影响。
适用场景:适用于经常查找一个元素是否在某群集中且需要排序的场景。
三、定义及初始化
set<int> a; //定义一个int类型的集合a
set<int> b(a); //定义并用集合a初始化集合b
set<int> b(a.begin(), a.end()); //将集合a中的所有元素作为集合b的初始值
//类似的可以使用数组来初始化向量:
int n[] = { 1, 2, 3, 4, 5 };
list<int> a(n, n + 5); //将数组n的前5个元素作为集合a的初值
四、基本操作
1)容量函数
- 容器大小:a.size();//返回a中元素个数
- 容器最大容量:a.max_size();//预分配的内存空间与size不同,返回a在内存中总共可以容纳的元素个数
- 容器判空:a.empty();//空则返回true,否则返回false
2)修改函数
插入函数:a.insert(x);//时间复杂度为O(log n)
注意:set 在进行插入的时候是不允许有重复的键值的,如果新插入的键值与原有的键值重复,则插入无效(multiset可以重复)
删除函数:a.erase(参数);
参数可以是元素或者迭代器,返回下一个元素的迭代器,时间复杂度为O(log n),注意在multiset中s.erase(x)会删除所有值为x的元素
set<int>::iterator it=a.begin();
a.erase(it);
a.erase(3);
- 删除区间[first,end)的元素:a.erase(iterator first, iterator end);
- 清空所有元素:a.clear();
- 交换两个同类型容器的元素:a.swap(b);
set<int>st1;
st1.insert(1);
st1.insert(2);
st1.insert(3);
set<int>st2;
st1.insert(4);
st1.insert(5);
st1.insert(6);
st1.swap(st2);
//st1: 4 5 6
//st2: 1 2 3
3)迭代器
开始迭代器指针:a.begin();//时间复杂度为O(1)
末尾迭代器指针:a.end();
返回集合的尾迭代器,众所周知,STL中区间都是左闭右开的,那么end()函数返回的迭代器即为指向集合中最大元素的下一个位置的迭代器,因此--s.end()才是指向集合中最大元素的迭代器,时间复杂度为O(1)
指向常量的开始迭代器指针:a.cbegin(); //意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
指向常量的末尾迭代器指针:a.cend();
反向迭代器指针,指向最后一个元素:a.rbegin();
反向迭代器指针,指向第一个元素的前一个元素:a.rend();
返回最后一个key<=keyElem元素的迭代器:a.lower_bound(keyElem);
返回第一个key>keyElem元素的迭代器:a.upper_bound(keyElem);
//假设 st:1 2 3
cout << "*(st.begin()): " << *(st.begin()) << endl;
cout << "*(st.end()): " << *(--st.end()) << endl;
cout << "*(st.cbegin()): " << *(st.cbegin()) << endl;
cout << "*(st.cend()): " << *(--st.cend()) << endl;
cout << "*(st.rbegin()): " << *(st.rbegin()) << endl;
cout << "*(st.rend()): " << *(--st.rend()) << endl;
cout << "*(st.lower_bound(2)): " << *(st.lower_bound(2)) << endl;
cout << "*(st.upper_bound(2)): " << *(st.upper_bound(2)) << endl;
/*
*(st.begin()): 1
*(st.end()): 3
*(st.cbegin()): 1
*(st.cend()): 3
*(st.rbegin()): 3
*(st.rend()): 1
*(st.lower_bound(2)): 2
*(st.upper_bound(2)): 3
*/
4)其他函数
统计键key的元素个数:a.count(key);//有则为1,无则为0
查找函数:a.find(x);
在set中查找值为x的元素,并返回指向该元素的迭代器,若不存在,返回set.end(),时间复杂度为O(log n)
五、与序列容器的不同点
- set 只支持默认构造函数和拷贝构造函数,没有其它重载的构造函数。
- set 只能使用insert的两种重载函数插入,不支持push_back()和push_front()函数。
- set 能不通过迭代器,只通过元素值来删除该元素。
- set 容器不提供下标操作符。为了通过键从 set 中获取元素,可使用 find 运算。
- set 不支持STL里的reverse和sort算法。
STL标准模板库之set的更多相关文章
- STL标准模板库(简介)
标准模板库(STL,Standard Template Library)是C++标准库的重要组成部分,包含了诸多在计算机科学领域里所常见的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应 ...
- STL标准模板库介绍
1. STL介绍 标准模板库STL是当今每个从事C++编程的人需要掌握的技术,所有很有必要总结下 本文将介绍STL并探讨它的三个主要概念:容器.迭代器.算法. STL的最大特点就是: 数据结构和算法的 ...
- STL学习系列一:STL(标准模板库)理论基础
STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. STL的从广 ...
- STL(标准模板库)理论基础,容器,迭代器,算法
基本概念 STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. ...
- STL(标准模板库)基本概念
一.什么是STL STL(Standard Template Library,标准模板库)的从广义上讲分为三类:algorithm(算法).container(容器)和iterator(迭代器),容器 ...
- C++ Templates STL标准模板库的基本概念
STL标准库包括几个重要的组件:容器.迭代器和算法.迭代器iterator,用来在一个对象群集的元素上进行遍历操作.这个对象群集或许是一个容器,或许是容器的一部分.迭代器的主要好处是,为所有的容器提供 ...
- STL标准模板库 向量容器(vector)
向量容器使用动态数组存储.管理对象.因为数组是一个随机访问数据结构,所以可以随机访问向量中的元素.在数组中间或是开始处插入一个元素是费时的,特别是在数组非常大的时候更是如此.然而在数组末端插入元素却很 ...
- STL标准模板库之vector
目录 vector容器 1)什么是vector 2)如何定义 3)常用的Vector函数 1.容量函数 2.增加函数 3.删除函数 4.迭代器 5.访问函数 6.其他函数及操作 7.算法 STL提供了 ...
- STL(标准模板库) 中栈(stack)的使用方法
STL 中栈的使用方法(stack) 基本操作: stack.push(x) 将x加入栈stack中,即入栈操作 stack.pop() 出栈操作(删除栈顶),只是出栈,没有返回值 stack.t ...
- STL 标准模板库
<vector> 可变长的数组 Vector<int>v int是一个模板参数,这样传进来的都会是int V.push_back(a)将a传进v,且放在最后一个 V.clear ...
随机推荐
- MFC消息路由
1.Command Routing(命令传递):当消息进来时,会有一个泵推动它前进.消息如何进来,以有泵函数如何推动,都是属于windows程序设计的范畴, 消息如果是从子类流向父类(纵向流动),那么 ...
- python自动华 (十五)
Python自动化 [第十五篇]:CSS.JavaScript 和 Dom介绍 本节内容 CSS javascript dom CSS position标签 fixed: 固定在页面的某个位置 rel ...
- The websites related Laravel 相关网站(内容将不断更新)
https://laraveldaily.com/ 文章内容质量很高
- 020_统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个
统计 13:30 到 14:30 所有访问 apache 服务器的请求有多少个 #!/bin/bash#awk 使用-F 选项指定文件内容的分隔符是/或者:#条件判断$7:$8 大于等于 13:30, ...
- PC端使用program來CHGUSRPRF
執行CHGUSRPRF命令需要*SECADM 權限,但通常Security部門不允許Grant這個這麼大的權限,爲了達到目的,改用下面的方法 1. Create CL program 注意裏面一定要用 ...
- CSP-S 模拟测试92 题解
话说我怎么觉得我没咕多长时间啊,怎么就又落了20多场题解啊 T1 array: 根据题意不难列出二元一次方程,于是可以用exgcd求解,然而还有一个限制条件就是$abs(x)+abs(y)$最小,这好 ...
- python实现随机生成头像
今天遇到如何给用户分配随机头像的问题,想着要在本地放很多图片,有点无聊,就找了一些生成头像的工具.发现gravatar生成图像还不错,挺好玩的. 1.下面上代码 # -*- coding: utf-8 ...
- vmware压缩vmdk文件大小
在搭建靶机环境的过程中总是遇见vmdk越来越大,导致上传时间变长.记一下压缩vmdk的方法 ;sync;rm -f zero.fill /usr/bin/vmware-toolbox-cmd disk ...
- 笔记七(编写第一个UEFI程序)
搭建好uefi开发环境之后,在MyWorkspace文件夹中建立一个文件夹ExamplePkg; ,然后在ExamplePkg文件夹中创建HelloWorld文件夹,Include文件夹,Exampl ...
- 重读APUE(8)-进程、进程组、会话
进程: 是系统中一段程序执行的实体,也是资源分配和调度的基本单位: 进程组: 为了方便管理多个进程,可以将多个进程加入到一个进程组内: 每个进程都属于一个进程组,但是同一个进程组内可以有多个进程: 每 ...