zoukankan      html  css  js  c++  java
  • 重读STL源码剖析:vector

    vector

    数据结构:

    三个数据成员:

    iterator start;//指向vector目前使用空间头,即vector.begin()

    iterator finish;//指向vector目前使用空间尾,即vector.end()

    iterator end_of_storage;//指向vector目前可用空间尾

    重要函数:

    begin():return start;

    end():return finish;

    size():return size_type(end()-begin());//size_type类似于value_type

    capacity():return end_of_storage-start;

    resize():

    首先判断新的大小是否小于原大小,如果小于size(),则将new_size之后的元素抹去

    否则在end()后补齐缺少的元素

    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);
    }
    

    clear():erase(begin(),end());//只析构,不释放空间  

    push_back():

    首先判断空间是否可用,如果可用,则在finish处构造,并将finish后移;

    如果不可用,则调用insert_aux搬移,下面具体介绍insert_aux();

    void push_back(const T& x)
    {
    	if(finish!=end_of_storage){
    		construct(finish,x);
    	++finish;
    	}
    	else
    		insert_aux(end(),x);
    }
    

      

    insert_aux()

    代码在P122页

    具体流程:

    首先判断当前是否还有容量(finish!=end_of_storage),如果还有容量,则将[position,finish)的元素整体后移一个,在原position上插入新元素,同时将finish向后移。

    如果没有容量,则首先计算新空间大小(为原来的2倍),并在开辟对应大小的新空间。

    开辟完成后将原来的元素拷贝到新空间,拷贝完成后析构源空间的元素并释放空间,重新调整三个迭代器start,finish与end_of_storage

    pop_back()

    pop_back()只是将finish前移并析构原back()的元素,并不释放空间

    void pop_back()
    {
      --finish;
      destory(finish);
    }
    

      

    erase()

    要删除的部分为[first,last),则首先将[last,finish)的元素复制到first及以后,然后清除覆盖区域以后的元素,也就是[i,finish)

    然后将finish移动到覆盖位置的尾端,返回插入位置的新元素

    iterator erase(iterator first,iterator last)
    {
    	iterator i=copy(last,finish,first);
    	destroy(i,finish);
    	finish=finish-(last-first);
    	return first;
    }
    

      

    insert()

    书上P125

    首先判断备用空间大小,如果大于或等于新增元素个数,则可以进行插入。

    此时:

    首先判断插入点之后的元素个数,如果插入点元素个数大于新增元素个数,则:

    首先将[finish-n,finish)的元素移动到finish之后(共n个元素),更新finish,然后将[position,old_finish-n)的元素移动到old_finish及之后(共m-n个元素),这样position~old_finish共m个元素都移动完毕,并腾出了n个元素的空间。再在[position,position+n)上覆盖新的元素。

    如果小于新增元素个数,则:

    首先在finish及之后的n-m个位置上生成插入元素,共n-m个。

    然后将position~old_finish共m个元素移动到新的尾部,这样腾出了m个元素空间。

    再在postition~old_finish上写入插入元素,共m个,则n-m+m=n,插入完成。

    如果空间不足:

    首先决定空间大小:len=old_size+max(old_size,n);//新长度要么扩容两倍能装下,如果装不下则要扩容到old_size+n刚好装下

    然后为新元素分配空间

    再然后将原来插入点之前的元素复制到新空间,再填入n个插入元素,再将原来插入点之后的元素复制到新空间。

    然后析构原来空间的元素,并释放空间。

    最后调整三个迭代器指向新空间的位置

  • 相关阅读:
    关于putty使用详解
    ORA12505: TNS: 监听程序当前无法识别连接描述符中所给出的SID等错误解决方法
    VMware的“Bridge”、“NAT”、“Hostonly”上网方式的区别
    转贴一个很全的sql用法
    网站
    sql exsits问题!!
    petshop4.0 profile
    一些应该知道的
    继承System.Web.UI.Page的页面基类
    应用程序域(Application Domain)
  • 原文地址:https://www.cnblogs.com/lxy-xf/p/11455670.html
Copyright © 2011-2022 走看看