C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++ STLのlist::splice()関数を徹底解説!構文・パラメータ・使用例まとめ

本記事では、C++ STLにおけるlist::splice()関数の仕組み、構文、そして具体的なコード例について詳しく解説します。

STLにおけるリスト(std::list)とは?

リストは、シーケンス内の任意の位置で定数時間O(1)での挿入・削除を実現できるデータ構造です。内部は双方向連結リストとして実装されており、非連続的なメモリ割り当てが可能です。

配列やvector、dequeと比べると、コンテナ内の任意の位置への要素の挿入・抽出・移動において優れたパフォーマンスを発揮します。その一方で、先頭や末尾以外の要素への直接アクセス(ランダムアクセス)は遅いという特徴があります。また、リストはforward_listとよく似ていますが、forward_listは単方向連結リストであり、前方方向にしか走査できない点が大きく異なります。

list::splice()とは?

list::splice()はC++ STLの組み込み関数で、<list>ヘッダーで宣言されています。この関数は、あるリストコンテナから別のリストコンテナへ、指定した位置に要素を移動(転送)するために使われます。

splice()の最大の特長は、要素を「コピー」するのではなく、連結リストのノードのポインタをつなぎ替えるだけで移動を行う点です。そのため、要素数に関わらず極めて高速に動作し、移動元リストからは該当要素が削除されるため、両方のリストのサイズが変化します。

構文

splice()には以下の3つのオーバーロードがあります。

list1.splice(position, list2);            // list2の全要素を転送
list1.splice(position, list2, i);         // iが指す1要素のみ転送
list1.splice(position, list2, first, last); // [first, last)の範囲を転送

パラメータ

  • position − 転送先リスト(list1)内の、要素を挿入したい位置を示すイテレータです。

  • list2 − 転送元となる別のリストです。list1と同じ型である必要があります。list1自身を指定することも可能です。

  • i − list2内の、転送したい単一要素の位置を指すイテレータです。この要素だけがlist1へ移動します。

  • first, last − 転送したい要素範囲の開始位置と終了位置を定義するイテレータのペアです。[first, last)の半開区間の要素がlist1へ移動されます。

戻り値

splice()関数は戻り値を返しません(void型)。要素は移動されるだけで、呼び出し後はlist2から該当要素が取り除かれ、list1の指定位置に挿入されます。

使用例1:リスト全体を転送する

#include <bits/stdc++.h>
using namespace std;

int main() {
    list<int> myList_1 = { 10, 20 };
    list<int> myList_2 = { 30, 40, 50 };

    // myList_2の全要素をmyList_1の先頭へ転送
    myList_1.splice(myList_1.begin(), myList_2);

    cout << "splice後のlist 1: ";
    for (auto x : myList_1)
        cout << x << " ";
    cout << "\nsplice後のlist 2のサイズ: " << myList_2.size();
    return 0;
}

上記コードを実行すると、次の出力が得られます。

splice後のlist 1: 30 40 50 10 20
splice後のlist 2のサイズ: 0

使用例2:単一の要素を転送する

#include <bits/stdc++.h>
using namespace std;

int main() {
    list<int> myList_1 = { 10, 20, 30, 40 };
    list<int> myList_2 = { 50, 60 };

    // myList_2の先頭要素(50)だけをmyList_1の末尾へ転送
    list<int>::iterator i = myList_2.begin();
    myList_1.splice(myList_1.end(), myList_2, i);

    cout << "splice操作後のリスト" << endl;
    for (auto temp : myList_1)
        cout << temp << " ";
    return 0;
}

上記コードを実行すると、次の出力が得られます。

splice操作後のリスト
10 20 30 40 50

このように、第3引数のイテレータiが指す1要素だけが転送され、myList_2には60が残ります。

使用例3:範囲を指定して転送する

#include <bits/stdc++.h>
using namespace std;

int main() {
    list<int> myList_1 = { 1, 2, 3 };
    list<int> myList_2 = { 4, 5, 6, 7 };

    // myList_2の2番目以降(5, 6, 7)をmyList_1の末尾へ転送
    auto first = next(myList_2.begin());
    auto last = myList_2.end();
    myList_1.splice(myList_1.end(), myList_2, first, last);

    for (auto x : myList_1)
        cout << x << " ";
    return 0;
}

上記コードを実行すると、次の出力が得られます。

1 2 3 5 6 7

まとめ

list::splice()は、連結リストの特性を活かして要素をコピーせずにO(1)で移動できる強力な関数です。大量のデータをリスト間で移動させたい場合に、vectorなどの再割り当てを伴う操作よりも大幅に効率的になります。「全要素」「1要素」「範囲指定」の3つのオーバーロードを使い分けて、柔軟にリスト操作を行いましょう。

  1. C++ STLのlist::reverse()関数の使い方と実例解説

    本記事では、C++におけるlist::reverse()関数の動作、構文、具体的な使用例について詳しく解説します。STLにおけるlistとはlistは、シーケンス内の任意の位置で定数時間O(1)での要素の挿入・削除を可能にするデータ構造です。listは双方向連結リストとして実装されており、メモリの非連続的な割り当てが可能です。配列、vector、dequeと比較すると、コンテナ内の任意の位置への要素の挿入・抽出・移動において優れたパフォーマンスを発揮します。一方で、要素への直接アクセス(ランダムアクセス)は遅いという特徴があります。listはforward_listと似ていますが、forwar

  2. C++STLのlist back()関数の使い方を解説

    C++のlist back()関数とは本記事では、C++におけるlist back()関数の動作について詳しく解説します。list::back()関数は、C++標準テンプレートライブラリ(STL)の一部であり、リストの最後(末尾)の要素を取得・表示するために使用されます。この関数を呼び出す前に、必ず<list>ヘッダーファイルをインクルードする必要がある点に注意してください。構文List_Name.back();パラメータこの関数は、いかなるパラメータも受け取りません。戻り値この関数は、リストの最後の要素の値を返します。なお、リストが空の場合の動作は未定義となるため、呼び出し前にリ