C++ STL之set详解

set容器总述

set集合容器实现了平衡二叉搜索树,复杂度稳定在logn。搜索使用中序遍历,所以可以迭代出从小到大的结果。
使用set容器需要

#include <set>

创建set容器

//创建set容器需要指定元素的类型~
set<int> s;

元素的插入&中序遍历

用insert()方法把元素插入到集合中。如果插入的元素已经有了,set会直接忽视它。默认是从小到大排成平衡二叉树,也可以手写比较函数。使用前向迭代器对集合中序遍历,结果正好是元素排序后的结果。

#include <iostream>
#include <set>
#include <queue>
#include <map>
using namespace std;
int main()
{
    set<int> s;
    s.insert(5);
    s.insert(3);
    s.insert(6);
    s.insert(7);
    set<int>::iterator it;//前向迭代器
    for(it = s.begin() ; it != s.end() ; it ++) {//中序遍历
        cout << *it << endl;
    }//输出3 5 6 7
    return 0;
}

反方向遍历

使用反向迭代器reverse_iterator可以反向遍历set。输出的正好是从大到小的结果。要用到rbegin()和rend(),给出了反向遍历的开始位置和结束位置。(不要尝试用正向迭代器反着来)

#include <iostream>
#include <set>
#include <queue>
#include <map>
using namespace std;
int main()
{
    set<int> s;
    s.insert(5);
    s.insert(3);
    s.insert(6);
    s.insert(7);
    set<int>::reverse_iterator it;
    for(it = s.rbegin() ; it != s.rend() ; it ++) {
        cout << *it << endl;
    }//输出7 6 5 3
    return 0;
}

元素的删除

#include <iostream>
#include <set>
#include <queue>
#include <map>
using namespace std;
int main()
{
    set<int> s;
    s.insert(5);
    s.insert(3);
    s.insert(6);
    s.insert(7);
    s.erase(6);//直接用键删去
    //剩3 5 7
    set<int>::iterator it;
    //注意看怎么迭代删除的
    it = s.begin();
    for(int i = 0 ; i < 2 ; i ++) {//迭代两次,删去前面两个元素
        s.erase(it++);
    }

    for(it = s.begin() ; it != s.end() ; it ++) {
        cout << *it << endl;
    }
    return 0;
}

元素的检索

使用find()方法对set进行检索。找到则返回元素位置的迭代器,否则返回end()。

#include <iostream>
#include <set>
#include <queue>
#include <map>
using namespace std;
int main()
{
    set<int> s;
    s.insert(5);
    s.insert(3);
    s.insert(6);
    s.insert(7);
    set<int>::iterator it;
    it = s.find(3);
    if(it == s.end()) cout << "Not found" << endl;
    else cout << "Find it!" << endl;
    return 0;//输出Find it!
}

自定义比较函数

使用insert将元素插入到集合中去的时候,集合会根据设定的比较函数将该元素放到相应的节点上去。在定义集合的时候如果没有指定比较函数,那么采用默认的比较函数,即按照键值从小到大的顺序插入元素。

编写比较函数有两种方法

①如果元素不是结构体。

#include <iostream>
#include <set>
#include <queue>
#include <map>
using namespace std;
struct cmp {
    bool operator() (const int &a,const int &b) {
        return a>b;
    }
};
int main()
{
    set<int,cmp> s;
    s.insert(5);
    s.insert(3);
    s.insert(6);
    s.insert(7);
    set<int>::iterator it;
    for(it = s.begin() ; it != s.end() ; it ++) {
        cout << *it << endl;
    }//输出7 6 5 3
    return 0;
}

②如果元素是结构体,那么可以直接把比较函数写在结构体内。

#include <iostream>
#include <set>
#include <string>

using namespace std;
struct Info {
    string name;
    double score;
    bool operator < (const Info &a) const {//重载<运算符
        return a.score < score;
    }
};
int main()
{
    set<Info> s;
    Info info;
    info.name = "Jack";
    info.score = 80;
    s.insert(info);
    info.name = "Tom";
    info.score = 99;
    s.insert(info);
    info.name = "Bill";
    info.score = 100;
    s.insert(info);
    set<Info>::iterator it;
    for(it = s.begin() ; it != s.end() ; it ++) {
        cout << it->name << endl;
        cout << it->score << endl;
    }
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值