コンテンツにスキップ

C++/標準ライブラリ/list

出典: フリー教科書『ウィキブックス(Wikibooks)』

標準ライブラリ::ヘッダー <list>

[編集]

概要

[編集]

std::list は、要素の順序を保持するコンテナです。他のコンテナとは異なり、std::list は双方向イテレータをサポートし、要素の挿入と削除が効率的に行えます。

std::list の主な機能と利点は以下の通りです。

要素の順序を保持する
要素の挿入順序を保持するため、履歴データの管理などに適しています。
双方向イテレータをサポートする
要素を前方向だけでなく、後方向からも反復処理できます。
挿入と削除が効率的
要素の挿入と削除は、リストの先頭または末尾で行うため、O(1) の計算時間で実行できます。

std::list は、以下の用途に適しています。

  • 履歴データの管理
  • 連結リストの実装
  • キューやスタックの実装

要素型

[編集]

std::list コンテナに格納できる要素の型は、以下の通りです。

  • 値型
  • 参照型

値型は、要素の値を直接格納します。参照型は、要素のメモリ位置を格納します。

カスタム型の要素を格納する場合は、以下の点に注意する必要があります。

  • コピーコンストラクタと代入演算子を実装する必要があります。
  • デストラクタを実装する必要がある場合は、std::list コンテナから要素が削除されたときに適切に呼び出されるようにする必要があります。

イテレータ

[編集]

std::list コンテナを反復処理するには、イテレータを使用します。std::list コンテナで使用できるイテレータの種類は以下の通りです。

bidirectional iterator
前方向と後方向の両方に移動できるイテレータ
forward iterator
前方向にのみ移動できるイテレータ

イテレータの操作方法は以下の通りです。

begin()
リストの先頭のイテレータを取得
end()
リストの終端のイテレータを取得
++
イテレータを次の要素に移動
--
イテレータを前の要素に移動
*
イテレータが指している要素を取得

イテレータの比較演算子は以下の通りです。

==
イテレータが同じ要素を指しているかどうかを比較
!=
イテレータが異なる要素を指しているかどうかを比較
<
イテレータが左側の要素を指しているかどうかを比較
<=
イテレータが左側の要素を指しているか、または同じ要素を指しているかどうかを比較
>
イテレータが右側の要素を指しているかどうかを比較
>=
イテレータが右側の要素を指しているか、または同じ要素を指しているかどうかを比較

コンストラクタ

[編集]

std::list コンテナには、以下のコンストラクタが用意されています。

デフォルトコンストラクタ
空のリストを作成
コピーコンストラクタ
既存のリストのコピーを作成
ムーブコンストラクタ
既存のリストの所有権を移動
範囲コンストラクタ
範囲内の要素を使用してリストを作成
初期化リストコンストラクタ
初期化リストを使用してリストを作成

代入演算子

[編集]

std::list コンテナには、代入演算子 (=) が用意されています。代入演算子を使用すると、既存のリストに別のリストの内容をコピーできます。

代入演算子には、以下の2 種類があります。

コピー代入
既存のリストに別のリストの内容をコピー
ムーブ代入
既存のリストに別のリストの所有権を移動

メンバ関数

[編集]

std::list コンテナには、以下のメンバ関数が用意されています。

要素の挿入と削除
push_front()
リストの先頭に要素を挿入
push_back()
リストの末尾に要素を挿入
pop_front()
リストの先頭の要素を削除
pop_back()
リストの末尾の要素を削除
insert()
指定された位置に要素を挿入
erase()
指定された要素または範囲を削除
要素の検索と取得
find()
リスト内で指定された要素を検索
find_if()
リスト内で条件を満たす要素を検索
front()
リストの先頭の要素を取得
back()
リストの末尾
リストのサイズ取得
size()
リスト内の要素数を取得
リストの空判定
empty()
リストが空かどうかを判定
リストのクリア
clear()
リスト内のすべての要素を削除

アルゴリズム

[編集]

std::list コンテナには、以下の標準アルゴリズムが適用できます。

検索アルゴリズム
find
リスト内で指定された要素を検索
find_if
リスト内で条件を満たす要素を検索
count
リスト内で指定された要素が出現する回数をカウント
count_if
リスト内で条件を満たす要素が出現する回数をカウント
ソートアルゴリズム
sort
リスト内の要素をソート
stable_sort
リスト内の要素をソート (元の順序をできるだけ保持)
その他のアルゴリズム
copy
リストの内容を別のリストにコピー
copy_if
リストの内容を別のリストにコピー (条件を満たす要素のみコピー)
swap
2 つのリストの内容を入れ替える
remove
リストから指定された要素を削除
remove_if
リストから条件を満たす要素を削除

[編集]
#include <iostream>
#include <list>

auto main() -> int {
    // デフォルトコンストラクタを使用して空のリストを作成
    std::list<int> list1;

    // コピーコンストラクタを使用してリストのコピーを作成
    std::list<int> list2(list1);

    // 範囲コンストラクタを使用してリストを作成
    std::list<int> list3{1, 2, 3, 4, 5};

    // 初期化リストコンストラクタを使用してリストを作成
    std::list<int> list4 = {6, 7, 8, 9, 10};

    // C++17で導入された推論ガイドを使用してリストを作成
    auto list5 = std::list{6, 7, 8, 9, 10};

    for (const auto &elem : list1) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // リストに要素を挿入
    list1.push_front(0);
    list1.push_back(11);

    for (const auto &elem : list1) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    for (const auto &elem : list3) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // リストから要素を削除
    list3.pop_front();
    list3.pop_back();
    for (const auto &elem : list3) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // リスト内の要素を検索
    auto it = std::find(list3.begin(), list3.end(), 3);
    if (it != list3.end()) {
        std::cout << "要素 3 はリスト内に存在します" << std::endl;
    } else {
        std::cout << "要素 3 はリスト内に存在しません" << std::endl;
    }

    // リストの内容を別のリストにコピー
    std::list<int> list6;
    std::copy(list4.begin(), list4.end(), std::back_inserter(list6));

    // リストの内容を標準出力に出力
    for (const auto &elem : list5) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

まとめ

[編集]

std::list コンテナは、要素の順序を保持する必要のある場合に適したコンテナです。双方向イテレータをサポートし、要素の挿入と削除が効率的に行えるため、履歴データの管理や連結リストの実装など、さまざまな用途に利用できます。