STL中的vector

1、vector概述
vector的数据安排以及操作方式与array非常相似。两者的唯一差别在于空间运用的灵活性。array是静态空间,一旦配置了就不能改变。当要扩大空间时,首先要配置新空间,然后将数据转移,还要释放旧空间。vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。因此,vector的运用对于内存的合理利用与运用的灵活性有很大的帮助。

2、vector迭代器
vector维护的是一个连续性空间,所以不论其元素型别为何,普通指针都可以作为vector的迭代器而满足所有必要条件,因为vector迭代器所需要的操作行为,如:operator*、operator->、operator++、operator–、operator+、operator-、operator+=、operator-=。vector支持随机存取,而普通指针正有着这样的能力,所以vector提供的是Random Access Iterators(原生态指针),即所存储元素类型的指针。如下所示:

template<class T, class Alloc = alloc>
class vector
{
public:
    typedef T value_type;
    typedef value_type* iterator; //vector的迭代器是普通指针
    ...
};

根据上述定义,如果客户端写出这样的代码:
vector::iterator ivite;
vector::iterator svite;
那么:ivite的型别其实就是int*,svite的型别其实就是shape*。

3、vector的数据结构
vector所采用的数据结构非常简单:线性连续空间。它以两个迭代器start和finish分别指向配置得来的连续空间中目前已被使用的范围,并以迭代器end_of_storage指向整块连续空间(含备用空间)的尾部,如下所示:

template<class T, class Alloc = alloc>
class vector
{
    ...
protected:
    iterator start;             //表示目前使用空间的头
    iterator finish;            //表示目前使用空间的尾
    iterator end_of_storage;    //表示目前可用空间的尾
    ...
};

释:为了降低空间配置时的速度成本,vector实际配置的大小可能比客户端需求量更大一些,以备将来可能的扩充,这便是容量的观念。换句话说,一个vector的容量永远大于或等于其大小。一旦容量等于大小,便是满载,下次再有新增元素,整个vector就得另觅居所。运用start、finish、end_of_storage三个迭代器,便可轻易地提供首尾标识、大小、容量、空容器判断、标注([ ])运算子、最前端元素值、最后端元素值等机能,如下图所示。在这里插入图片描述
其中,部分元素的定义如下所示:

template<class T, class Alloc = alloc>
class vector
{
    ...
public:
    iterator begin()
    {
        return start;
    }
 
    iterator end()
    {
        return finish;
    }
 
    size_type size()const
    {
        return size_type(end() - begin());
    }
 
    size_type capacity()const
    {
        return size_type(end_of_storage - begin());
    }
 
    bool empty()const
    {
        return begin() == end();
    }
 
    reference operator[](size_type n)
    {
        return *(begin() + n);
    }

    reference front()
    {
        return *begin();
    }
    
    reference back()
    {
        return *(end() - 1);
    }
    ...
};

4、vector的构造与内存管理
所谓动态增加大小,并不是在原空间之后接续新空间,因为无法保证原空间之后尚有可供配置的空间,而是以原大小的两倍另外配置一块较大空间,然后将原内存内容拷贝过来,接着才开始在原内容之后构造新空间,并释放原空间。因此,对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效。
1)allocate_and_fill(size_type, const T& x):配置后填充
2)fill_initialize(size_typen, const T& value):填充并予以初始化。

5、vector的元素操作
使用vector时必须包含vector头文件:必须引入标准命名空间std。
(1)vector的成员函数,访问权限是protected。
1)start:表示目前使用空间的头;
2)finish:表示目前使用空间的尾;
3)end_of_storage:表示目前可用空间的尾;
4)insert_aux(iterator position, const T& x):在position位置插入一个n数值;
5)deallocate:销毁和释放vector的整个空间;
6)fill_initialize(size_typen, const T& value):填充n个元素,并初始化为value数值。

(2)vector的成员函数,访问权限是public。
1)begin():vector有效元素的首端。
2)end():vector有效元素的尾端。
3)size():获取vector中有效元素的个数。
4)resize():更改vector中有效元素的个数。
5)capacity():获取空间大小。
6)empty():检测是否为空。
7)reserve():改变容量的空间,但是不改变有效元素的个数。
8)front():vector有效元素的第一个元素,返回*begin()
9)back():vector有效元素的最后一个元素的前一个元素,返回end()-1。

