STL中set的基本介绍

STl中的基本内容

容器

set/multiset

在集合中,所有的元素只能出现一次,并且默认按照元素的值从小到大自动排序

set不能通过迭代器来修改元素的值,即set的迭代器是一种const_iterator

multiset 和 set 的区别在于multiset中允许有重复的元素

内部采用的是一种非常高效的平衡检索二叉树:黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。这种结构使得集合在进行插入删除的时候,具有较高的效率,它不需要移动其他的元素,只需要改变个别元素之间的连接关系。同时,正式因为如此,在插入删除的过程中不会发生元素内存地址的改变(例如,如果在vector容器中,当加入的元素已经大于容器原来的最大容量时,就需要为容器申请新的更大的内存空间,并将之前的内容拷贝过去,这既降低了效率,又使得之前获取的迭代器失效),之前保存下来的迭代器仍然指向原来的内存地址,因此不会发生迭代器失效的问题。

set的声明和赋值
set<int> st;  //声明了一个int类型的集合 默认元素按照从小到大的顺序排序
set<int,cmp> stt;  //声明的stt集合中,元素按照cmp中规定的顺序进行排序
set<int> st_copy(st);  //使用拷贝构造函数
set<int> s_t;
swap(st,s_t);  //交换两个集合中的元素
set的大小和空判断
st.size();  //返回集合的大小也就是元素的个数
st.empty();  //返回集合是否为空,如果是空返回为真
set的插入操作
for(int i=10;i>0;i--)
    st.insert(i);   //按顺序插入,但是set中的顺序为从小到大
for(set<int>::iterator it=st.begin();it!=st.end();it++)
    cout<<*it<<" ";   //1 2 3 4 5 6 7 8 9 10

st.insert(it_begin,it_end);  //把[it_begin,it_end)区间内的值插入到st中

//由于集合中的元素只能出现一次,在执行st.insert(5);其实是没有进行操作的
pair<set<int>::iterator,bool> test=st.insert(5);
if(test.second)
    cout<<"插入成功"<<endl;
else
    cout<<"插入失败"<<endl;
//输出结果为插入失败
set的删除操作
st.erase(key);  //删除集合中值为5的元素
st.erase(it_begin,it_end);  //删除集合中[it_begin,it_end)之间的元素
st.erase(index);  //删除迭代器index所指向位置的元素
st.clear();  //删除集合中的全部元素
set的查找操作
st.find(key);  //在集合中查找键key是否存在,若存在则返回指向该位置处的迭代器,若不存在,则返回st.end()
st.count(key);  //返回值为集合中键key的元素个数 在set中只能是0/1
st.upper_bound(key);  //返回第一个键大于key的元素的迭代器
st.lower_bound(key);  //返回第一个键大于等于key的元素的迭代器
st.equal_range(key);  //返回集合中键与key相当的上下限的两个迭代器
下面来一个完整的示例
#include <iostream>
#include <set>
using namespace std;
class Student {
public:
    Student(char x, int y) :name(x), score(y) {};
    char name;
    int score;
    bool operator <(const Student& c) const
    {
        return this->score < c.score;
    }

};
struct cmp {
    bool operator()(Student a1, Student a2) const
    {
        return a1.score > a2.score;
    }
};
void show(set<Student> s)
{
    for (set<Student>::iterator it = s.begin(); it != s.end(); it++) 
        cout << it->name << " " << it->score << endl; 
    cout << endl;
}
void show(set<Student, cmp> s)
{
    for (set<Student>::iterator it = s.begin(); it != s.end(); it++)
        cout << it->name << " " << it->score << endl; 
    cout << endl;
}
int main()
{
    //按照自定义规则排序
    set<Student> s;
    set<Student, cmp> rs;
    for (int i = 0; i <= 5; i++)
        s.insert(Student('a'+i, (i+1)*10)), rs.insert(Student('a'+i, (i+1)*10));
    show(s);  //按照成绩升序排列
    show(rs);  //按照成绩降序排列
    rs.erase(rs.find(Student('d', 40)));  //删除('d',40)的元素
    show(rs); 
    s.erase(s.begin(), s.upper_bound(Student('b', 20)));  //删除所有成绩不大于20的元素
    show(s);
    while (!s.empty())  s.erase(s.begin());  //清空集合
    rs.clear();  //清空集合
}

运行结果如下

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值