「フレームワークが全部やってくれる時代に、なぜアルゴリズムを学ぶのか?」
初学者の皆さんが一度は抱く疑問でしょう。
確かに、現代の便利なライブラリを使えば、内部の仕組みを知らなくても動くアプリケーションは作れます。しかし、データ量が100件から10万件に増えてもそのアプリケーションは安定的に動きますか?
「動けばいい」から「正しく、速く動く」へ。 本記事では、初学者エンジニアが実務で「やらかさない」ために最低限知っておくべきアルゴリズムの基礎を、概論として解説します。
本記事で紹介している内容は以下のサイトから視覚的に確認することが可能です。
https://shihiro.com/tools/algorithm-visualizer
1. 全ての共通言語「計算量(オーダー記法)」
アルゴリズムを語る上で避けて通れないのが計算量。
エンジニアの会話で「その処理、オーダーどれくらい?」と聞かれて「牛丼並盛くらいです」と答えないための必須知識です。
計算量は主に時間計算量(実行時間)と空間計算量(メモリ消費)に分かれますが、まずは時間を表す「Big O(ビッグ・オー)記法」を覚えましょう。
- $O(1)$: データ量に関わらず一瞬で終わる。理想郷。
- $O(\log N)$: データが増えても計算時間があまり増えない。非常に優秀。
- $O(N)$: データ量に比例して時間が増える。一般的なfor文1回。
- $O(N^2)$: for文の中にfor文を書く(二重ループ)。データが1万件になると、1億回の計算が発生する。
- $O(2^N)$ や $O(N!)$: 宇宙が終焉を迎えるまで計算が終わらない可能性がある。絶対に書いてはいけない。
「PCの性能が上がっているから$O(N^2)$でも大丈夫だろう」と甘く見てはいけません。
クラウドインフラはあなたの非効率なコードを高速に処理してくれますが、月末に届くAWSの請求書はあなたの口座を確実に破壊します。
2. これだけは押さえたい!必須アルゴリズム4選
実務に直結する基礎的なアルゴリズムを4つ厳選しました。
① 探索(サーチ):欲しいものをどう見つけるか
データの中から特定の目的物を見つけるアルゴリズムです。
- 線形探索(Linear Search): 先頭から順番に1つずつ探す。計算量は $O(N)$。
- 二分探索(Binary Search): あらかじめソートされた(並べ替えられた)データに対し、真ん中の値を見て「右か左か」を半分に絞り込んでいく。計算量は $O(\log N)$。
辞書で「プログラミング」という単語を引くとき、1ページ目から順番に読む人はいないでしょう(それは線形探索です)。大体の当たりをつけて真ん中から開き、前か後ろかを探っていくのが二分探索の考え方です。
② ソート(並べ替え):データをどう整理するか
データを昇順や降順に並べ替えるアルゴリズムです。実務では Array.prototype.sort() のような組み込み関数を使うことがほとんどですが、内部の仕組みを知っておくことは重要です。
- バブルソート: 隣り合う要素を比較して入れ替えていく。実装は簡単だが $O(N^2)$ と遅い。教育用途では有用ですが、実務で使われることはほぼありません。
- クイックソート / マージソート: データを分割しながら効率よく並べ替える。現代の言語の多くが内部的に採用しており、計算量は平均して $O(N \log N)$。
③ ハッシュテーブル(連想配列):魔法の箱
アルゴリズムというよりデータ構造ですが、最も実務で活用する知識です。
キーと値をペアで保存し、キーから値を検索する際の計算量は平均的には $O(1)$ になります。
配列の中で id: 105 のユーザーを探すのに find() を使って $O(N)$ かけるよりも、ユーザーIDをキーとしたハッシュテーブル(Mapやオブジェクト)を作っておけば高速に取り出せます。
ただし注意点として、ハッシュテーブルは常に $O(1)$ ではありません。
ハッシュの衝突(collision)が多発すると、内部的に探索が発生し最悪の場合は $O(N)$ まで劣化します。
とはいえ、通常の実装ではほぼ $O(1)$ として扱って問題ありません。
「二重ループで遅いなら、片方をハッシュにしてループを一つ消せ」。これはテストに出ます。
実務のコードレビューで必ず指摘されます。
④ 再帰(Recursion):マトリョーシカの構造
関数の中で自分自身を呼び出す手法です。階層の深さがわからないツリー構造(ディレクトリ構造やDOMツリーなど)を探索する際によく使われます。
「再帰を理解するには、まず再帰を理解しなければならない」。プログラマが好む古典的なジョークです。なお、終了条件を書き忘れると無限ループに陥り「スタックオーバーフロー」という、どこかで聞いたことのある名前のエラーを出してプログラムが死にます。
(補足)指数オーダーは本当に悪なのか?
ここまでの話を聞くと、$O(2^N)$ や $O(N!)$ のようなアルゴリズムは”絶対悪"に思えるかもしれません。
しかし実際には、
- 全ての組み合わせを調べる必要がある
- 最適解を保証したい
- 入力サイズが小さい(例:N ≤ 20)
といったケースでは、あえて指数オーダーのアルゴリズムを使うのが正解になることもあります。
大切なのは「使うな」ではなく「どんな条件なら使っていいか」を理解することです。
3. なぜ"実務"でアルゴリズムが必要なのか
「でも、フロントエンドでReactを書くだけなら要らなくないですか?」
そんな声が聞こえてきそうです。しかし、アルゴリズム的思考は日常業務の至る所に潜んでいます。
- APIのレスポンス処理: バックエンドから返ってきた1万件の配列同士を結合する処理。二重ループ($O(N^2)$)で書くとブラウザが固まりますが、ハッシュマップを使えば $O(N)$ に落とせます。
- データベース設計: インデックス(Index)を張るとなぜ検索が速くなるのか?それは内部で「B-Tree」などの木構造アルゴリズムが使われ、$O(N)$ の全件走査から $O(\log N)$ の探索に変わるからです。
-
コンポーネントの再描画: 仮想DOMの差分検知(Diffアルゴリズム)の仕組みを少しでも知っていれば、「なぜ
keyプロパティを正しく設定しなければならないか」が論理的に理解できます。
アルゴリズムとは、単なるパズルや競技プログラミングのためのものではありません。
コンピュータの気持ちになって、限られたリソースを最適に使うための作法なのです。
おわりに
いかがでしたでしょうか。アルゴリズムの世界は奥深く、動的計画法(DP)やダイクストラ法、グラフ理論など、まだまだ面白い概念がたくさん待ち受けています。
最初から全てを完璧に理解する必要はありません。しかし、「このコードを書いたら、データが100倍になった時にどうなるだろうか?」という視点を持つだけで、あなたの書くコードの品質は劇的に向上します。
技術のトレンドは数年で移り変わりますが、計算機科学の基礎であるアルゴリズムは数十年経っても裏切りません。ドキュメントのないレガシーコードはあなたを裏切るかもしれませんが、アルゴリズムは決してあなたを裏切らないのです。
この記事が、皆さんのエンジニアリングライフの一助となれば幸いです。