C++ STL(容器:vector)

C++ vector 容器浅析:https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html (非常全面)

C++STL容器之Vector详解:https://blog.csdn.net/nilaodie110/article/details/88537555?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

目录

0vector容器

vector迭代器

vector数据结构

1vector常用API介绍

1.1构造函数

1.2赋值

1.3交换

1.4 常用

vector扩容机制:

其他常用 

1.5迭代器的使用 


0vector容器

vector(向量容器)的数据安排以及操作方式,与array非常相似,两者的唯一差别在于空间的运用灵活性,Array是静态空间,一旦配置了就不能改变,要换大一点或者小一点的空间。

vector是动态空间,随着元素的加入,它的内部机制会自动扩充空间以容纳新元素。因此vector的运用对于内存的合理利用与灵活性相较array有很大帮助。

vector会自动调整大小,根据添加元素,自动扩容,下面是示例代码。

    vector<int> V;
    for(int i = 0;i<10;++i)
    {
        V.push_back(i);
        cout<<V.capacity()<<endl;
    }

输出:

并不是单纯的扩大二倍,而是有一套自己的算法。

vector迭代器

器使用一个内存分配器对象来动态地处理它的存储需求。

vector维护一个线性空间,不论元素的类别如何,普通指针都可以作为vector的迭代器

vector<int> :: iterator it1;
vector<Teacher>::iterator it2;

显然it1int *类型,it2Teacher *类型

当然,也有const_iteratorreverse_iterator

vector数据结构

vector所采用的数据结构非常简单,线性连续空间,它以两个迭代器_Myfrist和_Mylast分别指向配置得来的连续空间中目前已被使用的范围,并以迭代器_Myend指向整块连续内存空间的尾端

为了降低空间配置时的速度成本,vector实际配置的大小可能比客户端需求大一些,以备将来可能的扩充,这边是容量的概念,

一个vector的容量永远大于或等于其大小,一旦容量等于其大小,就是满栈,下次再有新增元素,整个vector容器就得另觅居所。

所谓的另觅居所,就是要重新找一块内存空间,将目前的所有内容重新拷贝过去,此时,整个vector的首指针要改变指向。(见1.4)

支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。

操供了在序列末尾相对快速地添加/删除元素的操作。 只能从队尾插入元素

所以可以在API中看到,没有替换API,如果需要在中间插入或替换元素,则比较麻烦。

头文件

using namespace std;
#include<vector>;

1vector常用API介绍

1.1构造函数

vector():创建一个空vector
vector(int nSize):创建一个vector,元素个数为nSize
vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t
vector(const vector&):复制构造函数
vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中

操作:

    vector<int> V1;
    int arr[] = {1,2,3,4,5,6};
    vector<int> V2(arr,arr+sizeof(arr)/sizeof(int));

    qDebug()<<"V2";
    Print(V2);
    vector<int>V3(V2.begin(),V2.end());

    qDebug()<<"V3";
    Print(V3);

    vector<int> V4(10,300);
    qDebug()<<"V4";    
    Print(V4);

其中的Print函数会在之后介绍 

1.2赋值

void assign(int n,const T& x):设置向量中第n个元素的值为x
void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素

具体操作 

    //赋值
    vector<int> V5;
    V5.assign(V3.begin(),V3.end());
    qDebug()<<"V5";
    Print(V5);

1.3交换

void swap(vector&):交换两个同类型向量的数据

 具体操作:

    //互换
    V4.swap(V5);
    qDebug()<<"V4";

    Print(V4);
    qDebug()<<"V5";

    Print(V5);

1.4 常用

判断vector内是否为空 

bool empty() const:判断向量是否为空,若为空,则向量中无元素

返回大小,容量,最大允许值 

int size() const:返回向量中元素的个数
int capacity() const:返回当前向量所能容纳的最大元素值
int max_size() const:返回最大可允许的vector元素数量值

示例:

    vector<int>v;
    for(int i = 0;i<300;i++)
    {
        v.push_back(i);
    }
    qDebug()<<"V的容量"<<v.capacity();
    qDebug()<<"V的大小"<<v.size();

    v.resize(3);
    qDebug()<<"V的容量"<<v.capacity();
    qDebug()<<"V的大小"<<v.size();

vector扩容机制:

    vector<int>v;

    int * p = nullptr;
    int num=0;
    for(int i = 0;i<300;i++)
    {
        v.push_back(i);
        if(p != &v[0])
        {
            p = &v[0];
            num++;
        }
    }
    qDebug()<<"更换地址次数:"<<num - 1;

 解释程序:因为每次扩容,如果原始内存不够,会迁移内容到新的一块更大的内存中去,那么显然首地址的指向也会变好,if判断中的就是当vector扩容后,迁移地址的次数。

但是,当我们知道,vector即将放入300个数据,可以添加如下操作:reserve

   vector<int>v;
    v.reserve(300);
    int * p = nullptr;
    int num=0;
    for(int i = 0;i<300;i++)
    {
        v.push_back(i);
        if(p != &v[0])
        {
            p = &v[0];
            num++;
        }
    }
    qDebug()<<"更换地址次数:"<<num - 1;

一步到位,不需要其他变更地址的操作,节省空间和时间。

其他常用 

at(int i);//访问第i个元素,越界时,抛出out_of_range异常
operator[]//同上,越界时,直接报错
front();//返回容器中的第一个元素
back();//返回容器中的最后一个元素


insert(const_interator pos,int count,ele);//迭代器指向的位置pos插入count个元素ele
push_back(index);//在尾部插入元素index
pop_back();//最后一个元素出队,删除最后一个元素
clear();//清空

erase(const_interator start,const_interator end);//删除迭代器从start到end之间的元素
erase(const_interator pos);//删除迭代器指向的位置的元素
clear();//删除容器中所有元素

1.5迭代器的使用 

terator begin():返回向量头指针,指向第一个元素
iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
reverse_iterator rbegin():反向迭代器,指向最后一个元素
reverse_iterator rend():反向迭代器,指向第一个元素之前的位置

 打印(正向遍历) 

void Print(vector<int> &V)
{
    for(vector<int>::iterator it = V.begin();it!=V.end();++it)
    {
        qDebug()<<*it<<" ";

    }

}

(反向遍历) 

void A_Print(vector<int> &V)
{
    for(vector<int>::reverse_iterator ti = V.rbegin();ti!=V.rend();++ti)
    {
        qDebug()<<*ti<<" ";

    }

}

此处只是简单的介绍了几种非常常见的vector的API

更加全面的API介绍请移步:

https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html 

发布了85 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41605114/article/details/104945461