《STL源码剖析》---list容器transfer操作个人理解

        transfer:list容器内部提供的迁移动作:将某连续范围的元素迁移到某个特定位置之前。

        首先上list容器transfer操作的源码:

void transfer(iterator position,iterator first,iterator last)//将[first,last)之间的元素迁移到position之前
{
     if (position != last)
     {
          (*(link_type((*last.node).prev))).next = position.node;
          (*(link_type((*first.node).prev))).next = last.node;
          (*(link_type((*position.node).prev))).next = first.node;
          link_type tmp = link_type((*position.node).prev);
          (*position.node).prev = (*last.node).prev;
          (*last.node).prev = (*first.node).prev;
          (*first.node).prev = tmp;
     }
}
        这里主要的核心思想就是更正前后链接。具体如下:

     将[first,last)元素迁移到position之前,建立first、last与position位置节点的链接关系:

1、

(*(link_type((*last.node).prev))).next = position.node;
    这一步操作:因为[first,last)迁移至position之前,且是前闭后开区间。即position的前一个节点是last的前一个。所以第一步操作就是建立position与其前一个节点的链接关系:
1)(link_type((*last.node).prev))
        1)这一步找到last位置的节点的前一个节点,这个节点的.next指向position位置的节点:
(*(link_type((*last.node).prev))).next = position.node;

2、
(*(link_type((*first.node).prev))).next = last.node;
       因为区间是前闭后开,现在将这个区间迁移至position位置之前了,那么原有的链接关系就需要修正。first位置的节点至last位置的节点(不包含last位置这个节点)迁移走了,因此原有的first的前一个节点需要与last位置的节点建立链接关系:
2)(link_type((*first.node).prev))
       2)这一步找到first的前一个节点,这个节点的.next由原先的指向first位置的节点改变为指向last位置的节点:
(*(link_type((*first.node).prev))).next = last.node;

3、
(*(link_type((*position.node).prev))).next = first.node;
       区间迁移至了position之前,所以需要改变positon之前的那个节点的链接关系。原先指向position位置的节点,现在需要指向first节点。首先得到position位置的前面那个节点:
3)(link_type((*position.node).prev))
       3)得到这个节点之后,将其.next指向first位置的节点:
(*(link_type((*position.node).prev))).next = first.node;

      到这一步为止,初步建立了单向的链接关系:first的前一个节点指向了first,position位置的节点指向了其前一个,last位置前一个节点指向了last位置的节点。现在开始建立双向关系:


link_type tmp = link_type((*position.node).prev);//生成一个temp节点,因为position位置的前一个节点需要修正了
(*position.node).prev = (*last.node).prev;
(*last.node).prev = (*first.node).prev;

(*first.node).prev = tmp;


4、position位置前后节点的双向链接:
4)(*position.node).prev = (*last.node).prev;
      因为已经建立了其前一个节点指向position位置的节点,所以这一步修正实现position位置节点指向的前一个节点为last.node位置的前一个节点;

5、last位置前后节点的双向链接:
5)(*last.node).prev = (*first.node).prev;
同第四步操作;

6、first位置前后节点的双向链接:
6)(*first.node).prev = tmp;
        first位置的指向的前一个节点修正为原position位置的前一个节点。


        至此个人对transfer操作的理解记录至此。其中的核心思想就是指向关系的修正。



原文地址:https://www.cnblogs.com/zhong-dev/p/4044582.html