-------------------------------------set/multiset容器
set/multiset特性
set/multiset的特性是所有元素会根据元素的值自动进行排序。set是以RB-tree(红黑树,平衡二叉树的一种)为底层机制
其查找效率非常好。set容器中不允许重复元素,multiset允许重复元素
二叉树就是人和街店最多只允许有两个子节点。分别是左子节点和右子节点
二叉搜索树,是指二叉树中节点按照一定规则进行排序,使得对二叉树中元素访问更加高效
二叉搜索树的放置规则是:任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于其右子树的值
set是根据元素值进行排序,关系到set的排序规则,如果任意改变set的元素值,会严重破坏set的组织
---------------------set的常用API
set构造函数
set<T> st; set默认构造函数
multiset<T> mst; multiset默认构造函数
set(const set& st); 拷贝构造函数
set赋值操作
set& operator= (const set& st); 重载=操作符
swap(st); 交换两集合容器
set大小操作
size(); 返回容器中元素数目
empty(); 判断容器是否为空
set插入和删除操作
insert(elem); 在容器中插入元素
clear(); 清除所有元素
erase(pos); 删除pos迭代器所指向的元素,返回下一个元素的迭代器
erase(beg,end); 删除区间[beg,end)的所有元素,返回下一个元素的迭代器
erase(elem); 删除容器中值为elem的元素
set查找操作
find(key); 查找key是否存在,若存在,返回该元素的迭代器;若不存在,返回map.end()
lower_bound(keyElem); 返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem); 返回第一个key>keyElem元素的迭代器
equal_range(keyElem); 返回容器中key=keyElem的上下限的两个迭代器
#include<iostream>
#include<set>
#include<algorithm>
using namespace std;
//仿函数
class cmp {
public:
bool operator() (int v1,int v2) {
return v1 > v2;
}
};
//set容器初始化
void test01 () {
set<int,cmp> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
//默认 小->大
for (set<int>::iterator it = s1.begin();it != s1.end();it ++) {
cout << *it << " ";
}
cout << endl;
//赋值操作
set<int> s2;
s2 = s1;
//删除操作
s1.erase(s1.begin());
s1.erase(7);
for (set<int>::iterator it = s1.begin();it != s1.end();it ++) {
cout << *it << " ";
}
cout << endl;
//先序遍历 中序遍历 后序遍历
//如何改变默认排序
}
//set查找
void test02 () {
//实值
set<int> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
set<int>::iterator ret = s1.find(4);
if (ret == s1.end()) {
cout << "没找到" << endl;
}
else {
cout << "ret: " << *ret << endl;
}
}
//找到第一个大于等于key的元素
void test03 () {
set<int> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
set<int>::iterator ret = s1.lower_bound(2);
if (ret == s1.end()) {
cout << "没找到" << endl;
}
else {
cout << "ret: " << *ret << endl;
}
}
//找到第一个大于key的元素
void test04 () {
set<int> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
set<int>::iterator ret = s1.upper_bound(2);
if (ret == s1.end()) {
cout << "没找到" << endl;
}
else {
cout << "ret: " << *ret << endl;
}
}
//返回lower_bound和upper_bound的值
void test05 () {
set<int> s1;
s1.insert(7);
s1.insert(2);
s1.insert(4);
s1.insert(5);
s1.insert(1);
pair<set<int>::iterator,set<int>::iterator> ret = s1.equal_range(2);
if (ret.first == s1.end()) {
cout << "没找到" << endl;
}
else {
cout << "找到!";
cout << "ret.first: " << *ret.first << endl;
}
if (ret.second == s1.end()) {
cout << "没找到" << endl;
}
else {
cout << "找到!";
cout << "ret.scond: " << *ret.second << endl;
}
}
class Person {
public:
Person(int age,int id):age(age),id(id) {}
public:
int age;
int id;
};
class cmp2 {
public:
bool operator() (const Person& p1,const Person& p2) {
return p1.age > p2.age;
}
};
void test06 () {
set<Person,cmp2> sp; //set需要排序,当放入对象时,set不知道怎么排序
Person p1(10,20),p2(30,40),p3(50,60);
sp.insert(p1);
sp.insert(p2);
sp.insert(p3);
Person p4(60,30);
for (set<Person,cmp2>::iterator it = sp.begin();it != sp.end();it ++) {
cout << (*it).age << " " << (*it).id << endl;
}
//查找
set<Person,cmp2>::iterator ret = sp.find(p4);
if (ret == sp.end()) {
cout << "没有找到!" << endl;
}
else {
cout << "找到!" << (*ret).age << " " << (*ret).id << endl;
}
}