关联式容器有哪些?各自拥有哪些特点?
一、set
- key值唯一、不重复
- 有序,默认按照升序排列
- 底层使用红黑树数据结构
- 不支持==[]==运算符
- 不能通过迭代器iterator修改元素的值,为了维护红黑树的稳定性
注意:若元素是自定义类型、则必须支持元素之间的比较,因为:
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class set;
class Compare = std::less,会按照Key比较大小、若没有重载对应的运算符、则会报错。
1.构造函数
//1.以大括号序列形式构造set
set( std::initializer_list<value_type> init,
const Compare& comp = Compare(),
const Allocator& alloc = Allocator()
);
template< class InputIt >
//2.以迭代器范围的元素进行构造
set( InputIt first, InputIt last, const Allocator& alloc)
: set(first, last, Compare(), alloc) {}
//3.构造一个空的集合
set();
//4.拷贝构造
set( const set& other );
2.插入insert
//插入单个元素
std::pair<iterator,bool> insert( const value_type& value );
//插入一个元素到指定位置,这个位置没啥用
iterator insert( iterator hint, const value_type& value );
//插入一个迭代器范围内的元素
template< class InputIt >
void insert( InputIt first, InputIt last );
//插入大括号内的所有元素
void insert( std::initializer_list<value_type> ilist );
st.insert({1,2,3,4,5,6,7,8});
3.begin() 返回开始位置的迭代器
4.end() 返回最后一个元素的下一个元素的迭代器
5.empty() 检查容器是否位空
6.size() 容器的大小
7.swap() 交换两个集合
8.erase() 擦除元素
查找
9.count
10.find
euqal_range 返回指定条件key的迭代器范围
lower_bound 返回第一个不小于key的元素的迭代器
upper_bound 返回第一个大于key的元素的迭代器
代码:
#include <iostream>
#include <set>
#include <vector>
using std::cout;
using std::endl;
using std::set;
using std::vector;
template <typename Container>
void display(const Container &con)
{
for(auto &elem : con)
{
cout << elem << " ";
}
cout << endl;
}
void test()
{
//特征:唯一、有序、不能下标
set<int> number = {1,3,5,8,6,4,5,9};
set<int,std::greater<int>> number2 = {1,3,5,8,6,4,5,9};
display(number);
display(number2);
cout << endl << "set的查找操作" << endl;
size_t cnt = number.count(100);
cout << "cnt = " << cnt << endl; //存在返回1,不存在返回0
set<int>::iterator it = number.find(7);//返回迭代器
if(it != number.end())
{
cout << "存在 " << *it << endl;
}
else
{
cout << "不存在" << endl;
}
cout << endl << "set的insert操作" << endl;
std::pair<set<int>::iterator,bool> ret = number.insert(7);
if(ret.second)
{
cout << "insert success " << *ret.first << endl;
}
else
{
cout << "insert failed,the element already exits in set" << endl;
}
cout << endl;
vector<int> vec = {19,3,9,48,12,8,9};
number.insert(vec.begin(),vec.end());//左闭右开
display(number);
cout << endl;
cout << "插入一个大括号序列" << endl;
number.insert({1,2,3,4,5,6});
display(number);
cout << endl;
//out << number[1] << endl;
cout << endl;
it = number.begin();
cout << "*it" << *it << endl;
//*it = 300; 不支持修改
}
void test0(){
}
int main(void){
test();
test0();
return 0;
}
二、map
- 存放的是key-value,key是唯一的,不能重复
- value可以重复
- 有序、默认按照key升序排列
- 底层使用红黑树
- 下标具有:查找、插入、修改的功能,需要注意的是map没有提供const版本的[]下标运算符。
支持的操作和set很类似:
#include <iostream>
#include <map>
#include <string>
using std::cout;
using std::endl;
using std::map;
using std::string;
template <typename Container>
void display(const Container &con)
{
for(auto &elem : con)
{
cout << elem.first << " " << elem.second << endl;
}
}
void test0(){
//map特征:
//村法国的是key-value
//key唯一、value不唯一
//有序
//底层使用的是红黑树
map<int,string> number = {
{3,"wangdao"},
{1,"wuhan"},
std::pair<int,string>(2,"beijing"),
std::pair<int,string>(4,"nanjing"),
std::make_pair(5,"dongjing"),
std::make_pair(7,"dongjing"),
std::make_pair(1,"wuhans")
};
display(number);
cout << endl << "map的查找功能" << endl;
size_t cnt = number.count(4);
cout << "cnt = " << cnt << endl;
map<int,string>::iterator it = number.find(7);
if(it != number.end())
{
cout << "*it = " << endl << it->first << " " << it->second << endl;
}
else
{
cout << "不存在" << endl;
}
cout << endl << "map的下标操作" << endl;
cout << "number[3] " << number[3] << endl;//查询
cout << "number[8] " << number[8] << endl;//插入
cout << endl;
number[8] = "sichuan";
display(number);
}
#if 0
//map的下标运算符没有提供const版本[]运算符
void func(const map<int,string>& con)
{
con[1];
}
#endif
int main(void){
test0();
return 0;
}