C++STL之vector容器:基本使用及模拟实现

目录

vector的概念

vector的使用

1.push_back / pop_back / insert / erase 的使用

push_back尾插

pop_back尾删

insert任意位置的插入

erase任意位置的删除

2.构造函数和拷贝构造

3.赋值运算符 operator=

4.遍历数据

5.迭代器

6.容量相关的接口

1. 在 VS 中容量的增长是按1.5倍增长的

2 .在Linux中,则是按 2 倍增长的

3. vector 插入数据是如何实现的,为什么增容增加 2倍,1.5倍不行吗?

迭代器失效(☆)

情景一:

情景二:

vector的模拟实现

源码的引入

基本结构的搭建

vector.h

vector的模拟实现

push_back 尾插

reserve 增容

pop_back 尾删

insert 任意位置的插入

erase 任意位置的删除

resize的实现

拷贝构造

operator= 赋值

memcpy拷贝问题

整体代码

vector.h

test.c

动态二维数组的理解


vector的概念

上一节,我们学习了string的使用及模拟实现。

String 是把单向信息存起来,比如身份证号码,而vector是把多项相同的信息存起来,比如每个人的姓名、年龄、分数 保存到 vector 容器中。

我们可以把 vector看成顺序表,只不过在顺序表的基础上增加了一些功能,提供了丰富的成员函数和操作符重载,如迭代器支持、各种算法的适配等。而顺序表比较单一。

string 和 vector<char> 有什么区别???

  • vector 是一个动态的数组,里面存指定的类型,不够都可以动态增长
  • string 也具有类似的动态特性,能够自动管理内存以适应字符串内容的变化
  • string 有 \0,vector 没有 \0
  • string 支持+=、输入操作
  • vector存其它类型+=,输入的意义就不大。

vector的使用

和string的使用类似,如果遇到不会的可以查阅文档。

1.push_back / pop_back / insert / erase 的使用

push_back尾插

#include <iostream>
using namespace std;
#include <vector>
void test_vector1()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	for (auto e : v) 
	{
		cout << e << " ";   // 1 2 3 4
	}
	cout << endl;
}

int main() 
{
	test_vector1();
	return 0;
}

pop_back尾删

#include <iostream>
using namespace std;
#include <vector>
void test_vector1()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	//尾删
	v.pop_back();
	v.pop_back();
	for (auto e : v) 
	{
		cout << e << " ";   // 1 2 
	}
	cout << endl;
}

int main() 
{
	test_vector1();
	return 0;
}

insert任意位置的插入

insert 需要配合迭代器使用

#include <iostream>
using namespace std;
#include <vector>
void test_vector1()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.insert(v.begin(), 0); //头插 0
	v.insert(v.begin(), -1); //再头插 -1 
	v.insert(v.begin() + 1, 10);// 再插入完 -1 之后,再 -1的后面插入 10
	for (auto e : v)
	{
		cout << e << " ";  // -1  10  0  1  2  3  4
	}
	cout << endl;
}

int main() 
{
	test_vector1();
	return 0;
}

erase任意位置的删除

同样配合迭代器使用 v.erase( begin() + 1),  加几就是删掉下标为几的值

#include <iostream>
using namespace std;
#include <vector>
void test_vector1()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	//任意位置的删除
	v.erase(v.begin()); // 删除第一个位置,变成 2 3 4
	v.erase(v.begin() + 1); //2 3 4 中,删除 3 这个元元素
	for (auto e : v)
	{
		cout << e << " "; // 2  4
	}
	cout << endl;
}

int main() 
{
	test_vector1();
	return 0;
}

假设我要删除的数为指定的值的时候该怎么删除呢?

使用迭代器删除的时候相对于指定该数的下标,问题是我们不知道这个数的位置,如何删除呢?vector 中没有提供 find 查找功能

进入手册,在 C++ 的标准算法库<algorithm>中有 find 算法可以用于在容器中查找特定元素。(记得包文件)

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
void test_vector1()
{
	vector<int> v;
	v.push_back(10);
	v.push_back(20);
	v.push_back(5);
	v.push_back(30);
	v.push_back(40);

	vector<int>::iterator pos = find(v.begin(), v.end(), 5); //find用的算法里面的
	if (pos != v.end())
	{
		v.erase(pos);  // erase中依旧填 迭代器
	}
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;

}

int main() 
{
	test_vector1();
	return 0;
}

2.构造函数和拷贝构造

#include <iostream>
using namespace std;
#include <vector>
void test_vector2()
{
	vector<int> v1;   //构造,初始化 v1
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	vector<int> v2(v1); //拷贝构造 即初始化 v2
	for (size_t i = 0; i < v1.size(); ++i)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	for (size_t i = 0; i < v2.size(); ++i)
	{
		cout << v2[i] << " ";
	}
	cout << endl;
}

int main() 
{
	test_vector2();
	return 0;
}

3.赋值运算符 operator=

using namespace std;
#include <vector>
void test_vector3()
{
	vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);

	vector<int> v3;
	v3.push_back(10);
	v3.push_back(20);
	v3.push_back(30);
	v3.push_back(40);
	v1 = v3;  //赋值
	for (size_t i = 0; i < v1.size(); ++i)
	{
		cout << v1[i] << " ";
	}	
	cout << endl;
}

int main() 
{
	test_vector3();
	return 0;
}

4.遍历数据

#include <iostream>
using namespace std;
#include <vector>
void test_vector4()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	//1.遍历数据  修改数据
	//operator[] + size
	for (size_t i = 0; i < v.size(); ++i)
	{
		v[i] *= 2; //修改数据,都可以修改
		cout << v[i] << " ";
	}
	cout << endl;
	//2迭代器
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	//3.范围for  -> 被编译器替换成迭代器方式遍历支持的
	for (auto e : v)   // 加上引用后,修改会影响原容器中的元素
	{
		//e *= 2; //不加引用修改不会影响原来的容器
		cout << e << " ";
	}
	cout << endl;
}

int main() 
{
	test_vector4();
	return 0;
}

5.迭代器

迭代器有四种:非const 正向、非const 反向、const 正向、const 反向

const 对象通常在传参的时候才会产生,如果定义对象的时候就把对象定义成 const,那么都不能插入数据了

#include <iostream>
using namespace std;
#include <vector>
//const 正向迭代器,const不能写,可以读
void print_vector(const vector<int>& vt)
{
	vector<int>::const_iterator it = vt.begin();
	while (it != vt.end())
	{
		//*it = 1; 不能写
		cout << *it << " ";
		++it;
	}
	cout << endl;
}
//const反向迭代器,
void print_rvector(const vector<int>& vt) 
{
	vector<int>::const_reverse_iterator rit = vt.rbegin();
	while (rit != vt.rend()) 
	{
		//不能写(修改)
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}
void test_vector5() 
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	//1.正向迭代器
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	
	//3.const 正向迭代器
	print_vector(v);
	//4.const 反向迭代器
	print_rvector(v);

	//2.反向迭代器
	vector<int>::reverse_iterator rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
}
int main() 
{
	test_vector5();
	return 0;
}

6.容量相关的接口

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值