【C++学習|初心者向け】C++初心者必見!std::listで学ぶ「連結リスト」の基礎と使い分け

1. 導入:なぜstd::listが必要なのか?

C++の標準ライブラリ(STL)には、データを保持する「コンテナ」がたくさん用意されています。よく使われるのは std::vector ですが、実は「途中の要素を頻繁に削除・追加する」処理には向いていません。そこで登場するのが std::list です。std::listを使うことで、データの挿入や削除というコストの高い処理を、場所に関わらず瞬時に終わらせることができるようになります。

2. 基礎知識:連結リスト(Linked List)とは?

std::listは「双方向リンクリスト」という仕組みでできています。これは、各データが前後のデータの「場所(アドレス)」を指し示すメモを持っている構造です。
std::vector:本棚のようにデータが隙間なく並んでいる。途中に本を入れるには、後ろの本をすべてずらす必要がある。
std::list:数珠つなぎのようにデータがつながっている。途中の紐をほどいて新しいデータを繋ぐだけでいいので、ずらす必要がない。

この仕組みのおかげで、リストのどこであっても、要素の追加・削除が一定の時間(計算量 O(1))で完了します。

3. 実装/解決策:std::listを使いこなす

std::listを扱うには、ヘッダーファイル をインクルードします。要素の追加には push_back(末尾)や push_front(先頭)を使い、途中に挿入したい場合は「イテレータ(指し示す位置)」を指定して insert を使います。

4. サンプルプログラム

以下のコードをコピーして、実際に動かしてみてください。

include <iostream>
include <list>

int main() {
    // リストの初期化
    std::list<int> numbers = {10, 20, 30};

    // 末尾に追加
    numbers.push_back(40);
    // 先頭に追加
    numbers.push_front(5);

    // リストの途中に要素を挿入する
    // begin()は先頭を指すイテレータ。+1して2番目の位置へ移動
    auto it = numbers.begin();
    std::advance(it, 1); 
    numbers.insert(it, 15); // 5と10の間に15を挿入

    // 範囲ベースforループで表示
    for (int n : numbers) {
        std::cout << n << " ";
    }
    std::cout << std::endl;

    return 0;
}

5. 応用・注意点:使い分けが重要!

std::listは強力ですが、万能ではありません。注意すべきポイントは以下の2点です。

1. ランダムアクセスができない
std::vectorのように「3番目のデータ」をすぐに見ることはできません。リストの先頭から順番に辿る必要があるため、要素の検索には時間がかかります。
2. メモリ効率
各データに対して「前後の場所を指すポインタ」という管理用のメモリが必要なため、std::vectorよりもメモリ使用量が多くなりがちです。

結論
・順番にアクセスする、あるいは途中の追加・削除が多いなら std::list
・特定の番号へのアクセスが多い、あるいはメモリを節約したいなら std::vector
というように、用途に合わせて選ぶのがC++エンジニアの第一歩です!

コメント

タイトルとURLをコピーしました