比vector,list的实现是一个双向链表,他不会造成空间的浪费,并且插入和删除操作的时间复杂度是常数
list有一个重要的性质:插入操作(insert)和接合操作(splice)不会造成原有(非被删除)的list迭代器失效,这个是vector不具备的性质
list的insert操作,插入完成后新节点位于迭代器的前方。
list的erase操作,删除之后返回删除之后的节点
在介绍list的splice操作之前,先介绍一下list的tranfer操作:
上图中说明了七行代码代表的七个个动作,transfer(iterator position, iterator first, iterator last)操作是将first 到 last之间的元素移动到position之前,需要提及的是这三个指针可以是在同一个list中,需要注意的是,position不能在begin和last之间
有了transfer操作之后,splice显得很容易了
原型:设list2调用了splice函数
void splice ( iterator position, list<T,Allocator>& x );将list x中的所有元素插入到调用该函数的list2的position处。List x会被清空。
{
if(!x.empty())
transfer(position, x.begin(), x.end())
}
void splice ( iterator position, list<T,Allocator>& x, iterator i );将x中指向i的位置处的元素插入到list2的position处。X会将i位置处的值删除。
{
iterator j = i;
++j;
if(position == i||position == j) return;
transfer(position,i,j);
}
void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last ); 将x中[first,last)位置处的元素插入到list2的position处。
{
if(first != last)
transfer(position, first, last);
}
这里有个问题没解决,参数中的list<T,,Allocator>&x 这个参数是拿来做什么的呢???????
下面我们来看一下merge(),reverse(),操作是怎么用transfer实现的
list1.merge(list2)条件是list1和list2都经过递增排序的
比较list1和list2的头的大小,如果list1小,那么向后移动,直到比list2大
将list2中第一个元素利用transfer操作并在list1中,list2的头向后移动继续比较
直到list2头尾相碰
reverse()
核心代码很简单,直接贴上来了
first = begin();
first ++;
while(first != end)
{
iterator old = first;
++first;
transfer(begin(), old,first)
}
下图是局的一个例子