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


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-1); //調整finish的狀態,使指向上一個緩沖區的最后一個元素
    finish.cur=finish.last-1; destory(finish.cur); //將該元素析構
}

pop_front()函數如下:

void pop_front(){ if(start.cur!=start.last-1){ //第一緩沖區至少有一個元素
        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+1); //調整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+1;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()>>1)){ //如果清除點之前的元素比較少
        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)/2){ //如果前方的元素比較少
            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+1;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()/2){ //如果插入點之前的元素個數比較少
        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; }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM