SGISTL源码阅读十三 list容器下

SGISTL源码阅读十三 list容器下

前言

我们将继续介绍list的相关操作


深入源码
remove

remove的作用是删除指定值的节点

template <class T, class Alloc>
void list<T, Alloc>::remove(const T& value) {
  iterator first = begin();
  iterator last = end();
  //遍历list
  while (first != last) {
    iterator next = first;
    ++next;
    //如果当前节点的value为指定值,则删除它
    if (*first == value) erase(first);
    first = next;
  }
}
unique()

该函数的作用是删除值相同的连续的元素,直至该元素剩最后一个。

template <class T, class Alloc>
void list<T, Alloc>::unique() {
  iterator first = begin();
  iterator last = end();
  if (first == last) return;
  iterator next = first;
  while (++next != last) {
    /* 比较前后两个元素的值
     * 若相等,则进行删除
     * 否则移动first迭代器,跟进到next
     */
    if (*first == *next)
      erase(next);
    else
      first = next;
    /* 可能会因为erase删除操作使next失效
     * 所以需要更新next,保持与first指向相同元素
     */
    next = first;
  }
}
merge

函数的作用是将list x合并到该list上,合并的顺序是递增排序,并且要求合并前,两个list中的元素已经是递增的。调用了前面提到过的transfer函数

template <class T, class Alloc>
void list<T, Alloc>::merge(list<T, Alloc>& x) {
  iterator first1 = begin();
  iterator last1 = end();
  iterator first2 = x.begin();
  iterator last2 = x.end();
  //两个链表还没到结尾
  while (first1 != last1 && first2 != last2)
    /* 若*first2 < *first1
     * 则将first2指向的元素移动到first1指向的元素前面
     * 否则first1++,寻找下一个插入点
     */
    if (*first2 < *first1) {
      iterator next = first2;
      transfer(first1, first2, ++next);
      first2 = next;
    }
    else
      ++first1;
  /* 若first2 != last2
   * 证明x的元素还没全部被移动到list上
   * 将剩余的元素移动到last1前面
   */
  if (first2 != last2) transfer(last1, first2, last2);
}
reverse

故名思意,这个函数的作用是将链表倒置

template <class T, class Alloc>
void list<T, Alloc>::reverse() {
  //如果链表为空或者只有一个节点,则不用做任何操作
  if (node->next == node || link_type(node->next)->next == node) return;
  iterator first = begin();
  ++first;
  while (first != end()) {
    iterator old = first;
    ++first;
    //利用前插法倒置,begin位置不动,把依次后面的元素插入到begin前面去
    //插入结束后begin的位置是最后一个节点
    transfer(begin(), old, first);
  }
}
操作符重载
//重载=
template <class T, class Alloc>
list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
  if (this != &x) {
    iterator first1 = begin();
    iterator last1 = end();
    const_iterator first2 = x.begin();
    const_iterator last2 = x.end();
    //遍历并且依次赋值
    while (first1 != last1 && first2 != last2) *first1++ = *first2++;
    //如果list比listx元素多,那么删除list中多余元素
    if (first2 == last2)
      erase(first1, last1);
    //如果list中空间不够,则使用插入
    else
      insert(last1, first2, last2);
  }
  return *this;
}
//重载==
template <class T, class Alloc>
inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
  typedef typename list<T,Alloc>::link_type link_type;
  link_type e1 = x.node;
  link_type e2 = y.node;
  link_type n1 = (link_type) e1->next;
  link_type n2 = (link_type) e2->next;
  for ( ; n1 != e1 && n2 != e2 ; n1 = (link_type) n1->next, n2 = (link_type) n2->next)
    //如果value不同直接返回false 
    if (n1->data != n2->data)
      return false;
  //若最后长度相等,就返回true,否则返回false
  return n1 == e1 && n2 == e2;
}
//重载<
template <class T, class Alloc>
inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
  return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
总结

我们继续对list相关操作进行了分析。
list的学习就到此结束了,接下来将继续学习deque

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值