c++ list splice用法详解

  • Post author:
  • Post category:其他




1.splice的几种用法

项目开发过程中,发现stl中的list有splice方法,而且splice方法还挺实用,可以很方便地对链表进行一些连接断开的操作。因此我们下面来详细总结并实测一下splice的几种用法。

list1.splice(iterator position, list2)
list1.splice(iterator position, list2, iterator i)
list1.splice(iterator position, list2, iterator first, iterator last)

splice有以上三种函数签名,其中

list1表示被拼接的列表,操作以后其结构会发生改变(如果有改变的话)

iterator position表示操作开始时list1的迭代器位置

list2为将其元素拼接到list1的列表。

iterator i是list2中要拼接的迭代器元素。

iterator first, iterator last则是list2中要拼接元素的第一个与最后一个。

下面我们通过几个实例来进行测试。



2.全部拼接

void run3() {
    list<int> l1 = { 1, 2, 3 }; 
    list<int> l2 = { 4, 5 }; 
    list<int> l3 = { 6, 7, 8 }; 
  
    // 将l2全部加入l1,插入的位置为l1的开头
    l1.splice(l1.begin(), l2); 
  
    cout << "list l1 after splice operation" << endl; 
    for (auto ele : l1) cout << ele << " "; 
    cout << endl;
    cout << "list l2 after splice operation" << endl; 
    cout << "l2.size is: " << l2.size() << endl;
  
    // 将l1全部加入l3的末尾 
    l3.splice(l3.end(), l1); 
  
    // at the end of l3 
    cout << "list l3 after splice operation" << endl; 
    for (auto ele : l3) cout << ele << " "; 
}

如果我们将上面的代码运行,最终将得到如下输出

list l1 after splice operation
4 5 1 2 3 
list l2 after splice operation
l2.size is: 0
list l3 after splice operation
6 7 8 4 5 1 2 3 
l1.splice(l1.begin(), l2);

这行代码,表示将l2全部拼接到l1,拼接的位置在l1的头位置。并且注意拼接完成以后,l2此时的size已经变为0。

同理当

l3.splice(l3.end(), l1);

这行代码执行以后,会将l1全部拼接到l3,拼接位置在l3的尾部。



3.拼接单个元素

void run4() {
    list<int> mylist = {1, 2, 3, 4, 5};
    list<int>::iterator needit;
    for(auto it=mylist.begin(); it!=mylist.end(); it++) {
        if (*it==3) needit = it;
    }
    mylist.splice(mylist.begin(), mylist, needit);
    for(int ele: mylist) {
        cout<<ele<<" ";
    }
}
mylist.splice(mylist.begin(), mylist, needit);

重点解释一下上面这行代码。注意此时list2的位置,我们传入的跟list1相同,也即意味着我们操作的是同一个列表。我们想要做的事情是将列表中的某一个元素,移动到列表表头的位置。所以最后代码的输出为:

3 1 2 4 5 

所以,用splice方法就可以达到我们上述的目的。这样的好处在于,简单不易出错,帮我们简化省略了链表中各种指针断链再重新链接的过程。



4.移动一段元素

上面解释的移动一个元素,如果我们想移动多个连续的一段元素,那么自然也可以采用类似的办法。

void run5() {
    list<int> mylist = {1, 2, 3, 4, 5, 6, 7};
    list<int>::iterator beginit, endit;
    for(auto it=mylist.begin(); it!=mylist.end(); it++) {
        if (*it==3) beginit = it;
        if (*it==5) endit = it;
    }
    mylist.splice(mylist.begin(), mylist, beginit, endit);
    for(int ele: mylist) {
        cout<<ele<<" ";
    }
}

具体原理跟上面类似,不再多做解释。最终代码输出为

3 4 1 2 5 6 7 

从上面的测试代码不难看出,最终的last元素,不包含在移动范围之内。



版权声明:本文为bitcarmanlee原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。