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. 学习java之路 简单日历查询代码

    /** * 31天的 1, 3, 5, 7, 8, 10 ,12 30天的 4, 6,9,11 28天(平年) 2 29天(闰年) 2 */ class Demo{ public static voi ...

  2. [入门]在Mac OS X下使用和配置Android Studio

    Android Studio可谓是安卓开发的XCode,流畅的速度+顺眼的UI足以秒杀Eclipse.在Mac OS X可以通过如下的途径获得Android Studio  最新版本的Android ...

  3. 在centos7上配置jenkins

    在Linux(centos7)环境下配置jenkins,并用github作为仓库. 配置jenkins https://blog.csdn.net/wangfei0904306/article/det ...

  4. SQL语句操作数据

    --切换数据库:手动切换和命令切换 use MySchool --向Student表中插入数据 --语法:INSERT [INTO] 表名 (列名) VALUES (值列表) --注意事项: --1. ...

  5. 问题:计算foldRight(1)(_-_) 与foldLeft(1)(_-_)值不一样

    List(1,2,3,4)问题:计算foldRight(1)(_-_) 与foldLeft(1)(_-_)值不一样首先看foldRight(1)(_-_)计算过程((( (1-1)-2)-3)-4) ...

  6. spring学习(二)---依赖注入

    spring第二个特性是依赖注入. 学习依赖注入,首先应该明白两个问题:1,谁依赖谁:2,谁注入,注入什么? 首先还是看代码: 还是这个bean: package testSpring.busines ...

  7. Django项目及应用的创建

    一.url解释 1url是全球资源定位符,网上的每个文件都有唯一的url地址,组成:协议.服务器名称(或IP地址).路径和文件名. 2有时候,URL以斜杠“/”结尾,而没有给出文件名,在这种情况下,U ...

  8. 【转】mysqldump与innobackupex知多少

    作者:罗小波 [目录] 1. 先看mysqldump 1.1 mysqldump备份过程解读 1.2 mysqldump备份过程中的关键步骤 1.2.1 FLUSH TABLES和FLUSH TABL ...

  9. android-读取MediaProvider

    1.MediaProvider存储手机中的媒体文件,用 SQLite 数据库存储图片.视频.音频等多媒体文件的信息,供视频播放器.音乐播放器.图库使用.以 root 权限进入 adb shell,使用 ...

  10. now