- 序列容器
主要包括 vector 向量容器、list 列表容器以及 deque 双端队列容器。之所以被称为序列容器,是因为元素在容器中的位置同元素的值无关,即容器不是排序的。将元素插入容器时,指定在什么位置,元素就会位于什么位置。 - 排序容器
包括 set 集合容器、multiset多重集合容器、map映射容器以及 multimap 多重映射容器。排序容器中的元素默认是由小到大排序好的,即便是插入元素,元素也会插入到适当位置。所以关联容器在查找时具有非常好的性能。 - 哈希容器
C++ 11 新加入 4 种关联式容器,分别是 unordered_set 哈希集合、unordered_multiset 哈希多重集合、unordered_map 哈希映射以及 unordered_multimap 哈希多重映射。和排序容器不同,哈希容器中的元素是未排序的,元素的位置由哈希函数确定。
迭代器的分类
- 前向迭代器
假设 p 是一个前向迭代器,则 p 支持 ++p,p++,*p *** 作,还可以被复制或赋值,可以用 == 和 != 运算符进行比较。此外,两个正向迭代器可以互相赋值。 - 双向迭代器
双向迭代器具有正向迭代器的全部功能,除此之外,假设 p 是一个双向迭代器,则还可以进行 --p 或者 p-- *** 作(即一次向后移动一个位置)。 - 随机访问迭代器
随机访问迭代器具有双向迭代器的全部功能。除此之外,假设 p 是一个随机访问迭代器,i 是一个整型变量或常量,则 p 还支持以下 *** 作:
p+=i:使得 p 往后移动 i 个元素。
p-=i:使得 p 往前移动 i 个元素。
p+i:返回 p 后面第 i 个元素的迭代器。
p-i:返回 p 前面第 i 个元素的迭代器。
p[i]:返回 p 后面第 i 个元素的引用。
此外,两个随机访问迭代器 p1、p2 还可以用 <、>、<=、>= 运算符进行比较。
迭代器的定义
-
正向迭代器
容器类名::iterator 迭代器名;
-
常量正向迭代器
容器类名::const_iterator 迭代器名;
-
反向迭代器
容器类名::reverse_iterator 迭代器名;
-
常量反向迭代器
容器类名::const_reverse_iterator 迭代器名;
示例:
#includeusing namespace std; int main() { //v被初始化成有10个元素 vector v{1,2,3,4,5,6,7,8,9,10}; cout << "第一种遍历方法:随机访问迭代器支持" << endl; //像普通数组一样使用vector容器 for (int i = 0; i < v.size(); ++i) cout << v[i] <<" "; cout << endl << "第二种遍历方法:三种迭代器均支持" << endl; vector ::iterator i; //用 != 比较两个迭代器 for (i = v.begin(); i != v.end(); ++i) cout << *i << " "; cout << endl << "第三种遍历方法:随机访问迭代器支持" << endl; //用 < 比较两个迭代器 for (i = v.begin(); i < v.end(); ++i) cout << *i << " "; cout << endl << "第四种遍历方法:随机访问迭代器支持" << endl; i = v.begin(); //间隔一个输出 // 随机访问迭代器支持 "+= 整数" 的操作 while (i < v.end()) { cout << *i << " "; i += 2; } }
输出:
- array
(数组容器):n个固定元素,随机访问
表示可以存储 N 个 T 类型的元素,是 C++
本身提供的一种容器。此类容器一旦建立,其长度就是固定不变的,这意味着不能增加或删除元素,只能改变某个元素的值; - vector(向量容器):尾部删除插入,随机访问
用来存放 T类型的元素,是一个长度可变的序列容器,即在存储空间不足时,会自动申请更多的内存。使用此容器,在尾部增加或删除元素的效率最高(时间复杂度为O(1) 常数阶),在其它位置插入或删除元素效率较差(时间复杂度为 O(n) 线性阶,其中 n 为容器中元素的个数); - deque(双端队列容器):头部尾部删除插入,随机访问
和 vector非常相似,区别在于使用该容器不仅尾部插入和删除元素高效,在头部插入或删除元素也同样高效,时间复杂度都是 O(1)常数阶,但是在容器中某一位置处插入或删除元素,时间复杂度为 O(n) 线性阶; - list(链表容器):任意位置删除插入,两个方向顺序访问
是一个长度可变的、由 T类型元素组成的序列,它以双向链表的形式组织元素,在这个序列的任何地方都可以高效地增加或删除元素(时间复杂度都为常数阶O(1)),但访问容器中任意元素的速度要比前三种容器慢,这是因为 list 必须从第一个元素或最后一个元素开始访问,需要沿着链表移动,直到到达想要的元素。 - forward_list(正向链表容器):任何位置删除插入,正向顺序访问
和 list容器非常类似,只不过它以单链表的形式组织元素,它内部的元素只能从第一个元素开始访问,是一类比链表容器快、更节省内存的容器。
vector容器包含的成员函数
- begin() 返回指向容器中第一个元素的迭代器。
- end() 返回指向容器最后一个元素所在位置后一个位置的迭代器,通常和 begin() 结合使用。
- rbegin() 返回指向最后一个元素的迭代器。
- rend() 返回指向第一个元素所在位置前一个位置的迭代器。
- cbegin() 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
- cend() 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
- crbegin() 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
- crend() 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改元素。
- size() 返回实际元素个数。
- max_size() 返回元素个数的最大值。这通 常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
- resize() 改变实际元素的个数。
- capacity() 返回当前容量。
- empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
- reserve() 增加容器的容量。
- shrink _to_fit() 将内存减少到等于当前元素实际所使用的大小。
- operator[ ] 重载了 [ ] 运算符,可以向访问数组中元素那样,通过下标即可访问甚至修改 vector 容器中的元素。
- at() 使用经过边界检查的索引访问元素。
- front() 返回第一个元素的引用。
- back() 返回最后一个元素的引用。
- data() 返回指向容器中第一个元素的指针。
- assign() 用新元素替换原有内容。
- push_back() 在序列的尾部添加一个元素。
- pop_back() 移出序列尾部的元素。
- insert() 在指定的位置插入一个或多个元素。
insert示例代码:
#includeusing namespace std; int main() { std::vector demo{1,2}; //第一种格式用法 demo.insert(demo.begin() + 1, 3);//{1,3,2} //第二种格式用法 demo.insert(demo.end(), 2, 5);//{1,3,2,5,5} //第三种格式用法 std::array test{ 7,8,9 }; demo.insert(demo.end(), test.begin(), test.end());//{1,3,2,5,5,7,8,9} //第四种格式用法 demo.insert(demo.end(), { 10,11 });//{1,3,2,5,5,7,8,9,10,11} return 0; }
- erase() 移出一个元素或一段元素。
- remove() 删除容器中所有和指定元素值相等的元素,并返回指向最后一个元素下一个位置的迭代器。值得一提的是,调用该函数不会改变容器的大小和容量。
- clear() 移出所有的元素,容器大小变为 0。
- swap() 交换两个容器的所有元素。
- emplace() 在指定的位置直接生成一个元素。
- emplace_back() 在序列尾部生成一个元素。
示例:
#includeusing namespace std; int main(){ // 创建int类型vector容器 vector v; // 获得vector容器容量 cout< va(10,-1);//第一个容量,第二个为值,默认为0 //返回元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。 cout< deque包含的成员函数
deque包含的成员函数和vector基本一致,常用的增加了:
- push_front() 在序列的头部添加一个元素。
- pop_front() 移除容器头部的元素。
list容器可用的成员函数
- empty() 判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
- size() 返回当前容器实际包含的元素个数。
- max_size() 返回容器所能包含元素个数的最大值。这通常是一个很大的值,一般是 232-1,所以我们很少会用到这个函数。
- front() 返回第一个元素的引用。
- back() 返回最后一个元素的引用。
- assign() 用新元素替换容器中原有内容。
- emplace_front() 在容器头部生成一个元素。该函数和 push_front() 的功能相同,但效率更高。
- push_front() 在容器头部插入一个元素。
- pop_front() 删除容器头部的一个元素。
- emplace_back() 在容器尾部直接生成一个元素。该函数和 push_back() 的功能相同,但效率更高。
- push_back() 在容器尾部插入一个元素。
- pop_back() 删除容器尾部的一个元素。
- emplace() 在容器中的指定位置插入元素。该函数和 insert() 功能相同,但效率更高。
- insert() 在容器中的指定位置插入元素。
- erase() 删除容器中一个或某区域内的元素。
- swap() 交换两个容器中的元素,必须保证这两个容器中存储的元素类型是相同的。
- resize() 调整容器的大小。
- clear() 删除容器存储的所有元素。
- splice() 将一个 list 容器中的元素插入到另一个容器的指定位置。
#includeusing namespace std; int main(){ list li1{3.1,2.2,2.9},li2{9.9,10.9}; //排序 li1.sort(); for (auto it:li1) { std::cout << it << " "; } cout< ::iterator it = ++li1.begin(); //调用第一种语法格式 li1.splice(it, li2); // li1: 3.1,9.9,10.9,2.2,2.9 for (auto it:li1) { std::cout << it << " "; } cout<
- remove(val) 删除容器中所有等于 val 的元素。
#includeusing namespace std; int main(){ list li{1,3,5,2,4,3,5,3,3}; li.remove(3); for (auto it:li) { std::cout << it << " "; } return 0; }
- remove_if() 删除容器中满足条件的元素。
#includeusing namespace std; int main(){ list li{1,3,5,2,4,3,5,3,3}; li.remove_if([](int value) {return (value <= 3); }); for (auto it:li) { std::cout << it << " "; } return 0; }
- unique() 删除容器中相邻的重复元素,只保留一个。
#include#include using namespace std; //二元谓词函数 bool demo(double first, double second) { return (int(first) == int(second)); } int main() { list
mylist{ 1,1.2,1.2,3,4,4.5,4.6 }; //删除相邻重复的元素,仅保留一份 mylist.unique();//{1, 1.2, 3, 4, 4.5, 4.6} for (auto it = mylist.begin(); it != mylist.end(); ++it) cout << *it << ' '; cout << endl; //demo 为二元谓词函数,是我们自定义的去重规则 mylist.unique(demo); for (auto it = mylist.begin(); it != mylist.end(); ++it) std::cout << *it << ' '; return 0; }
- merge() 合并两个事先已排好序的 list 容器,并且合并之后的 list 容器依然是有序的。
#includeusing namespace std; int main(){ list li{1,3,5,2,4,3,5,3,3},l2{9,8,1,5}; li.merge(l2); for (auto it:li) { std::cout << it << " "; } return 0; }
- sort() 通过更改容器中元素的位置,将它们进行排序。
- reverse() 反转容器中元素的顺序。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)