deque源码1(deque概述、deque中的控制器)

deque源码2(deque迭代器、deque的数据结构)

deque源码3(deque的构造与内存、ctor、push_back、push_front)

deque源码4(deque元素操作:pop_back、pop_front、clear、erase、insert)

pop_back()函数如下:

void pop_back(){
if(finish.cur!=finish.first){
//最后缓冲区至少有一个元素
--finish.cur; //调整指针,相当于排除了最后元素
destory(finish.cur); //将最后元素构析
}
else
//最后缓冲区没有任何元素
pop_back_aux(); //这里将进行缓冲区的释放工作
} //只有当finish.cur==finish.first时才会被调用
template <class T,class Alloc,size_t BufSize>
void deque<T,Alloc,BufSize>::pop_back_aux(){
deallocate_node(finish.first); //释放最后一个缓冲区
finish.set_node(finish.node-); //调整finish的状态,使指向上一个缓冲区的最后一个元素
finish.cur=finish.last-;
destory(finish.cur); //将该元素析构
}

pop_front()函数如下:

void pop_front(){
if(start.cur!=start.last-){
//第一缓冲区至少有一个元素
destory(start.cur); //将第一元素析构
++start.cur; //调整指针,相当于排除了第一元素
}
else
//第一个缓冲区仅有一个元素
pop_front_aux(); //这里将进行缓冲区释放工作
} //只有当start.cur==start.last-1时才会被调用
template <class T,class Alloc,size_t BufSize>
void deque<T,Alloc,BufSize>::pop_front_aux(){
destory(start.cur); //将第一缓冲区的第一个元素析构
deallocate_node(start.first); //释放第一缓冲区
start.set_node(start.node+); //调整start的状态,使指向下一个缓冲区的第一个元素
start.cur=start.first;
}

clear()用来清除整个deque,需要注意的是deque的最初状态没有任何一个元素,保有一个缓冲区,因此,clear()完成之后回复初始状态,也一样要保留一个缓冲区。

clear()函数如下:

template <class T,class Alloc,size_t BufSize>
void deque<T,Alloc,BufSize>::clear(){
//以下针对头尾以外的每一个缓冲区
for(map_pointer node=start.node+;node<finish.node;++node){
//将缓冲区内的所有元素析构
destory(*node,*node+buff_size());
//释放缓冲区内存
data_allocator::deallocate(*node,buff_size());
}
if(start.node!=finish.node){ //至少有头尾两个缓冲区
destory(start.cur,start.last); //将头缓冲区的目前所有元素析构
destory(finish.first,finish.cur); //将尾缓冲区的目前所有元素析构
//以下释放尾缓冲区,注意,头缓冲区保留
data_allocator::deallocate(finish.first,buffer_size());
}
else //只有一个缓冲区
destory(start.cur,finish.cur); //将此唯一缓冲区内所有元素析构,并保留缓冲区
finish=start; //调整状态
}

erase()函数清除某一个元素:

//清除pos所指向的元素,pos为清除点
iterator erase(iterator pos){
iterator next=pos;
++next;
difference_type index=pos-start; //清除点之前的元素个数
if(index<(size()>>)){ //如果清除点之前的元素比较少
copy_backward(start,pos,next); //就移动清除点之前的元素
pop_front(); //移动完毕,清除最前一个元素
}
else{ //清除点之后的元素比较少
copy(next,finish,pos); //就移动清除点之后的元素
pop_back(); //移动完毕,清除最后一个元素
}
return start+index;
}

erase()函数用来清除(first,last)区间内所有元素:

template <class T,class Alloc,size_t BufSize>
deque<T,Alloc,BufSize>::iterator
void deque<T,Alloc,BufSize>::erase(iterator first,iterator last){
if(first==start&&last==finish){ //如果清除区间就是整个deque
clear(); //直接调用clear()函数
return finish;
}
else{
difference_type n=last-first; //清除区间的长度
difference_type elems_before=first-start; //清除区间前方的元素个数
if(elems_before<(size()-n)/){ //如果前方的元素比较少
copy_backward(start,first,last); //向后移动前方元素(覆盖清除区间)
iterator new_start=start+n; //标记deque的新起点
destory(start,new_start); //移动完毕,将冗余的元素析构
//以下将冗余的缓冲区释放
for(map_pointer cur=start.node;cur<new_start.node;++cur)
data_allocator::deallocate(*cur,buffer_size());
start=new_start; //设定deque的新起点
}
else{ //如果清除区间后方的元素比较少
copy(last,finish,first); //向前移动后方元素(覆盖清除区间)
iterator new_finish=finish-n; //标记deque的新尾点
destory(new_finish,finish); //移动完毕,将冗余的元素析构
//以下将冗余的缓冲区释放
for(map_pointer cur=new_finish.node+;cur<=finish.node;++cur)
data_allocator::deallocate(*cur,buffer_size());
finish=new_finish; //设定deque的新尾点
}
return start+elems_before;
}
}

deque提供了多个insert功能,这里描述最基础的insert方法,允许在某个点之前插入一个元素,并设定其值。

insert()函数如下:

