zoukankan      html  css  js  c++  java
  • STL容器之vector

    vector概述

       vector的数据安排以及操作方式,与数组非常类似,两者的唯一差别在于空间的运用的灵活性。数组是静态空间,一旦配置了就不能改变:要换个大(或小)一点的房子,可以,一切细节都由自己来:首先配置一块新空间,然后将元素从旧址一一搬往新址,再把原来的空间释还给系统。vector是动态空间,随着元素的加入,它的内部机制会自行扩展空间以容纳新元素。以此,vector的运用对于内存的合理利用与运用的灵活性有很大的帮助,我们也不必因为害怕空间不足而一开始就要求一个大块头的数组了,我们可以安心使用vector,吃多少用多少。

    vector定义摘要

    以下是vector定义的源代码摘录

    //alloc SGI STL的空间配置器

    template <class T,class Alloc = alloc>

    class vector

    {

      public:

      //vectord的嵌套类别定义

      typedef  T           value_type; 

      typedef  value_type*  pointer;

      typedef  value_type*  iterator;

      typedef  value_tpe&  reference;

      typedef  size_t       size_type;

      typdefe  ptrdiff_t     difference_type;

     

      protected:

      //simple_alloc SGI STL的空间配置器

       typedef  simple_alloc<value_type,Alloc>  data_allocator;

       

      iterator  start;//表示目前使用空间的头

      iterator  finish;//表示目前使用空间的尾

      iterator  end_of_storage;//表示目前可用空间的尾

     

      void  insert_aux(iterator position,const T& x);

      void  deallocate()

      {

    if(start)

      data_allocator::deallocate(start,end_of_storage - start);

      }

      void  fill_initialize(size_type n, const T& value)

      {

    start = allocate_add_fill(n,value);

    finish = start + n;

    end_of_storage = finish;

      }

     

    public:

      iterator    begin() { return start; }//返回vector

      iterator    end() { return finish; }//返回vector

      size_type  size() const { return  size_type(end() - begin()); } //获得vector大小

      size_type  capacity() const  //获得vector空间大小

      {  

    return size_type( end_of_storage - begin()); 

      }  

      bool empty() const { return begin() == end();}//判断vector是否为空

      reference operator[] (size_type n) { return *(begin() + n) ; }//重载[]运算符

     

     vector():start(0),finish(0),end_of_storage(0) {}//无参构造

     explicit vector(size_type n) { fill_initialize(n,T()); }//指定vector初始大小

     vector(size_type n, const T& value)//指定vector初始大小和初始值

     {

       fill_initialize(n,value); 

     }

    vector(int n,const T& value){fill_initialize(n,value); }

    vector(long n,const T& value){fill_initialize(n,value); }

     

    ~vector()

    {

      destory(start,finish);

      deallocate();

    }

    reference  front() { return *begin(); } //返回第一个元素

    reference  back() { return *(end() - 1); } //返回最后一个元素

     

    void push_back(const T& x)  //将元素插入至尾部

    {

       if(finish != end_of_storage)

       {

         construct(finish,x);//全局函数

         ++finish;

       }

       else

       {

          insert_aux(end(),x);

       }

    }

       

    void pop_back()//删除尾部元素

    {

      --finish;

      destroy(finish); //全局函数

    }

     

    iterator  erase(iterator position)  //清除某位置上的元素

    {

       if(position + 1 != end())

         copy(position + 1, finish, positon);

      -- finish;

      destroy(finish);

      return position;

    }

     

    void  resize(size_type  new_size,  const T& x)

    {

       if(new_size < size())

       {

          erase( begin() + new_size(),end());

       }

       else

       {

     insert(end(),new_size - size(),x); 

       }

    }

    void resize(size_type new_size) { resize(new_size,T()); }

    void clear(){ erase(begin(),end());} //清空vector

     

    protected:

       //配置空间并填满内容

       iterator allocate_and_fill(size_type n , const  T& x)

    {

       iterator resualt = data_allocator::allocate(n);

       uninitialized_fill_n(result,n,x);//全局函数

       return resualt;

    }

    };

    vector 的迭代器

       vector 维护的是一个连续的线性空间,所以不论其元素类型为何,普通指针

    都可以作为vector的迭代器而满足所有必要条件,因为vector迭代器所需要的

    操作行为,如operator*,operator->,operator++,operator--,operator+,operator-,

    operator+=,operator-=,普通指针天生就具备。vector支持随机存取,而普通指针正有这样的能力。

     

    template <class T,class Alloc = alloc>

    class vector

    {

      public:

      typedef  T   value_type; 

      typedef  value_type*  iterator;

      ...

    };

    根据上述定义,如果写出这样的代码:

    vector<int>:;iterator ivite;

    vector<Shape>::iterator svite;

     

    ivite的类型其实就是 int*, svite的类型就是Shap*

     

     

    vector实例:

    #include<vector>

    #include<iostream>

    #include<algorithm>

    using namespace std;

     

    int main(int argc, char* argv[])

    {

    int i;

    vector<int> iv(2,9);//初始大小为2  初始值为9

    cout<<"size="<<iv.size()<<endl;   //size = 2 

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 2

        cout<<endl;

     

    iv.push_back(1);//尾部插入1

    cout<<"size="<<iv.size()<<endl;   //size = 3 

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 4

        cout<<endl;

     

    iv.push_back(2);//尾部插入2

    cout<<"size="<<iv.size()<<endl;   //size = 4 

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 4

        cout<<endl;

     

    iv.push_back(3);//尾部插入3

    cout<<"size="<<iv.size()<<endl;   //size = 5

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 8

        cout<<endl;

     

    iv.push_back(4);//尾部插入4

    cout<<"size="<<iv.size()<<endl;   //size = 6

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 8

        cout<<endl;

     

    for(i=0;i<iv.size();i++)  //输出 9 9 1 2 3 4

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    iv.push_back(5);//尾部插入5

    cout<<"size="<<iv.size()<<endl;   //size = 7

    cout<<"capacity="<<iv.capacity()<<endl; //capacity = 8

        cout<<endl;

     

        for(i=0;i<iv.size();i++)  //输出 9 9 1 2 3 4 5

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    iv.pop_back();//删除尾部元素

    iv.pop_back();//删除尾部元素

    cout<<"size="<<iv.size()<<endl;  //size = 5

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        cout<<endl;

     

    iv.pop_back();//删除尾部元素

        cout<<"size="<<iv.size()<<endl;  //size = 4

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        cout<<endl;

     

        for(i=0;i<iv.size();i++)  //输出 9 9 1 2 

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    vector<int>::iterator ivite = find(iv.begin(),iv.end(),1);//查找元素为1的位置

    if(ivite) iv.erase(ivite);//删除元素1

        cout<<"size="<<iv.size()<<endl;  //size = 3

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        for(i=0;i<iv.size();i++)  //输出 9 9  2 

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    ivite = find(iv.begin(),iv.end(),2);//查找元素为2的位置

        if(ivite) iv.insert(ivite,3,7);//2前插入37

        cout<<"size="<<iv.size()<<endl;  //size = 2

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

        for(i=0;i<iv.size();i++)  //输出 9 9 7 7 7 2

    {

    cout<<iv[i]<<' ';

    }

    cout<<endl;

     

    iv.clear();//清空

    cout<<"size="<<iv.size()<<endl;  //size = 0

    cout<<"capacity="<<iv.capacity()<<endl;  //capacity=8

    return 0;

    }

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    LeetCode 189. Rotate Array
    LeetCode 965. Univalued Binary Tree
    LeetCode 111. Minimum Depth of Binary Tree
    LeetCode 104. Maximum Depth of Binary Tree
    Windows下MySQL的安装与配置
    LeetCode 58. Length of Last Word
    LeetCode 41. First Missing Positive
    LeetCode 283. Move Zeroes
    《蚂蚁金服11.11:支付宝和蚂蚁花呗的技术架构及实践》读后感
    删除docker下的镜像
  • 原文地址:https://www.cnblogs.com/marshhu/p/3454408.html
Copyright © 2011-2022 走看看