c++ list splice用法详解

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元素,不包含在移动范围之内。

  • 10
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值