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. Linux任务计划命令 :crontab -e

    crond是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond ...

  2. 【Selenium】【BugList11】启动selenium server报错:Unsupported major.minor version 52.0

    [环境信息] python:3.6.5 平台:win7 selenium:3.11.0 selenium server:selenium-server-standalone-3.11.0.jar jd ...

  3. ConcurrentDictionary

    ConcurrentDictionary ConcurrentDictionary一大特点是线程安全,在没有ConcurrentDictionary前 在多线程下用Dictionary,不管读写都要加 ...

  4. 第八周助教工作总结——NWNU李泓毅

    1.助教博客链接: https://www.cnblogs.com/NWNU-LHY/ 2.作业要求博客链接: http://www.cnblogs.com/nwnu-daizh/p/10687492 ...

  5. affiliate的使用方式

    什么是affiliate https://www.zhihu.com/question/24262490 通俗的理解就是,我们寻找合作伙伴,让合作伙伴帮忙做宣传,我们会根据他们的宣传力度发放相关的奖励 ...

  6. PHP PDO预定义常量

    以下常量由本扩展模块定义,因此只有在本扩展的模块被编译到PHP中,或者在运行时被动态加载后才有效. 注意: PDO使用类常量自PHP 5.1.以前的版本使用的全局常量形式PDO_PARAM_BOOL中 ...

  7. 第二次OO总结

    作业5——多线程电梯 好像失忆了,竟然对这三部电梯很陌生,我尽量回忆一下当时挣扎的场景orz 整体思路和第二次电梯差不多,但是将调度器类套在了电梯类里 优点可能是没有无效,足矣!!!缺点emmmm要是 ...

  8. 效果监控js源码

    function _bxmPlatformFn(e, t) { var n, o, i = ""; try { i = localStorage.getItem("lis ...

  9. MySQL数据库(一)

    一:MySQL的简单介绍 MySQL属于关系型数据库,数据是以行和列的形式去存储(表),表中的每一行叫一条记录,表中的每一列叫一个字段,表和表之间的逻辑关联叫关系. 二:MySQL的基本操作 (一)M ...

  10. python random 模块

    http://blog.csdn.net/m0_38061927/article/details/75335069