【JavaScript】二分探索(バイナリサーチ)の実装方法:検索値が存在すればインデックスを返す
本記事では、ソート済みの数値配列を第1引数、検索したい数値を第2引数として受け取るJavaScript関数の実装方法を解説します。
検索対象の数値が配列内に存在する場合はそのインデックスを返し、存在しない場合は -1 を返します。この処理は二分探索(バイナリサーチ)アルゴリズムを用いて実装します。
二分探索とは?
二分探索は、典型的な分割統治法(Divide and Conquer)に分類されるアルゴリズムです。配列を半分ずつ再帰的(または反復的)に分割していき、探索範囲を絞り込みながら目的の要素へ収束させていきます。
なお、二分探索を行うには配列が事前にソートされている必要があります。ソート済みであることで、「中央の値と比較した結果から、次に探索すべきは左半分か右半分か」を簡単に判断できるためです。
実装コード
const arr = [-3, -1, 4, 7, 9, 11, 14, 22, 26, 28, 36, 45, 67, 78, 88, 99];
const binarySearch = (arr = [], num) => {
let l = 0;
let r = arr.length - 1;
while (l <= r) {
const mid = Math.floor((l + r) / 2);
if (num === arr[mid]) {
// 中央の値が検索値と一致 → インデックスを返す
return mid;
} else if (num < arr[mid]) {
// 検索値が中央より小さい → 右端を左側へ移動
r = mid - 1;
} else {
// 検索値が中央より大きい → 左端を右側へ移動
l = mid + 1;
}
}
// 見つからなかった場合
return -1;
};
console.log(binarySearch(arr, 22));
console.log(binarySearch(arr, 56));
console.log(binarySearch(arr, 11));コードのポイント
- ポインタ変数
lとr:それぞれ探索範囲の左端と右端のインデックスを表します。 - 中央インデックスの計算:
Math.floor((l + r) / 2)で中央位置を求めます。 - 比較による範囲の絞り込み:検索値が中央の値より小さければ右端を
mid - 1に、大きければ左端をmid + 1に更新し、探索範囲を半分に縮小します。 - ループ終了条件:
l > rになった時点で探索範囲が消滅したことを意味するため、-1を返して「見つからなかった」ことを示します。
実行結果
コンソールへの出力は以下のようになります。
7 -1 5
22 はインデックス7に存在するため 7、56 は配列内に存在しないため -1、11 はインデックス5に存在するため 5 がそれぞれ出力されます。
計算量について
二分探索の時間計算量は O(log n) です。線形探索(O(n))と比べ、要素数が多い配列ほど圧倒的に高速に動作します。例えば、10億件のデータでも最大約30回の比較で検索が完了するため、大量データの検索において非常に有効な手法です。
-
JavaScriptでドキュメント内の画像の数を取得する方法
Webページ(ドキュメント)に含まれる画像の数を取得したい場合、JavaScriptのimagesプロパティを利用するのが最も簡単な方法です。document.imagesは、ドキュメント内のすべての<img>要素を格納したコレクション(HTMLCollection)を返します。このコレクションに対して.lengthを使用することで、画像の総数を数値として取得できます。基本的な使い方以下のように記述するだけで、ドキュメント内の画像の数を取得できます。var val = document.images.length;サンプルコード実際に動作を確認できる完全なサンプルコードがこちらです
-
JavaScriptで線形探索(リニアサーチ)を実装する方法
線形探索(リニアサーチ)とは線形探索は、配列の先頭から順に要素を一つずつ調べ、目的の値と一致する要素を見つけ出す最も基本的な検索アルゴリズムです。事前にデータをソートしておく必要がなく、実装も非常にシンプルなため、小規模なデータ検索やプログラミング学習の入門としてよく利用されます。以下は、JavaScriptで線形探索を実装したサンプルコードです。サンプルコード<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta