C++ vector使用详解

目录

一.vector的介绍

1.1 vector的本质

1.2 vector的特点

1.3 vector的优缺点

二.vector的初始化

三.vector iterator 的使用(迭代器)

 四 vector空间增长问题

五 vector 增删查改  

5.1 push_back

 5.2 pop_back()

 5.3 find() 函数

 5.4 insert()函数

 5.5 erase()函数

 5.6 swap() 函数

 5.7 operator[]


在学STL的时候希望大家多翻阅一下文档---vector的文档介绍:

https://cplusplus.com/reference/vector/vector/

一.vector的介绍

  C++是一门广泛应用于计算机程序设计的编程语言,而vector则是C++中非常常用的一个容器。下面将详细介绍C++ vector的特性和使用方法。

1.1 vector的本质

  vector是C++ STL(标准模板库)中的一个动态数组容器,可以在程序运行时动态地定义和改变其大小。与传统数组相比,vector的最大优势就是内存管理的自动化,让开发者不必过多关注内存的分配和释放问题。

1.2 vector的特点

(1)向量大小可变:由于vector是动态数组,所以其大小是可变的,可以通过push_back、insert、erase等操作实现动态调整数组大小。

(2)连续存储:不像链表那样需要额外的指针来建立节点间的联系,vector的元素都是连续存储的,这也使得它的访问速度比链表更快。

(3)支持随机访问:由于vector的元素是连续存储的,所以我们可以使用下标随机访问其中的元素,这也是vector的另一个优点。

(4)内存管理自动化:vector容器对内存进行了自动管理,对于开发者而言,不必再去手动分配内存空间或者释放内存空间。

1.3 vector的优缺点

  优点:

  1.采用连续的地址存储元素, 自然就支持下标的随机访问, 因此 访问元素的效率 更加高效。

  2.在尾部插入删除等行为不需要挪动数据,效率也较高。

缺点:

  1.空间不足扩容时,可能造成空间的浪费。(看下面的解释)

  2.在除尾部外 进行数据的插入删除操作时,会依次挪动数据,效率极为低下。

ps:从本质讲,vector使用动态分配数组来存储它的元素。

当新元素插入时候,这个数组需要被重新分配大小为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到新的数组。就时间而言,这是一个相对代价高的任务。因此每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小,而是采取对应的分配空间策略。


vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。


因此,vector占用了更多的存储空间。

二.vector的初始化

注意:<>里面的内容即为数组存储元素的类型

方式1.

//无参函数构造,即构造一个大小为0的数组
vector<int> v;

方式2:

//定义具有10个整型元素的变量,且给其中的每个元素初值为1
vector<int>  v(10,1);

方式3:

//拷贝构造
vector<int>  v1(v);

方式4:

//迭代器构造

vector<int> v1(v.begin(),v.end());

注意:vector的迭代器实际上是一个原生指针,我们来看一下这个方法在文档中的定义:

//这里的InputIterator 即为指针类型
vector (InputIterator first, InputIterator last);

因此我们也可以得出下面这个方式:

//数组赋值
int v[3]={1,2,3};
vector<int> v1(v,v+3);

这里实际上也是借助指针来赋值。

代码实现在下面板块写。

三.vector iterator 的使用(迭代器)

iterator 的使用接口说明
begin() + end()获取第一个数据位置的iterator/const_iterator, 获取最后一个数据的下一个位置的iterator/const_iterator
rbegin()+rend()获取最后一个数据位置的reverse_iterator,获取第一个数据前一个位置的reverse_iterator

 

 代码实现:

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	vector<int> v(10,1);

	vector<int> v1(v);

	vector<int>::iterator it = v.begin();

	while (it != v.end())
	{
		cout << *it << ' ';
		it++;
	}

	cout << endl;

	//有迭代器就有范围for

	for (auto x : v1)
	{
		cout << x << ' ';
	}
	cout << endl;


	return 0;
}

 结果为:

 

#include<iostream>
#include<vector>
using namespace std;

int main()
{

	vector<int> v;

	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };

	vector<int> v1(a, a + 10);

	for (auto x : v1)
	{
		cout << x << ' ';
	}
	cout << endl;

	vector<int> v2(v1.begin(), v1.end());

	for (auto x : v2)
	{
		cout << x << ' ';
	}
	cout << endl;


	return 0;
}

结果为:

 四 vector空间增长问题

函数定义接口说明
size()获取有效空间(数据个数)
capacity()获取最大空间(有效容量)
empty()判断空间大小是否为空
resize()改变vector 的size
reserve()改变vector 的capacity

代码示例:

#include<iostream>
#include<vector>

using namespace std;

int main()
{
	vector<int> v(20, 1);

	v.reserve(30);//这里将v的capacity扩大为30

	cout << v.size() << endl;

	cout << v.capacity() << endl;

	v.resize(30);

	cout << v.size() << endl;

	cout << v.capacity() << endl;


	return 0;
}

代码结果为:

 capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题
resize在开空间的同时还会进行初始化,影响size。

五 vector 增删查改
 

