17 連結リスト

1. 連結リストとは

連結リスト(linked list)とは、各要素が「次の要素への参照(リンク)」を持つことで、データを順番に並べるデータ構造です。 配列と違って、メモリ上の連続した場所に並んでいる必要はありません。

head 10 next 20 next 30 next 40 null
headはリストの先頭を指す変数。各ノードのnextは次のノードを指す参照。最後のノードの next は null

2. ノードの構造

節点型: Node
    値型:  value      // この節点が持つデータ
    Node型: next      // 次の節点への参照(最後なら null)
endtype

3. 配列との比較

操作配列連結リスト
i 番目のアクセス(添字)O(1)O(n)
先頭への挿入O(n)O(1)
末尾への挿入O(1) ※O(n) ※
中間への挿入O(n)O(1) ※ノードを把握済みなら
削除(ノード把握済み)O(n)O(1)
メモリの使い方連続分散
使い分け:
・要素数があまり変わらず、ランダムアクセスが多い → 配列が有利
・要素の挿入・削除が頻繁 → 連結リストが有利

4. 連結リストの基本操作

① 末尾への追加

head 10 20 30 null ↑旧 50 null 新ノード追加 30 の next を 50 に更新
○ append(Node型: head, 値型: v)
    Node型: newNode ← 新しいノード(value=v, next=null)
    if ( head が null と等しい )
        head ← newNode
        return head
    endif
    Node型: cur ← head
    while ( cur.next が null と等しくない )
        cur ← cur.next
    endwhile
    cur.next ← newNode
    return head

末尾まで n 個たどるため O(n)

② 中間ノードの挿入

A B C X(新) A の next を X へ書き換え
// A と B の間に新ノード X を挿入
newNode.next ← A.next   // 新ノードを B に接続
A.next ← newNode        // A を新ノードに接続

A を把握しているなら、ポインタの付け替えだけで O(1)

③ ノードの削除

// A の次のノード B を削除
A.next ← A.next.next   // A の next を B の次(C)に直接つなぐ

「飛ばす」ことで削除完了。これも O(1)


5. 連結リストの探索

○ 論理型: search(Node型: head, 値型: target)
    Node型: cur ← head
    while ( cur が null と等しくない )
        if ( cur.value が target と等しい )
            return true
        endif
        cur ← cur.next
    endwhile
    return false

先頭から1つずつ確認するため O(n)

開始 cur ← head cur が null? True return false False value= target? True return true False cur ← cur.next

6. 双方向連結リストと循環連結リスト

双方向連結リスト(双連結リスト)

各ノードが next だけでなく prev(前のノード)も持つ。前後どちらにも進める。

A B C next prev next prev

循環連結リスト

最後のノードの next が null ではなく、先頭ノードを指す。リング状になる。


7. 理解度チェック問題

問題17-1

連結リストの先頭から3番目の要素にアクセスする計算量はどれですか。

解説を表示 正解:イ
連結リストは添字アクセスができず、必ず先頭から next をたどっていく必要があります。n 番目までたどる場合は最悪 n 回なので O(n)。

問題17-2

連結リストの「途中のノードA」の直後に、新しいノードを挿入する計算量はどれですか(A は既に把握済み)。

解説を表示 正解:ア
A.next の参照を 2 回書き換えるだけ。データの移動や再配置が一切不要なので O(1)。
これが配列より優れている点です(配列だと後ろの要素を全部ずらす必要があり O(n))。

問題17-3

連結リストと配列の特徴の組合せとして、最も適切なのはどれですか。

解説を表示 正解:ウ
配列:添字でランダムアクセス O(1)、挿入・削除は O(n)。
連結リスト:アクセスは O(n)、挿入・削除は(ノード把握済みなら)O(1)。

問題17-4

次のようなノードのつながりがあります。X を削除するために必要な操作はどれですか。

head → A → X → B → null
解説を表示 正解:イ
A の next を X の次(B)に直接つなぎ替えることで、X が連結から外れます。

問題17-5

双方向連結リストが単方向リストに比べて優れている点はどれですか。

解説を表示 正解:ア
双方向リストは prev 参照があるため、前のノードにもたどれます。
ただし参照を1つ余分に持つためメモリ使用量は逆に増えます(イ・ウ・エは誤り)。