Instiq
第1章 · 基礎理論とアルゴリズム·v1.0.0·更新 2026/7/9·読了目安 約15分

変更要約: 初版

1.3データ構造

この節の要点

配列リストスタックキューの基礎操作の計算量、階層構造を表す木構造2分探索木平衡木ヒープ)、キーから直接位置を求めるハッシュ、そして頂点と辺で関係を表すグラフを、それぞれの計算量特性とセットで学びます。

FEでも学ぶ基本的なデータ構造ですが、APレベルでは「なぜその計算量になるのか」を構造から説明できることが求められます。木がなぜ平衡を保つ必要があるのか、ハッシュ衝突がなぜ性能を悪化させるのか——構造と計算量の因果関係を理解することが、次節のアルゴリズム設計の土台になります。

1.3.1配列・リスト・スタック・キュー

  • 配列=連続メモリに要素を並べ、添字でO(1)アクセスできる一方、途中挿入・削除は要素をずらすためO(n)リスト(連結リスト)は途中挿入・削除が参照の付け替えだけでO(1)だが、n番目要素へのアクセスは先頭からたどりO(n)
  • スタック(LIFO)・キュー(FIFO)はいずれも push/pop・enqueue/dequeueがO(1)の特殊化されたリスト。用途で選ぶ=コールスタックや括弧対応チェックはスタック、幅優先探索やジョブの順番待ちはキュー。

1.3.2木構造(2分探索木・平衡木・ヒープ)

  • 2分探索木(BST)=各ノードについて「左部分木の全要素 < 自身 < 右部分木の全要素」を満たす2分木。検索・挿入・削除は木の高さに比例し、平均O(log n)だが、挿入順が偏ると一直線の木(偏った木)になり最悪O(n)まで悪化する。
  • 平衡木(AVL木・赤黒木等)=挿入・削除のたびに木の高さの偏りを自動的に是正し、常にO(log n)を保証する2分探索木の改良版。最悪ケースでも性能が悪化しないことが実務での採用理由。
  • ヒープ=親が子より必ず大きい(または小さい)というヒープ条件を満たす完全2分木。最大値(または最小値)の取得が常にO(1)(根を見るだけ)で、挿入・削除は木の高さに比例しO(log n)。優先度付きキューの実装に使われる。
試験ポイント

「配列=アクセスO(1)・挿入O(n)」「リスト=アクセスO(n)・挿入O(1)」「BST=平均O(log n)だが偏ると最悪O(n)」「平衡木=常にO(log n)を保証」「ヒープ=最大/最小の取得がO(1)」の対比が最頻出です。「なぜその計算量になるか」を木の高さや連続メモリの構造から説明できるようにしておきましょう。

1.3.3ハッシュとグラフ

  • ハッシュ=キーをハッシュ関数で固定長の値(ハッシュ値)に変換し、それを配列の添字として使うことで平均O(1)での検索・挿入を実現する構造。異なるキーが同じハッシュ値になる衝突が発生すると、チェイン法(同じ位置に連結リストで複数格納)等で対処するが、衝突が多発すると性能はO(n)に近づく。
  • グラフ=頂点(ノード)と辺(エッジ)で要素間の関係を表す構造。SNSの友人関係、道路網、依存関係の管理など多対多の関係を表現するのに適し、木構造は「閉路がなく親が1つ」というグラフの特殊な形。

あるECサイトの商品検索機能で、100万件の商品を商品コード(キー)から即座に取得したいという要件があるとします。2分探索木を使う場合、平均でも log2(1,000,000) ≒ 20 回の比較が必要ですが、ハッシュテーブルを使えば衝突が少ない限り平均1回のアクセスで目的の商品にたどり着けます。ただしハッシュ関数の設計が悪く、多くの商品コードが同じハッシュ値に集中してしまうと、その場所に長い連結リストができてO(n)に近い性能まで悪化するため、ハッシュ関数の分散性が重要になります。一方、この商品の「関連商品」「同カテゴリの商品」といった多対多の関係を管理したい場合はグラフが適しています——商品を頂点、関連性を辺として表現すれば、「ある商品から2ステップ以内でたどれる関連商品」のような問い合わせを幅優先探索(キューを使う)で効率的に解けます。さらに、在庫が残りわずかな人気商品を常に最優先で処理したい(在庫確認バッチの優先度付け等)という要件にはヒープが適しており、根に最優先の商品が常に来るため、優先度付きキューとしてO(log n)で挿入しつつO(1)で最優先品を取得できます。このように、同じ「複数のデータを扱う」課題でも、アクセスパターン(キーからの直接検索か、関係性のたどりか、優先度順の取り出しか)によって最適なデータ構造は大きく異なります。

構造検索挿入特徴
配列O(1)(添字)O(n)連続メモリ
リストO(n)O(1)(位置既知時)参照でつながる
BST(平均)O(log n)O(log n)偏ると最悪O(n)
平衡木O(log n)保証O(log n)保証常に自動平衡
ハッシュ(平均)O(1)O(1)衝突多発でO(n)に劣化
ヒープ最大/最小O(1)O(log n)優先度付きキューに利用
注意

ひっかけ: 「2分探索木は常にO(log n)で検索できる」は誤りです——挿入順によっては偏った木(実質的に連結リスト)になり最悪O(n)まで悪化します。常にO(log n)を保証したいなら平衡木を使う必要があります。また「ハッシュテーブルは衝突が起きない限り必ず配列より速い」も誤り=ハッシュ関数の計算コストや衝突処理のオーバーヘッドを考慮する必要があり、要素数が極小なら配列の線形探索で十分な場合もあります。

配列/リスト/スタック/キュー・木/ヒープ・ハッシュ/グラフの図。
データを組み立てる形

1.3.4この節のまとめ

  • 配列=アクセス速いが挿入遅いリスト=挿入速いがアクセス遅いというトレードオフを理解する
  • BSTは平均O(log n)だが偏ると最悪O(n)、平衡木は常にO(log n)を保証、ヒープは最大/最小取得がO(1)
  • ハッシュは平均O(1)だが衝突が増えると劣化、グラフは多対多の関係を表現する

進捗の記録にはログインが必要です。

理解度チェック

(軽い確認用)

Q1. 2分探索木に関する記述として最も適切なものはどれか。

Q2. 常に最優先度のタスクをO(1)で取得しつつ、新規タスクの追加はO(log n)で行いたい。最も適したデータ構造はどれか。

Q3. 100万件の商品データをキーである商品コードから頻繁に検索する用途で、平均的な性能を最も重視する場合に適した構造はどれか。

理解度を確認第1章「基礎理論とアルゴリズム」の問題を解く