1. 基本概念
- vector容器:本质上就是一个单端数组和动态数组。
(1)但当原空间的容量不足时,会开辟新空间,将原数据复制到新空间后释放原空间;
(2)vertor容器并不是进行两倍容量过逐一增加,而是有特定的算法。 - vector迭代器:由于vector容器类似于数组,维护的时线性空间,因此普通指针都可以作为vector迭代器。
(1)vector支持随机存取: 如operaroe*, operator->, operator++, operator--, operator+, operator-, operator+=, operator-=
2. vector容器的构造、赋值、交换
2.1 构造
- 构造方式
vector<T> v;
vector(v.begin(), v.end());
vector(n, elem);
vector(const vector &vec);
- 代码实现
void test01()
{
vector<int> v1;
vector<int> v2(10, 100);
myPrint(v2);
vector<int> v3(v2.begin(), v2.end());
myPrint(v3);
vector<int>v4(v3);
myPrint(v3);
}
2.2 赋值与交换
- 赋值函数
assign(beg, end);
assign(n, elem);
vector& operator=(const vector &vec);
- 交换函数
swap(vec);
- 代码实现
void test02()
{
vector<int> v1;
v1.assign(10, 100);
myPrint(v1);
vector<int> v2;
v2.assign(v1.begin(), v1.end());
myPrint(v2);
vector<int> v3;
v3 = v1;
myPrint(v3);
int arr[] = {1, 2, 3, 4, 5};
vector<int> v4;
v4.assign(arr, arr + (sizeof(arr) / sizeof(int)));
myPrint(v4);
v4.swap(v3);
myPrint(v3);
myPrint(v4);
}
3. 常用接口
3.1 大小操作
size();
empty();
resize(int num);
resize(int num, elem);
capacity();
reserve(int len);
void test03()
{
int arr[] = {0, 1, 2, 3, 4};
vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
if (v.empty())
{
cout << "容器已空" << endl;
}
else
{
cout << v.size() << endl;
}
v.resize(10, 100);
myPrint(v);
v.resize(3);
myPrint(v);
}
3.2 数据存取操作
at(int idx);
operator[];
front();
back();
void test04()
{
int arr[] = { 0, 1, 2, 3, 4 };
vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
for (int i = 0; i < v.size(); i++)
{
cout << v.at(i) << endl;
cout << v[i] << endl;
}
try
{
cout << v.at(100) << endl;
cout << v[100] << endl;
}
catch (...)
{
cout << "wrong" << endl;
}
cout << v.front() << endl;
cout << v.back() << endl;
}
3.3 插入和删除
insert(const_iterator pos, int count,ele);
push_back(ele);
pop_back();
erase(const_iterator start, const_iterator end);
erase(const_iterator pos);
clear();
void test05()
{
int arr[] = { 0, 1, 2, 3, 4 };
vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
v.insert(v.begin(), 3, 100);
myPrint(v);
v.pop_back();
myPrint(v);
v.erase(v.begin());
myPrint(v);
v.erase(v.begin(), v.end());
myPrint(v);
v.assign(arr, arr + (sizeof(arr) / sizeof(int)));
v.clear();
myPrint(v);
}
3.4 vector案例
- 通过swap收缩容量
- 通过reserve减少扩充次数
void test06()
{
vector<int>v;
v.reserve(100000);
int* p = NULL;
int num = 0;
for (int i = 0; i < 100000; i++)
{
v.push_back(i);
if (p != &v[0])
{
p = &v[0];
num++;
}
}
cout << "num =" <<num << endl;
v.resize(3);
cout << v.size() << endl;
cout << v.capacity() << endl;
vector<int>(v).swap(v);
cout << v.size() << endl;
cout << v.capacity() << endl;
}
3.5 逆序遍历
void test07()
{
vector<int> v;
for (int i = 0; i < 5; i++)
{
v.push_back(i);
}
for (vector<int>::reverse_iterator rit = v.rbegin(); rit != v.rend(); rit++)
{
cout << *rit << endl;
}
vector<int>::iterator itBegin = v.begin();
itBegin++;
itBegin--;
itBegin = itBegin + 1;
list<int>L;
L.push_back(10);
L.push_back(10);
L.push_back(10);
list<int>::iterator lBegin = L.begin();
lBegin++;
lBegin--;
}
4. deque容器
4.1 基本概念
- deque与vector容器的区别:
(1)vector容器时单项开口的连续内存空间,而deque容器则是双向开口的连续内存空间,即可以实现在头尾两端分别做元素的插入和删除操作。
(2)vector容器也可以实现两端插入和删除但效率太低,vector容器的存储方式相当于连续存储的栈,deque容器存储方式相当于连续存储的队列。注意:只是相似,而非相同,因为栈个队列无法遍历
(3)deque容器没有容量的概念,其存储是连续分段的存储方式,当原存储容量不足时,会在开辟一块内存存储新的数据,但原来数据继续在原来的地址,通过中控其存储各个段的首地址。 - deque迭代器也支持随机访问,但其复杂度远高于vector迭代器,因此占用资源贡多,应尽量使用vector容器。
4.2 基本操作
4.2.1 构造函数
deque<T> deqT;
deque(beg, end);
deque(n, elem);
deque(const deque &deq);
4.2.2 赋值操作
assign(beg, end);
assign(n, elem);
deque& operator=(const deque &deq);
swap(deq);
4.2.3 大小操作
deque.size();
deque.empty();
deque.resize(num);
deque.resize(num, elem);
4.2.4 双端插入和删除操作
push_back(elem);
push_front(elem);
pop_back();
pop_front();
4.2.5 数据存取
at(idx);
operator[];
front();
back();
4.2.6 插入操作
insert(pos,elem);
insert(pos,n,elem);
insert(pos,beg,end);
4.2.7 删除操作
clear();
erase(beg,end);
erase(pos);
deque<int> d1(10, 100);
deque<int> d2(d1);
deque<int> d3(d2.begin(), d2.end());
deque<int> d4;
deque<int> d5;
d5 = d1;
deque<int> d6;
d6.assign(5, 100);
deque<int> d7;
d7.assign(d3.begin(), d3.end());
deque<int> d8;
d8.swap(d7);
if (d2.empty())
{
cout << "空" << endl;
}
else
{
cout << "deque.size():" << d2.size() << endl;
}
d3.resize(10000);
d3.resize(10000, 10);
d5.push_back(10);
d6.push_front(10);
d7.pop_back();
d1.pop_front();
for (int i = 0; i < d1.size(); i++)
{
cout << d1[i] << endl;
cout << d1.at(i) << endl;
}
try
{
cout << d1[10000000] << endl;
cout << d1.at(10000000) << endl;
}
catch (...)
{
cout << "wrong" << endl;
}
cout << d2.front() << endl;
cout << d2.back() << endl;
d3.insert(d3.begin(), 10, 100);
d3.insert(d3.begin(), ++d2.begin(), d2.end());
d5.clear();
d6.erase(++d6.begin(), --d6.end());
d6.erase(d6.begin());
}