(3)全局函数
1)push_back(n):将元素n插入到最后端。
2)pop_back():将最尾端元素取出。
3)erase():清除任意位置上的元素。
4)destroy():销毁。
5)insert(iterator position, size_type n, const T& x):在position位置插入n个x。
6)clear():将vector中的元素清空,不改变容量。
7)assign():赋值。
8)allocate_and_fill:配置空间并填满内容
9)uninitialized_fill_n
10)operator[]:随机访问。
11)resize:更改vector中有效元素的个数。

6、实例
【例1】

#include<vector>
#include<stdlib.h>
#include<iostream>

using namespace std;
 
void TestVector1()
{
    //构造一个空的vector
    vector<int> v1;
 
    //构造一个空的vector,但是底层空间大小设置为20个元素
    vector<int> v2(20);

    //构造一个vector对象,并用数组进行初始化
    int array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    vector<int> v3(array, array + sizeof(array) / sizeof(array[0]));

    //查看v1中元素的个数
    cout << "v1是一个空的vector" << endl;
    cout << "size1 =" << v1.size() << endl;
    //查看v1容量的大小
    cout << "capacity1 =" << v1.capacity() << endl << endl;
    
    cout << "v2是一个空的vector,但是底层空间大小设置为20个元素" << endl;
    cout << "size2 =" << v2.size() << endl;
    cout << "capacity2 =" << v2.capacity() << endl << endl;

    cout << "v3是初始化为0到9的vector" << endl;
    cout << "size3 =" << v3.size() << endl;
    cout << "capacity3 =" << v3.capacity() << endl << endl;

    //将v3赋值给v1后再次查看v1的元素个数和容量大小
    cout << "将v3赋值给v1后再次查看v1的元素个数和容量大小" << endl;
    v1 = v3;
    cout << "size1 =" << v1.size() << endl;
    cout << "capacity1 =" << v1.capacity() << endl;
    
    cout << "v1 data:";
    for (size_t i = 0; i < v1.size(); i++)
    {
        cout << v1[i] << " ";
    }
    cout << endl;

    cout << "v3 data:";
    for (size_t i = 0; i < v1.size(); i++)
    {
        cout << v1[i] << " ";
    }
    cout << endl << endl;

    //将v3赋值给v2后再次查看v2的元素个数和容量大小
    cout << "将v3赋值给v2后再次查看v2的元素个数和容量大小" << endl;
    v2 = v3;
    cout << "size2 =" << v2.size() << endl;
    cout << "capacity2 =" << v2.capacity() << endl;
 
    cout << "v2 data:";
    for (size_t i = 0; i < v1.size(); i++)
    {
        cout << v2[i] << " ";
    }
    cout << endl;

    cout << "v3 data:";
    for (size_t i = 0; i < v1.size(); i++)
    {
        cout << v1[i] << " ";
    }
    cout << endl << endl;

    //将v2赋值给v3后再次查看v3的元素个数和容量大小
    cout << "将v2赋值给v3后再次查看v3的元素个数和容量大小" << endl;
    v3 = v2;
    cout << "size3 =" << v3.size() << endl;
    cout << "capacity3 =" << v3.capacity() << endl;

    cout << "v3 data:";
    for (size_t i = 0; i < v3.size(); i++)
    {
        cout << v3[i] << " ";
    }
    cout << endl;

    cout << "v2 data:";
    for (size_t i = 0; i < v2.size(); i++)
    {
        cout << v2[i] << " ";
    }
    cout << endl;

    //注意:除了该函数的作用域之后,vector会自动将其内部的空间释放掉
}

int main()
{
    TestVector1();
    system("pause");
    return 0;
}

运行结果为:
在这里插入图片描述
【例2】push_back/pop_back/insert/erase

