一覧へ

グラフ — 隣接行列 vs 隣接リスト

グラフをコードで表現する2つの方法(隣接行列、隣接リスト)の構造、長所と短所、選択基準を説明します。

中級
|
5
|
検証済み (2026-07)
進捗0/23 (0%)

グラフ — 隣接行列 vs 隣接リスト

このトピックを終えると

グラフとは何か、そして隣接行列と隣接リストという2つの表現方法の違いを理解できるようになります。


木はグラフの特殊なケースです

これまで見てきた配列、連結リスト、木 — これらのデータ構造は、データ間の関係が単純です。配列は順序、木は階層です。

しかし、現実の関係は複雑です。SNSでは人々は互いにフォローします。都市は道路でつながっています。ウェブページはリンクでつながっています。このような多対多の関係を表現するデータ構造がグラフです。

グラフは、ノード(または頂点)とノードを接続するエッジで構成されます。木もグラフの一種ですが、「親-子」制約と「サイクルがない」という条件を持つ特殊なグラフです。


有向グラフ vs 無向グラフ

無向グラフ: AとBが接続されている場合、A→B、B→Aの両方向に移動できます。Facebookの友達関係のように、私が友達であれば、相手も友達です。

有向グラフ: A→Bのみ可能で、B→Aはできない場合があります。Instagramのフォローのように、私がフォローしても、相手が私をフォローするとは限りません。


隣接行列:2次元配列

ノードが5個のグラフを5×5の行列で表現します。matrix[i][j] = 1の場合、ノードiからjへのエッジがあることを意味します。

text
A  B  C  D
A [ 0, 1, 1, 0 ]
B [ 1, 0, 0, 1 ]
C [ 1, 0, 0, 1 ]
D [ 0, 1, 1, 0 ]

A-B、A-C、B-D、C-Dが接続された無向グラフです。無向であるため、行列は対角線を基準に左右対称です。

python
graph = [
[0, 1, 1, 0],
[1, 0, 0, 1],
[1, 0, 0, 1],
[0, 1, 1, 0],
]
# AとBが接続されているか確認
if graph[0][1] == 1:
print("A-B 接続") # O(1)

長所: 2つのノードが接続されているかを確認するのが**O(1)**です。インデックスで直接アクセスします。

短所: ノードがN個の場合、N×Nサイズの配列が必要です。ノードが10,000個の場合、1億個のセルが必要です。エッジがあまりなくても、すべての空間を使用します。


隣接リスト:連結リスト

各ノードに対して、「このノードに接続されているノードのリスト」を保存します。

text
A: [B, C]
B: [A, D]
C: [A, D]
D: [B, C]

同じグラフですが、表現方法が異なります。

python
graph = {
'A': ['B', 'C'],
'B': ['A', 'D'],
'C': ['A', 'D'],
'D': ['B', 'C'],
}
# Aの隣接ノードを走査
for neighbor in graph['A']:
print(neighbor) # B, C

長所: エッジ数に比例したメモリのみを使用します。ノードが10,000個あっても、エッジが100個の場合、100個分の空間のみが必要です。

短所: 2つのノードが接続されているかを確認するには、リストを走査する必要があります。最悪の場合、**O(N)**です。


どちらを使うべきか

text
| 隣接行列          | 隣接リスト
---------+------------------+------------------
空間      | O(V^2)           | O(V + E)
接続確認  | O(1)             | O(degree)
隣接ノード走査 | O(V)             | O(degree)
適切な場合 | エッジが多い密なグラフ | エッジが少ない疎なグラフ

密なグラフ: ノードに対してエッジが多い。すべての都市間に直行便がある航空ネットワーク。隣接行列が適切です。

疎なグラフ: ノードに対してエッジが少ない。SNSで1億人のユーザーのうち、各ユーザーが平均200人しかフォローしていない。隣接リストが適切です。

ほとんどの実際のグラフは疎なグラフです。そのため、隣接リストが基本的な選択肢です。コーディングテストでも、最初に隣接リストを思いつくとよいでしょう。


重み付きグラフ

エッジに重みを付けることができます。都市間の距離、ネットワークの遅延時間などです。

隣接行列では、1の代わりに重み値を入れます。

python
# matrix[A][B] = 距離
matrix = [
[0, 5, 3, 0],
[5, 0, 0, 2],
...
]

隣接リストでは、タプルで表現します。

python
graph = {
'A': [('B', 5), ('C', 3)],
'B': [('A', 5), ('D', 2)],
...
}

重み付きグラフで最短経路を見つけるには、BFSの代わりにダイクストラアルゴリズムを使用します。BFSはエッジ数基準の最短、ダイクストラは重みの合計基準の最短です。


重要なポイント

グラフは、ノードとエッジで多対多の関係を表現するデータ構造です。 隣接行列は、接続確認がO(1)ですが、空間をO(V^2)使用します。 隣接リストは、空間をO(V+E)のみ使用し、ほとんどの実際のグラフで基本的な選択肢です。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...