例说数据结构&STL(一)——vector

1 白话vector(向量)
  数据结构vector又称为动态数组,因为它无需像普通数组定义的时候规定具体空间大小,一定程度上可以节约内存空间。但是它又具有普通数组连续物理内存存储的优势,即各元素之间构成一个线性的前后次序,数据的物理存储位置与其逻辑次序完全吻合,这样我们就可以常数级时间内通过秩(下标)访问每个元素。
  当然STL中vector底层构建还是基于静态数组实现的,只不过固定大小由系统自动完成,不用我们操心。一旦数据量超过系统初始设置的内存大小,系统也会自动拷贝数据到一块更大的连续空间存储,这个固定大小可以通过vector类提供的接口查询。废话不多说,下面直接进入STL中vector模板类的示例介绍中。
2 STL中vector实战
 2.1 头文件包含
  STL容器vector使用首先需要在程序开头添加头文件包含,这样才可以直接调用vector中各种类方法。

#include<vector>

  其次一定要加上C++标准库命名空间std,一种方便形式是在文件头文件后面添加using namespace std;,这样全文可以直接使用std下面定义的类与方法了。还可以每个实体前声明诸如std::vector<int>形式,这样稍显复杂,但是如果程序中有自己定义的命名空间就最好这样声明了。
 2.2 变量声明
  由于vector是模板类,所以我们再定义vector变量的时候需要指明容器保存的类型,这种数据类型可以是int,long,float等常见类型,还可以是定义的类诸如string等。下面我们以int类型为例。

vector<int> vec_one;  //最简单vector实例定义

  定义变量同时初始化如下:

vector<int> vec_sed(10,1);         //分配10个空间,并且初始化为1

int nArr[] = {0,1,2,3,4,5,6,7,8,9};
//指针初始化为一个数组某一范围内数据,等价vector<int> vec_thr(&nArr[0],&nArr[9]);
vector<int> vec_thr(nArr,nArr+10); 

vector<int> vec_for(vec_thr.begin(),vec_thr.end()); //迭代器初始化为另一个vector某一范围内数据

  上面不同vector实例化是由类中构造器重载所匹配的,但是需要注意下面的初始化方式:

int nLen = 10;
vector<int> vec_fiv(nLen); //分配nLen个空间,并且每个空间初始化为0

  上面实例并不是初始化一个存储10的vector,而是分配了10个空间,并且每个空间初始化为0(构造函数默认初始化数值是0,所以没有明确指出初始值就是0),切记不要弄错。
 2.3 查询元素

int nData1 = vec_fir.front(); //查询vector中第一个元素
int nData2 = vec_fir.back();  //查询vector中最后一个个元素
int nData3 = vec_fir.at(8);   //查询vector中索引为8(即第9个)元素
int nData4 = vec_fir[8];      //同上,operator[]运算符重载

 2.4 赋值操作

vec_fir.assign(10,2);                          //重新赋值vec_fir实例中数据为102

vec_fir.assign(vec_sed.begin(),vec_sed.end()); //重新赋值vec_fir为vec_sed

 2.5 vector尾部操作
  由于vector数组只需常数级时间花费在其尾部添加数据,所以STL提供了尾部删除元素pop_back()与添加元素push_back()的方法接口,也很好记忆,back为尾部的意思,pop是删除,push是推进。而首部添加与删除就需要花费线性级时间,所以没有pop_front()与push_front()对应方法(后面介绍的双向链表list就有)。使用如下:

vec_fir.push_back(10) //vector尾部添加一个10数据

vec_fir.pop_back()   //删除vector尾部一个数据

 2.6 删除操作

vec_fir.erase(vec_fir.begin()); //删除vec_fir第一个数据(索引删除)

vec_fir.erase(vec_fir.begin(),vec_fir.begin()+5); //删除vec_fir第一个到第五个间断数据

 2.7 插入操作
  与删除操作一样,插入操作的时间复杂度是线性级,因为我们再删除或者插入数值后需要移动剩余所有数据,从而让数据存放在连续的空间中。

vec_fir.insert(vec_fir.begin(),10086); //开始位置插入一个10086数据

vec_fir.insert(vec_fir.begin(),10,99); //开始位置插入10个初始化为99的数据集

vec_fir.insert(vec_fir.begin(),vec_sed.begin().vec_sed.begin()+5); //将vec_sed开始的5个数插入在vec_fir开头

 2.8 遍历vector
  由于vector数据存放在一块物理内存连续的空间,所以我们可以通过下标顺序访问。

for(size_t i=0; i<vec_fir.size(); i++) //vec_fir.size()是统计数组中数据个数
    cout<<vec_fir[i]<<endl; //或者vec_fir.at(i)

  此外还可以迭代器(指针)累加连续访问每个数直到结尾,迭代器(iterator)是STL一个重要概念,简单理解可以为指针,每个迭代器存储一个vector中数据地址空间。使用迭代器需要另包含头文件#include<iterator>,因为它不仅vector可以使用,后面很多STL容器都可以使用。

vector<int>::iterator iter;
for(iter=vec_fir.begin();iter!=vec_fir.end();iter++)
    cout<<*iter<<endl;

  另外还包括反向迭代,更详细介绍请另阅例说数据结构&STL(十二)——iterator
 2.9 其他接口

vec_fir.size(); //求解vector数据个数

//重新定义空间大小为100个空间,空间增加了则新增空间初始化为0,缩小了就仅保留前100个数据
vec_fir.resize(100); 

vec_fir.clear(); // 清空vector

vec_fir.swap(vec_sed); //交换两个vector中所有数据

 2.10 二维数组
  下面我们示例定义一个10*9的二维数组。

const size_t m=10, n=9;
vector<vector<int>> vec_2D_1(m,vector<int>(n)); //vector中存储的是vector,并且里面初始化m个保存n个0的vector的数据集

vector<vector<int>> vec_2D_2(m,vector<int>(n,1)); //所有数初始化为1

vector<vector<int>> vec_2D_3; 
vec_2D_3.resize(m,vector<int>(n,1));

3 小结
  至此,我们将STL容器中vector大部分方法接口介绍了一遍,相信大家有了一定的认识,最后还是需要自己动手实践才能真正很好的掌握。vector是STL基本容器,凭借其查询常数级,尾部插入常数级时间花费在很多程序中有大量的使用,所以学好vector是学号数据结构的第一步。
  以上是个人学习记录,由于能力和时间有限,如果有错误望读者纠正,谢谢!
  转载请注明出处:http://blog.csdn.net/fx677588/article/details/76166957

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值