void TestVector2()
{
    //构造一个空的vector,然后向里面尾插入1、2、3、4、5,5个元素
    vector<int> v2;
    v2.push_back(1);
    v2.push_back(2);
    v2.push_back(3);
    v2.push_back(4);
    v2.push_back(5);
    cout << "尾插入5个元素后:" << endl;
    cout << "size =" << v2.size() << endl;
    cout << "capacity =" << v2.capacity() << endl;
 
    //打印vector中的元素
    cout << "v2 data:";
    for (size_t i = 0; i < v2.size(); i++)
    {
        cout << v2[i] << " ";
    }
    cout << endl << endl;
 
    //尾删
    v2.pop_back();
    v2.pop_back();
    cout << "尾删2个元素后" << endl;
    cout << "size =" << v2.size() << endl;
    cout << "capacity =" << v2.capacity() << endl;
    cout << "v2 data:";
    for (size_t i = 0; i < v2.size(); i++)
    {
        cout << v2[i] << " ";
    }
    cout << endl << endl;

    //insert——任意位置插入
    cout << "在vector起始位置插入数据0后:" << endl;
    v2.insert(v2.begin(), 0);
    cout << "size =" << v2.size() << endl;
    cout << "capacity =" << v2.capacity() << endl;
    cout << "v2 data:";
    vector<int>::iterator it = v2.begin();
    while (it != v2.end())
    {
        cout << *it++ << " ";
    }
    cout << endl << endl;

    cout << "在vector末尾位置插入2个8后:" << endl;
    v2.insert(v2.end(), 2, 8);
    cout << "size =" << v2.size() << endl;
    cout << "capacity =" << v2.capacity() << endl;
    cout << "v2 data:";
    for (size_t i = 0; i < v2.size(); i++)
    {
        cout << v2.at(i) << " ";
    }
    cout << endl << endl;
 
    //删除任意位置元素
    v2.erase(v2.begin()); //删除起始位置
    v2.erase(v2.begin(), v2.begin() + 2);//删除指定区间内的元素,注意区间是“[)”
 
    //使用vector迭代器遍历vector中所有元素
    it = v2.begin();
    cout << "删除起始位置元素和指定区间内元素后:" << endl;
    cout << "v2 data:";
    while (it != v2.end())
    {
        cout << *it++ << " ";
    }
    cout << endl;
}

运行结果为:
在这里插入图片描述
注意:
1)如果用迭代器vector代替for语句,会出错。因为:当插入新元素,内存不足时,系统会开辟新的空间,然后把原来的数据复制到新空间里,最后把原来的空间释放掉。
2)vector底层为连续空间,支持随机访问,vector重载了[]。

【例3】//assign/resize/clear

void TestVector3()
{
    vector<int> v3;
    v3.push_back(1);
    v3.push_back(2);
    v3.push_back(3);
    v3.push_back(4);
    v3.push_back(5);
    v3.push_back(6);
 
    cout << "v3 data:";
    for(size_t i = 0; i < v3.size(); ++i )
    {
    	cout << v3[i] << " ";
    }
    cout << endl;
 
    //给vector中5个值为8 的元素
    v3.assign(5, 8);
    cout << "给vector中5个值为8的元素后,v3 data:";
    for(size_t i = 0; i < v3.size(); i++)
    {
    	cout << v3[i] << " ";
    }
    cout << endl;
    cout << "size =" << v3.size() << endl;
    cout << "capacity =" << v3.capacity() << endl;

    //将vector中元素清空,注意底层容量的空间不变
    v3.clear();
    cout << "将vector中元素清空后,v3 data:";
    for(size_t i = 0; i < v3.size(); i++)
    {
    	cout << v3[i] << " ";
    }
    cout << endl;
    cout << "size =" << v3.size() << endl;
    cout << "capacity =" << v3.capacity() << endl;

   //将vector中的元素增加到3个
    v3.resize(3);
    cout << "将vector中元素增加到3个后,v3 data:";
    for(size_t i = 0; i < v3.size(); i++)
    {
    	cout << v3[i] << " ";
    }
    cout << endl;
    cout << "size =" << v3.size() << endl;
    cout << "capacity =" << v3.capacity() << endl;
    
    //将vector中的元素增加到10个
    v3.resize(10);
    cout << "将vector中的元素增加到10个后,v3 data:";
    for(size_t i = 0; i < v3.size(); i++)
    {
    	cout << v3[i] << " ";
    }
    cout << endl;
    cout << "size =" << v3.size() << endl;
    cout << "capacity =" << v3.capacity() << endl;

    //将vector底层容量空间增加到20个
    v3.reserve(20);
    cout << "将vector底层容量空间增加到20个后,v3 data:";
    for(size_t i = 0; i < v3.size(); i++)
    {
    	cout << v3[i] << " ";
    }
    cout << endl;
    cout << "size =" << v3.size() << endl;
    cout << "capacity =" << v3.capacity() << endl;
}

运行结果为:
在这里插入图片描述
注意:
(1)assign()是给vector进行赋值,在赋值之前,该方法会先将vector中原有的旧元素erase掉,然后再将新元素插入进去
(2)
1)resize(n)表示增加n个有效元素。
2)resize(n, data)将vector中元素改变到n个,并且n个元素的值为data。第二个参数可以不用传,默认情况下使用缺省值。
如果增加到某个个数而没有超过vector的实际容量,vector底层的容量不会改变。
3)reserve(n)函数只是将容量增大,不改变元素的个数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值