//在position处插入一个元素,其值为x
iterator insert(iterator position,const value_type& x){
if(position.cur==start.cur){ //如果插入点是deque最前端
push_front(x); //调用push_front函数
return start;
}
else if(position.cur==finish.cur){ //如果插入点是deque最尾端
push_back(x); //调用push_back函数
iterator temp=finish;
--temp;
return temp;
}
else{
return insert_aux(position,x); //调用insert_aux函数
}
} template <class T,class Alloc,size_t BufSize>
deque<T,Alloc,BufSize>::iterator
void deque<T,Alloc,BufSize>::insert_aux(interator pos,const value_type& x){
difference_type index=pos-start; //插入点之前的元素个数
value_type x_copy=x;
if(index<size()/){ //如果插入点之前的元素个数比较少
push_front(front()); //在最前端口加入与第一元素同值的元素
iterator front1=start; //以下标示记号,然后进行元素移动
++front1;
iterator front2=front1;
++front2;
pos=start+index;
iterator pos1=pos;
++pos1;
copy(front2,pos1,front1); //元素移动
}
else{ //插入点之后的元素个数比较少
push_back(back()); //在最尾端加入与最后元素同值的元素
iterator back1=finish; //以下标示记号,然后进行元素移动
--back1;
iterator back2=back1;
--back2;
pso=start+index;
copy_backward(pos,back2,back1); //元素移动
}
*pos=x_copy; //在插入点上设定新值
return pos;
}

deque源码4(deque元素操作:pop_back、pop_front、clear、erase、insert)的更多相关文章

  1. deque源码3(deque的构造与内存、ctor、push_back、push_front)

    deque源码1(deque概述.deque中的控制器) deque源码2(deque迭代器.deque的数据结构) deque源码3(deque的构造与内存.ctor.push_back.push_ ...

  2. deque源码2(deque迭代器、deque的数据结构)

    deque源码1(deque概述.deque中的控制器) deque源码2(deque迭代器.deque的数据结构) deque源码3(deque的构造与内存.ctor.push_back.push_ ...

  3. deque源码1(deque概述、deque中的控制器)

    deque源码1(deque概述.deque中的控制器) deque源码2(deque迭代器.deque的数据结构) deque源码3(deque的构造与内存.ctor.push_back.push_ ...

  4. list源码3(参考STL源码--侯捷):push_front、push_back、erase、pop_front、pop_back、clear、remove、unique

    list源码1(参考STL源码--侯捷):list节点.迭代器.数据结构 list源码2(参考STL源码--侯捷):constructor.push_back.insert list源码3(参考STL ...

  5. 读 Zepto 源码之集合元素查找

    这篇依然是跟 dom 相关的方法,侧重点是跟集合元素查找相关的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zept ...

  6. HashMap源码调试——认识"put"操作

    前言:通常大家都知道HashMap的底层数据结构为数组加链表的形式,但其put操作具体是怎样执行的呢,本文通过调试HashMap的源码来阐述这一问题. 注:jdk版本:jdk1.7.0_51 1.pu ...

  7. jQuery 源码分析(十三) 数据操作模块 DOM属性 详解

    jQuery的属性操作模块总共有4个部分,本篇说一下第2个部分:DOM属性部分,用于修改DOM元素的属性的(属性和特性是不一样的,一般将property翻译为属性,attribute翻译为特性) DO ...

  8. 多目标遗传算法 ------ NSGA-II (部分源码解析) 交叉操作 crossover.c

    遗传算法中的交叉操作是 对NSGA-II  源码分析的  最后一部分, 这一部分也是我 从读该算法源代码和看该算法论文理解偏差最大的  函数模块. 这里,首先提一下,遗传算法的  交叉操作.变异操作都 ...

  9. elfinder源码浏览-Volume文件系统操作类(1)

    今天看了一个文件管理的java后台源码,elfinder 发现这个东东比我写的代码效率告到不知道哪去了,苦思冥想后还是抽点时间看看吧.. 它实现了我们电脑上的所以关于文件操作的动作,并生成了api开放 ...

随机推荐

  1. ----constructor 与 object----

    CONSTRUCTOR constructor是一种特殊的object,同样是用来创建和声明一个类 语法规则: constructor([arguments]) { ... } 注意: 1.在类中,只 ...

  2. squid 透明代理配置

    阿铭在教程中已经介绍过squid的安装和配置,http://study.lishiming.net/chapter22.html 教程中只介绍了初级的正向代理和反向代理,这篇文档将要介绍透明代理如何配 ...

  3. mac系统 pip3 install scrapy 失败 No local packages or working download links found for incremental>=16.10.1

    使用pip3 install scrapy命令之后,会出现如下问题: Collecting scrapy Downloading Scrapy-1.4.0-py2.py3-none-any.whl ( ...

  4. safari10.0以上版本出现默认小人头图标

    1.可能改input输入框外层有兄弟元素在input之前,将input元素位置放置在所有兄弟元素之前即可

  5. 使用EasyUI的Datagrid的Editor进行行编辑,Enter回车结束编辑,并开启新的一行。

    //新增数据function add() { if (Index == undefined) { row = { move_date: '', start_time: '', end_time: '' ...

  6. 学以致用三十二-----python中函数的括号使用

    一直以来对python中函数括号的使用,有点分不清楚,到底什么时候用括号,什么时候不用括号,造成了很大看困惑. 今天来总结下. class aaa(): y = 'you' def __init__( ...

  7. Book : <Hands-on ML with Sklearn & TF> pdf/epub

    非常好的书,最近发现了pdf版本,链接:http://www.finelybook.com/hands-on-machine-learning-with-scikit-learn-and-tensor ...

  8. MySQL数据库(三)索引总结

    一.什么是索引?  索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存. 如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录 ...

  9. redis操作(String,Hash,List,Set,其他操作)

    一.String操作 String操作,redis中的String在在内存中按照一个name对应一个value来存储.如图: set(name,value,ex=None,px=None,nx=Fal ...

  10. bzoj1038(半平面交)

    #include<iostream> #include<cstring> #include<cmath> #include<cstdio> #inclu ...