1、set
C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。
set里元素唯一,且默认从小到大排序。
总的内置函数:
1. begin()--返回指向第一个元素的迭代器
2. clear()--清除所有元素
3. count()--返回某个值元素的个数
4. empty()--如果集合为空,返回true
5. end()--返回指向最后一个元素的迭代器
6. equal_range()--返回集合中与给定值相等的上下限的两个迭代器
7. erase()--删除集合中的元素
8. find()--返回一个指向被查找到元素的迭代器
9. get_allocator()--返回集合的分配器
10. insert()--在集合中插入元素
11. lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器
12. key_comp()--返回一个用于元素间值比较的函数
13. max_size()--返回集合能容纳的元素的最大限值 int:214748364 ll:178956970
14. rbegin()--返回指向集合中最后一个元素的反向迭代器
15. rend()--返回指向集合中第一个元素的反向迭代器
16. size()--集合中元素的数目
17. swap()--交换两个集合变量
18. upper_bound()--返回大于某个值元素的迭代器
19. value_comp()--返回一个用于比较元素间的值的函数
常用函数:
1、set输出最小与最大元素
int MIN, MAX;
MIN = *set_.begin();
MAX = *set_.end();
//特别的:
iter = set_.end();
cout<<*iter<<endl;
cout<<*(--iter)<<endl;
这样竟然返回的都是最后一个集合元素
2、set迭代器与反向迭代器
set<int> set_;
up(i, 1, 8) set_.insert(i);
set<int>::iterator iter = set_.begin();
while(iter != set_.end()) printf("%d ", *iter++);
puts("");
set<int>::reverse_iterator riter = set_.rbegin();
while(riter != set_.rend()) printf("%d ", *riter++);
puts("");
输出结果:
1 2 3 4 5 6 7 8
8 7 6 5 4 3 2 1
3、set删除元素
/***
erase(iterator); //删除定位器iterator指向的值
erase(first,second); //删除定位器first和second之间的值
erase(key_value); //删除键值key_value的值
***/
/***删除5***/
set_.erase(set_.find(5));
set_.erase(lower_bound(set_.begin(), set_.end(), 5));
set_.erase(set_.lower_bound(5));
set_.erase(set_.find(5), set_.find(6)); //左闭右开
set_.erase(5);
set<int>::iterator iter = set_.begin();
while(iter != set_.end()) printf("%d ", *iter++);
puts("");
4、set查询
if(set_.find(9) == set_.end()) cout<<"查询不到"<<endl;
//如果查询不到返回迭代器值 set_.end()
// 特别的 :
iter1 = set_.end();
iter2 = set_.end();
*(iter1) == *(--iter2);
if(set_.count(9) == 0) cout<<"查询不到"<<endl;
5、set自定义排序
特别的对于string的长度进行排序:
struct cmp_string_m_n
{
bool operator() (const string & x, const string & y) const
{
return x.length() > y.length();
}
//注意 如果set_插入为
};
set<string, cmp_string_m_n> set__;
set__.insert("aa");
set__.insert("ab");
set__.insert("abc");
set<string>::iterator iter = set__.begin();
while(iter != set__.end()) cout<< *(iter++) << ' ';
puts("");
//输出结果 : abc aa
其他自定义排序:
//普通的
struct cmp_int_m_n
{
bool operator() (const int & x, const int & y) const
{
return x > y;
}
};
//结构体
struct node
{
int x, y;
};
struct cmp_node_m_n
{
bool operator() (const node & t, const node & tt) const
{
if(t.x != tt.x) return t.x < tt.x; //先升序
else return t.y > tt.y; //再降序
}
};
int main()
{
set<node, cmp_node_m_n> set_;
set_.insert({1, 2});
set_.insert({2, 3});
set_.insert({2, 4});
set_.insert({2, 5});
set_.insert({3, 6});
set<node>::iterator iter = set_.begin();
while(iter != set_.end()) printf("%d %d\n", iter->x, iter->y), iter++;
puts("");
}
//运行结果:
1 2
2 5
2 4
2 3
3 6
2、multiset 多重集合容器
顾名思义,可以存储重复的元素;有一点需要特别注意:删除的时候:
int main()
{
multiset<int> set_;
set_.insert(1);set_.insert(1);set_.insert(1);
set_.erase(set_.find(1)); //删除一个
cout<<set_.size()<<' ';
set_.erase(1); //全部删除
cout<<set_.size()<<'\n';
}
//运行结果: 2 0
3、priority_queue定义优先级
//优先级队列定义优先级,和set的方式类似
struct cmp_int_m_n
{
bool operator() (const int & x, const int & y) const
{
return x > y;
//因为优先级队列是先输出大的,所以要反着来,x > y 是先输出小的
}
};
int main()
{
priority_queue<int, vector<int>, cmp_int_m_n> que;
que.push(1);que.push(2);que.push(3);que.push(4);
cout<<que.top()<<endl;
}
//运行结果:
1