STL源码分析之deque有序容器 中

前言

前一节我们分析了deque的基本使用, 本节我们来分析一下deque的对map的操作, 即插入, 删除等. 但是本节只分析push, pop和删除操作, 而insert操作有点复杂还是放到下节来分析.

push, pop

因为deque的是能够双向操作, 所以其push和pop操作都类似于list都可以直接有对应的操作. 需要注意的是list是链表, 并不会涉及到界线的判断, 而deque是由数组来存储的, 就需要随时对界线进行判断.

push实现.

template <class T, class Alloc = alloc, size_t BufSiz = 0> 
class deque {
   
    ...
public:                         // push_* and pop_*
    // 对尾进行插入
    // 判断函数是否达到了数组尾部. 没有达到就直接进行插入
  void push_back(const value_type& t) {
   
    if (finish.cur != finish.last - 1) {
   
      construct(finish.cur, t);
      ++finish.cur;
    }
    else
      push_back_aux(t);
  }
    // 对头进行插入
    // 判断函数是否达到了数组头部. 没有达到就直接进行插入
  void push_front(const value_type& t) {
   
    if (start.cur != start.first) {
   
      construct(start.cur - 1, t);
      --start.cur;
    }
    else
      push_front_aux(t);
  }
    ...
};

如果判断数组越界, 就移动到另一个数组进行push操作.

注意 : push_back是先执行构造在移动node, 而push_front是先移动node在进行构造. 实现的差异主要是finish是指向最后一个元素的后一个地址而first指向的就只第一个元素的地址. 下面pop也是一样的.

// Called only if finish.cur == finish.last - 1.
// 到达了数组的尾部
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_back_aux(const value_type& t) {
   
  value_type t_copy = t;
  reserve_map_at_back();
  // 申请空间
  *(finish.node + 1) = allocate_node();
  __STL_TRY {
   
  	// 执行构造
    construct(finish.cur, t_copy);
    // 移动node, 指向下一个数组的头
    finish.set_node(finish.node + 1);
    finish.cur = finish.first;	// cur只指向当前数组的头
  }
  // 如果分配失败, 释放掉该内存
  __STL_UNWIND(deallocate_node(*(finish.node + 1)));
}

// Called only if start.cur == start.first.
template <class T, class Alloc, size_t BufSize>
void deque<T, Alloc, BufSize>::push_front_aux(const value_type& t) {
   
  value_type t_copy = t;
  reserve_map_at_front();
  // 申请空间
  *(start.node - 1) = allocate_node();
  __STL_TRY {
   
  	// 先要移动node, 让其指向上一个数组的尾部
    start.set_node(start.node - 1);
    // cur指向当前数组的尾部
    start.cur = start.last - 1;
    // 执行构造
    construct(start.cur, t_copy);
  }
#     ifdef __STL_USE_EXCEPTIONS
  catch(...) {
   
    start.set_node(start.node + 1);
    start.cur = start.first;
    deallocate_node(*(start.node - 1));
    throw;
  }
#     endif /* __STL_USE_EXCEPTIONS */
} 

pop实现.

template <class T, class Alloc = alloc, size_t BufSiz = 0> 
class deque {
   
    ...
public: 
    // 对尾部进行操作
    // 判断是否达到数组的头部. 没有到达就直接释放
    void pop_back() {
   
    if (finish.cur != finish.first) {
   
      --finish
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值