C++中STL容器之动态数组——vector

1.vector与数组
1.1 增删改查

数组向量都可以用来存储元素列表,向量可以用来替换数组,且比数组更灵活(类vector包含很多成员函数)。但是,如果列表大小固定,则使用数组会更加高效。

关于数组和向量的不同和相似之处如下表所示:

操作数组向量
创建一个数组/向量string a[10]vector<string> v
访问一个元素a[index]v[index]
更新一个元素a[index] = “China”v[index ] = " China"
返回大小sizeof(a)/sizeof(a[0])v.size()
追加新的元素v.pusk_back(“Chian”)
删除(最后的)元素v.pop_back()
删除所有的元素v.clear()
1.2 复杂度
操作时间复杂度
push_back()O(1)
pop_back()O(1)
insert()O(n)
erase()O)(n)

注释

  • vector是动态数组,在堆中分配内存
  • vector与数组一样,都是分配的一段连续的内存空间,并且起始地址不变,因此能够很好支持随机存取,复杂度为 O ( 1 ) O(1) O(1) 。但是在头部或者中间进行插入和删除的时候会涉及元素的移动,即内存块的拷贝,所以在中间插入或者删除元素的复杂度为 O ( n ) O(n) O(n)
  • 对最后元素操作最快(在后面添加删除元素最快),此时一般不需要移动内存。
2.vector的用法

vector是一个模板类 所以使用时要用vector<int> a 这样的方式来声明一个vector,即

template<typename T>
vector<T> vectorname;

初始化vector的方法:
初始化vector的方法

2.1 基本用法
操作含义
vector<T> name声明一个名为name的向量
c.back()传回最后一个数据,不检查这个数据是否存在
clear()删除所有元素
erase()删除一个或者多个元素
empty()测试是否为空
c.front()传回第一个数据
push_back()在尾部添加元素
pop_back()在尾部删除元素
resize()改变大小
size()返回v中元素个数
  • vector之间可以直接赋值或者作为函数的返回值
  • push_back()和pop_back()无需改变数组长度,自动会增加和减小数组长度
  • 增加长度后增加的元素值为0

示例代码:

#include<iostream>
#include<vector> //vector类需要添加的头文件

using namespace std;


int main() {
	//声明并初始化一个向量a = [0,1,2,3,4]
	vector<int> a;
	for (int i = 0; i < 5; i++) a.push_back(i); //在末尾追加数
	cout << "print1 a的值:" << endl;
	for (int i = 0; i < a.size(); i++) {
		cout << a[i] << " ";
	}
	cout << endl;

	//向量间直接赋值
	vector<int> b;
	b = a;
	cout << "print2 b=a: 直接赋值" << endl;
	for (int i = 0; i < b.size(); i++) {
		cout << b[i] << " ";
	}
	cout << endl;

	//改变大小
	cout << "a.size() = " << a.size() << endl;
	a.resize(7);
	cout << "a.size() = after resize(7) :" << a.size() << endl;
	cout << "print3 after resize(7):" << endl;
	for (int i = 0; i < a.size(); i++) {
		cout << a[i] << " ";
	}
	cout << endl;

	//在尾部删除元素
	a.pop_back();
	cout << "a.size() = after pop_back() :" << a.size() << endl;
	cout << "print4 after pop_back():" << endl;
	for (int i = 0; i < a.size(); i++) {
		cout << a[i] << " ";
	}
	cout << endl;
	//测试是否为空
	cout << "a.empty()?:" << a.empty() << endl;

	//删除某一元素
	a.erase(a.begin()+2); //删除a[2]
	cout << "print5 after erase a[2]:" << endl;
	for (int i = 0; i < a.size(); i++) {
		cout << a[i] << " ";
	}
	cout << endl;
	//清空所有元素
	a.clear();
	cout << "a.size() = after a.clear() :" << a.size() << endl;
	cout << "a.empty()? after a.clear(): " << a.empty() << endl;
	cout << "print6 after a.clear():" << endl;
	for (int i = 0; i < a.size(); i++) {
		cout << a[i] << " ";
	}
	cout << endl;
	
	return 0;
}

输出结果

print1 a的值:
0 1 2 3 4
print2 b=a: 直接赋值
0 1 2 3 4
a.size() = 5
a.size() = after resize(7) :7
print3 after resize(7):
0 1 2 3 4 0 0
a.size() = after pop_back() :6
print4 after pop_back():
0 1 2 3 4 0
a.empty()?:0
print5 after erase a[2]:
0 1 3 4 0
a.size() = after a.clear() :0
a.empty()? after a.clear(): 1
print6 after a.clear():
2.2 STL中vector的方法:
2.2.1 非变动操作
操作含义
c.capacity()返回重新分配空间前可容纳的最大元素数量
c.empty()判断容器是否为空
c.max_size()返回容器最大容纳数据的数量(固定值)
c.resize(num)重新指定队列的长度
c.reserve(n)保留容量为n
c.size()返回容器中实际数据的个数
2.2.2 赋值操作
操作含义
c1 = c2将c2的全部元素赋值给c1
c.assign(n,elem)将n个elem的拷贝赋值给c
c.assign(beg,end)将[beg; end)区间中的数据赋值给c
c1.swap(c2)将c1和c2元素互换
swap(c1,c2)同上,全局函数
2.2.3 元素存取
操作含义
c. at(idx)传回索引idx所指的数据,如果idx越界,抛出out_of_range
c.front()传回第一个数据
c.back()传回最后一个数据,不检查这个数据是否存在
2.2.4 迭代器相关函数
操作含义
c.begin()返回一个迭代器,指向第一个元素(即是指向第一个数据的一个指针)
c.end()返回一个迭代器(指针),指向最后一个元素的下一个位置(实际不存在)
c.rbegin()返回一个逆向迭代器,指向逆向遍历的第一个元素
c.rend()返回一个逆向迭代器,指向最后一个数据的下一个位置

迭代器持续有效,除非发生下面两种情况:

  • 删除或插入元素
  • 容量变化而引起的内存重新分配
2.2.5 插入(insert)元素
操作含义
c.insert(pos,elem)在pos位置插入一个elem拷贝,传回新数据位置
c.insert(pos,n,elem)在pos位置插入n个elem数据,无返回值
c.insert(pos,beg,end)在pos位置插入在[beg,end)区间的数据。无返回值
c.push_back(elem)在尾部加入一个元素elem的副本
2.2.6 移除(remove)元素
操作含义
c.pop_back()删除最后一个数据
c.erase(pos)删除pos位置的数据,传回下一个数据的位置
c.erase(beg,end)删除[beg,end)区间的数据,传回下一个数据的位置
c.clear()移除容器中所有数据
c.resize(num)将元素数量改为num(增加的元素默认初始化,多余的元素被删除)
c.resize(num.e)将元素数量改为num(增加的元素是e的副本)

注意:

vector的v.erase()
v.erase(v.begin()+2);//删除v[2]元素 
v.erase(v.begin()+2,v.begin()+5);//删除v[2] v[3] v[4] 
v.clear();//清空 

示例代码:

#include<iostream>
#include<vector> //vector类需要添加的头文件

using namespace std;


int main() {
	//声明并初始化一个数组a = [0,1,2,3,4,4,4]
	int a[] = { 0,1,2,3,4 ,4,4};
	//将数组a的值赋值给向量b;
	vector<int> b;
	int alen = sizeof(a) / sizeof(a[0]); //数组a的长度
	cout << "print 数组a的长度:" << alen << endl;
	b.assign(a, a + alen); //注意c.assign(beg,end)中beg和end是区间地址边界,不包含end
	cout << "print1 赋值后b的值:" << endl;
	for (int i = 0; i < b.size(); i++) {
		cout << b[i] << " ";
	}
	cout << endl;

	cout << "print2 b的最后一个值:" << b.back() << endl;   //返回的是一个数值
	cout << "print3 b的第一个值:" << b.front() << endl;   //返回的是一个数值
	printf("print4 b的迭代器第一个元素的地址: %p\n", b.begin()); //返回的是地址
	cout << "print5 b的第一个元素的地址&b[0]:" << &b[0] << endl; //发现和上面并不相等
	cout << "print6 b的迭代器的第一个元素的地址中所存储的值:" << *b.begin() << endl;

	return 0;
}

输出结果:

print 数组a的长度:7
print1 赋值后b的值:
0 1 2 3 4 4 4
print2 b的最后一个值:4
print3 b的第一个值:0
print4 b的迭代器第一个元素的地址: 00E02FF0
print5 b的第一个元素的地址&b[0]:00E02098
print6 b的迭代器的第一个元素的地址中所存储的值:0
请按任意键继续. . .
2.3 vector声明多维向量

多维数组可以用嵌套的向量来实现,如二维数组可以用向量的向量来实现。
例如下面代码实现对二位数组求和:

#include<iostream>
#include<vector> //vector类需要添加的头文件

using namespace std;

int sum(vector<vector<int>>& matrix) {
	int total = 0;
	for (int i = 0; i < matrix.size(); i++) {
		for (int j = 0; j < matrix[i].size(); j++) total += matrix[i][j];
	}
	return total;
}

int main() {
	vector<vector<int>> matrix(4); //4行
	for (int i = 0; i < 4; i++) matrix[i] = vector<int>(3); //每行3列
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 3; j++) matrix[i][j] = 3 * i + j + 1;
	}
	
	cout << "print1 矩阵matrix: " << endl;
	for (int i = 0; i < 4; i++) {
		for (int j = 0; j < 3; j++) cout << matrix[i][j]<<" ";
		cout << endl;
	}
	cout << "print2 矩阵matrix第一维度: " << matrix.size() << endl;
	cout << "print3 矩阵matrix第二维维度: " << matrix[0].size() << endl;
	cout << "print4 矩阵matrix所有元素的和 " << sum(matrix) << endl;

	return 0;
}

输出结果:

print1 矩阵matrix:
1 2 3
4 5 6
7 8 9
10 11 12
print2 矩阵matrix第一维度: 4
print3 矩阵matrix第二维维度: 3
print4 矩阵matrix所有元素的和 78
请按任意键继续. . .
参考资料

1.柳婼 の blog
https://www.liuchuo.net/archives/tag/c/page/6
2.Introduction to Programming with C++. Y.Daniel Liang著.

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值