函数名称接口说明
push_back()尾插
pop_back()尾删
find()查找(注意这个是算法模块实现,不是vector的成员接口)
insert()在position之前插入val
erase()删除position位置的数据
swap()交换两个vector的数据空间
operator()像数组一样访问 下标随机访问

5.1 push_back

函数定义为:

  作用为:在顺序表尾部插入一个 val 数据


代码示例:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<int> v(2, 1);
	for (auto x : v)
	{
		cout << x << " ";
	}
	cout << endl;

	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	for (auto x : v)
	{
		cout << x << " ";
	}
	cout << endl;

	return 0;
}

代码结果为:

 5.2 pop_back()

函数定义:

 函数作用:

删除尾部元素。

代码示例:

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	vector<int> v(2, 1);
	for (auto x : v)
	{
		cout << x << " ";
	}
	cout << endl;

	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	v.push_back(3);
	for (auto x : v)
	{
		cout << x << " ";
	}
	cout << endl;

	v.pop_back();
	v.pop_back();
	v.pop_back();
	v.pop_back();

	for (auto x : v)
	{
		cout << x << " ";
	}
	cout << endl;

	return 0;
}

结果为:

 5.3 find() 函数

函数定义:

  其中,val 指定需要查找的元素值,返回值是指向第一个匹配元素的迭代器。如果没有找到匹配的元素,则返回指向 vector 容器末尾的迭代器(end())。 

代码示例:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> vec = { 10, 20, 30, 40, 50, 60 };

    // 查找元素
    auto iter = find(vec.begin(), vec.end(), 30);

    if (iter != vec.end())
    {
        cout << "元素找到,并位于 vector 的第 " << iter - vec.begin() << " 个位置上。" << endl;
    }
    else
    {
        cout << "未能找到指定元素。" << endl;
    }

    return 0;
}

 代码结果为:

 5.4 insert()函数

函数定义:

 其中,第一个版本的 insert() 函数使用了一个元素值作为插入项。

第二个版本的 insert() 函数接受了一对迭代器和一个元素值,表示在指定区间范围内插入相应数量的元素。

第三个版本的 insert() 函数则是在指定位置上插入输入区间中的所有元素。

 代码示例:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> vec = { 10, 20, 30 };
    auto pos = vec.begin() + 1;

    vec.insert(pos, 40);//在第二个位置插入一个40

    for (auto it : vec)
    {
        cout << it << " ";
    }
    cout << endl;

    pos = vec.begin() + 1;//注意迭代器失效

    vec.insert(pos, 2, 50);//在第二个元素前插入两个五十

    for (auto it : vec)
    {
        cout << it << " ";
    }
    cout << endl;

    vector<int> vec2 = { 60, 70, 80 };
    vec.insert(vec.begin(), vec2.begin(), vec2.end() );//在begin()位置之前插入一个迭代器区间的所有值

    for (auto it : vec)
    {
        cout << it << " ";
    }
    cout << endl;

    return 0;
}

输出结果:

 5.5 erase()函数

函数定义:

 其中,第一个版本的 erase() 函数删除指定位置上的单个元素

第二个版本的 erase() 函数则删除迭代器指定区间内的所有元素。

代码示例:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> vec = { 10, 20, 30, 40, 50 };

    for (auto it : vec)
    {
        cout << it << " ";
    }
    cout << endl;

    // 删除单个元素
    auto it1 = vec.erase(vec.begin() + 2);  // 删除第三个元素
    cout << "After erasing: ";
    for (auto it : vec)
    {
        cout << it << " ";
    }
    cout << endl;

    // 删除区间内的元素
    auto it2 = vec.erase(vec.begin() + 1, vec.begin() + 3);  // 删除第二个到第四个元素
    cout << "After erasing: ";
    for (auto it : vec)
    {
        cout << it << " ";
    }
    cout << endl;

    return 0;
}

代码结果为:

 5.6 swap() 函数

函数定义:

其中,swap() 通过引用传递另一个 vector 容器,并且不返回任何值。

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> vec1 = { 10, 20, 30 };
    vector<int> vec2 = { 40, 50, 60 };


    //交换前
    cout << "Before swapping:\n";
    cout << "vec1: ";
    for (auto it : vec1)
    {
        cout << it << " ";
    }
    cout << "\nvec2: ";
    for (auto it : vec2)
    {
        cout << it << " ";
    }
    cout << endl;

    vec1.swap(vec2);
    //交换后
    cout << "After swapping:\n";
    cout << "vec1: ";
    for (auto it : vec1)
    {
        cout << it << " ";
    }
    cout << "\nvec2: ";
    for (auto it : vec2)
    {
        cout << it << " ";
    }
    cout << endl;

    return 0;
}

代码结果:

 5.7 operator[]

支持vector像数组一样访问下标。

代码示例:

#include<iostream>
#include<vector>

using namespace std;

int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	v.push_back(6);

	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;

	return 0;
}

代码结果为:

 总结:

vector 是 C++ STL 库中常用的容器之一,其提供了丰富的成员函数,包括插入、删除、元素访问等操作。而其中的 swap() 函数则是在 vector 容器中交换两个容器元素的重要成员函数之一,通过掌握其使用方法,我们可以更加高效地开发出满足需求的应用程序。

  • 12
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值