容器
如果你看到这里,那就祝你虎年快乐 。
现在是2022年1月28号、晴、温度3摄氏度。
这里主要说两类容器 vector 和 list 和迭代器,内容较多分成三个篇章。
vector:
1、动态数组、数组升级版。(相较于静态数组、容量可变化)
2、提供 api简化数组操作
3、以类模板 vector<T>定义头文件 vector 内。命名空间 std。--》头文件 vector 命名 std:
定义
一个创建实例:
依赖
#include <vector>
using namespace std;
基础:01
vector <int> values;
/*
或者没 using namespace std
则*/
std::vector <int> values;
空容器、无内存占用、添加元素后再分配空间。
增加 02
values.reserve(20);
内存分配 20 个元素。
也可以创建时候,进行申请
//创建 + 初始化
vector<double>primes{2, 3, 5, 10, 29};
//创建+ 指定个数
vector <double> values(20);//默认初始值为0
//创建+ 指定整体元素默认值
vector <int> vaules(20, 3);//20个元素全是3 注意第一个参数和第二个参数 可以是变量。
其他:vector<char>value1(5, 'c');
//嵌套
value2(value1); //基于容器1 创建容器2
//嵌套
value2(value1); //基于容器1 创建容器2
数组转容器:疑问,经测试确实如此
int array[] = {1, 2, 3} ;
vector<int>values(array, array+2 )//说明是地址存储。存储 1 、2
vector<int>values(array, array+3 )//说明是地址存储。存储 1 、2 、3
容器转容器
- vector<int> v1(10, 1);
- vector<int> v2(v1); //用v1来初始化v2
- vector<int> v3 = v2; //用v2数组给v3数组赋值
访问
访问形式和数组一样、支持下标访问。
vector<int>values(20, 1);//20个1
values[19] 值为 1 values[0]值为1 、、、
但是不允许下标赋值,赋值见下一章节、
- vector<int> v;
- v[2] = 2; //错误
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() | 在指定的位置插入一个或多个元素。 |
erase() | 移出一个元素或一段元素。 |
clear() | 移出所有的元素,容器大小变为 0。 |
swap() | 交换两个容器的所有元素。 |
emplace() | 在指定的位置直接生成一个元素。 |
emplace_back() | 在序列尾部生成一个元素。 |
- 获取容器容量 v.capacity() 获取容量
- 获取容器大小 v.size(); 获取大小, 容量 != 大小,大小== 实际
一个例子
std::vector<int>value{ 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 };
value.reserve(20);
cout << "value 容量是:" << value.capacity() << endl;
cout << "value 大小是:" << value.size() << endl;
结论:
value 容量是:20
value 大小是:15
- 填充
vector<int> v; v.assign(5,10);//往v里放5个10
- 区间赋值
vector<int> v1, v2;
v2.assign(v1.begin(), v1.end()) //将左第一元素 和右倒数第二个 左开右闭
- 获取元素 下标获取。其他方式不考虑。
- 插入insert
vector < int >v;
v.insert(pos, xxx) //位置 pos 上插入元素 xxx 返回新数据位置。
v.insert(pos, n, xxxx) //位置 pos 上插入 n 个 xxxx 无返回
v.insert(pos, begin, end); //在pos位置插入[begin, end)区间的数据,无返回值
c.insert(pos,elem) 在pos位置插入一个elem的拷贝,返回插入的值的迭代器。
c.insert(pos,n,elem)在pos位置插入n个elem的数据,无返回值。
c.insert(pos,beg,end)在pos位置插入在[beg,end)区间的数据,无返回值。
vector<int> v; v.insert(v.begin(),10); v.insert(v.begin(),2,20); v.insert(v.begin(),v1.begin(),v1.begin()+2);
-
删除erase
v.erase(pos);移出 pos 位置的元素,返回下个元素位置
v.erase(v.begin());
v. erase(begin,end);移出[begin, end]元素,返回下一个元素位置。
v.erase(v.begin(),v.end())
- 尾部插入和删除
vector<int> v;
v.push_back(1);插入尾部
v.pop_back();删除尾部
- 获取尾部和头部元素
v.front();
v.back();
- 返回尾部和头部迭代器
v.begin();
v.end();
vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); vector<int>::iterator it; for(it = v.begin();it!=v.end();it++){ cout << *it << "\t"; } cout << endl;
- 区间插入和删除
demo
#inlcude <iostream>
#include <vector>
using namespace std;
int main()
{
vector <int> v;
v.insert(v.begin(), 'a');//头部插入
v.insert(v.begin(), 'b');
v.insert(v.begin(), 'c');
v.insert(v.begin() + 1 , 5, 't');
for(int i = 0; i < 8; i++)
{
cout << v[i]<<endl;
}
cout << "erase ..." <<endl;
v.erase(v.begin()+ 1, v.begin() + 6);//删除区间6个元素
for(int i=0; i< 3; i++)
{
cout<< v[i] <<endl;
}
system("pause");
return 0;
}
算法复杂度:
留白。