前面已经为大家总结了有关vector,list等的用法(https://blog.csdn.net/yaotengjian/article/details/81706046)。
set:
set是STL中一种标准关联容器(vector,list,string,deque都是序列容器,而set,multiset,map,multimap是标准关联容器),它底层使用平衡的搜索树——红黑树实现,插入删除操作时仅仅需要指针操作节点即可完成,不涉及到内存移动和拷贝,所以效率比较高。set,顾名思义是“集合”的意思,在set中元素都是唯一的,而且默认情况下会对元素自动进行升序排列,支持集合的交(set_intersection),差(set_difference) 并(set_union),对称差(set_symmetric_difference) 等一些集合上的操作,如果需要集合中的元素允许重复那么可以使用multiset。
set的一个集合,好比一个袋子里面装了好多个小球。但是红黑树是一种特殊的二叉搜索树,set中的元素根据其值的大小在红黑树中有特定的位置,是不可移动的。所以,1是search操作效率会很高O(log n),2是set中元素的值不可改变。
下面附上简单的代码讲解各部分的接口与功能:
int main()
{
//创建set对象
set s{ 1,5,1,6,3,5 };
set::iterator it;
for (it = s.begin(); it != s.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
//1 3 5 6
//元素的反向遍历 rebegin rend
set s{ 6,4,3,5,2,8,3,1, };
set::reverse_iterator it;
for (it = s.rbegin(); it != s.rend(); ++it)
{
cout << *it << " ";
}
cout << endl;
//元素的删除
set s{ 5,1,6,6,3,5,6 };
set::reverse_iterator it;
for (it = s.rbegin(); it != s.rend(); ++it)
{
cout << *it << endl;
}
cout << endl;
//set::iterator itr;
//itr = s.begin();
//for (int i = 0; i < 2; i++)
// itr = s.erase(itr);
//for (itr = s.begin(); itr != s.end(); ++it)
//{
// cout << *itr << " ";
//}
//cout << endl;
s.clear();
cout << s.size() << endl;
//查找元素
set s{ 5,1,6,6,3,5,6 };
set::iterator it;
it = s.find(8);
if(it != s.end())
{
cout << *it << endl;
}
else
{
cout << "not find it" << endl;
}
system("pause");
return 0;
}
//自定义比较函数
struct mycomp
{
bool operator()(const int& a, const int& b)
{
if (a != b)
return a > b;
else
return a > b;
}
};
int main()
{
set s{ 2,3,4,5,6,5,1 };
set::iterator it;
for (it = s.begin(); it != s.end(); ++it)
cout << *it << " ";
cout << endl;
system("pause");
return 0;
}
set和multiset、unordered_set的区别
multiset是不去重的,set是去重的;
unordered_set是C++11中引入的新的容器,其内部不再采用红黑树实现,而是采用了hash表,加速了检索速度。
set和map的内部实现是一样的,unordered_set和unordered_map的内部实现也是一样的。
map:
map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
下面附上简单的代码及注释:
//map容器
//map是STL的一个关联容器,它提供一对一
//(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力
//map提供一对一的数据处理能力,内部是由红黑树实现的,具有自动排序能力,
//map内部的所以数据是有序的
int main()
{
//用insert插入pair数据
map mapstudent;
mapstudent.insert(pair(1, "s1"));
mapstudent.insert(pair(2, "s2"));
mapstudent.insert(pair(3, "s3"));
mapstudent.insert(pair(4, "s4"));
map::iterator it;
for (it = mapstudent.begin(); it != mapstudent.end(); ++it)
{
cout << it->first << " " << it->second << endl;
}
//insert插入value_type数据
map mapstudent;
mapstudent.insert(map::value_type(1, "s1"));
mapstudent.insert(map::value_type(2, "s2"));
mapstudent.insert(map::value_type(3, "s3"));
map::iterator it;
for (it = mapstudent.begin(); it != mapstudent.end(); ++it)
{
cout << it->first << " " << it->second << endl;
}
//用数组方式插入数据
map mapstudent;
mapstudent[1] = "s1";
mapstudent[2] = "s2";
mapstudent[10] = "s10";
map::iterator it;
for (it = mapstudent.begin(); it != mapstudent.end(); ++it)
{
cout << it->first << " " << it->second << endl;
}
int size = mapstudent.size(); //
cout << mapstudent.size() << endl;
//数据的遍历
map mapstudent;
mapstudent.insert(pair(1, "s1"));
mapstudent.insert(pair(2, "s2"));
mapstudent.insert(pair(3, "s3"));
mapstudent.insert(pair(4, "s4"));
map::reverse_iterator it;
for (it = mapstudent.rbegin(); it != mapstudent.rend(); it++)
{
cout << it->first << " " << it->second << endl;
}
//数据的查找
map mapstudent;
mapstudent.insert(pair(1, "s1"));
mapstudent.insert(pair(2, "s2"));
mapstudent.insert(pair(3, "s3"));
mapstudent.insert(pair(4, "s4"));
map::iterator it;
it = mapstudent.find(3);
if (it != mapstudent.end())
{
cout << "find:" << it->second << endl;
}
else
cout << "not find" << endl;
//map的判空
//如果要删除1,用迭代器删除
map mapstudent;
mapstudent.insert(pair(1, "s1"));
mapstudent.insert(pair(2, "s2"));
mapstudent.insert(pair(3, "s3"));
mapstudent.insert(pair(4, "s4"));
map::iterator iter;
iter = mapstudent.find(1);
mapstudent.erase(iter);
//如果要删除1,用关键字删除
int n = mapstudent.erase(1);//如果删除了会返回1,否则返回0
//用迭代器,成片的删除
//一下代码把整个map清空
mapstudent.erase(mapstudent.begin(), mapstudent.end());
//成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合
system("pause");
return 0;
}
Set和map的区别?
set和map的区别就在于键和值是否相同,set中将值作为键,支持STL的提供的一些交集、并集和差集等运算;map的键和值不同,每个键都有自己的值,键不能重复,但是值可以重复。multimap和multiset就在map和set的基础上,使他们的键可以重复,除此之外基本等同。
set是一种关联式容器,其特性如下:
map和set一样是关联式容器,它们的底层容器都是红黑树,区别就在于map的值不作为键,键和值是分开的。它的特性如下:
其它相关(红黑树与哈希表)
红黑树:
红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:
哈希表:
哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。