JavaScriptによる2分探索(バイナリサーチ) のサンプルコード

JavaScriptによる2分探索(バイナリサーチ) のサンプルコード

2020-05-245 min read

目次

  1. 概要
  2. 2分探索について
  3. ソース
  4. 参考

概要

JavaScriptで2分探索(バイナリサーチ)を実装してみました。

2分探索について

探索する範囲を半分に絞る→次の探索でさらに半分に絞る...という具合に探索する方法です。

前提として探索する配列などのデータがソートされている必要があります。

また、wikipediaではこのように説明されています。

ソート済みのリストや配列に入ったデータ(同一の値はないものとする)に対する検索を行うにあたって、 中央の値を見て、検索したい値との大小関係を用いて、検索したい値が中央の値の右にあるか、左にあるかを判断して、片側には存在しないことを確かめながら検索していく。

大小関係を用いるため、未ソートのリストや大小関係の定義されない要素を含むリストには二分探索を用いることはできない。

n個のデータがある場合、時間計算量はO(log _{2}n)である(O記法)。

n個のデータの中央の値を見ることで、1回の操作でn/2個程度(奇数の場合は(n-1)/2個、偶数の場合はn/2個または(n/2)-1個)の要素を無視することができる。

https://ja.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%8E%A2%E7%B4%A2

より

ソース

2分探索ソースがこちらです。

関数 binarySearch は、探索する配列と探索対象を受け取り結果のインデックスを返します。見つからなかったら-1を返します。

このサンプルでは検索結果のインデックスとともに探索時の最後に絞った探索範囲の最小値と最大値を返しています。

/**
 * 2分探索
 * @param Array arr ソート済みの探索対象配列
 * @param Int target 探索する値
 * @return Array 探索結果の添字 見つからなかった場合は-1を返す
 */
function binarySearch(arr, target) {
    let idx = -1;
    let iMin = 0;
    let iMax = arr.length - 1;
    while (iMin <= iMax) {
        let iMid = Math.floor((iMin + iMax) / 2);
        if (arr[iMid] === target) {
            idx = iMid;
            break;
        } else if (arr[iMid] < target) {
            iMin = iMid + 1;
        } else {
            iMax = iMid - 1;
        }
    }
    return [idx, iMin, iMax]
}

//
// sample
//
let data = [0,9,1,8,2,7,3,6,4,5,10].sort((a,b) => a-b)
console.log(data)
// 0,1,2,3,4,5,6,7,8,9,10
let [idx, iMin, iMax] = binarySearch(data, 4)
console.log([idx, iMin, iMax])
// 4,4,4

参考

https://ja.wikipedia.org/wiki/2分探索

https://qiita.com/may88seiji/items/189002cb497e61578114

Tags
javascript(103)
linux(54)
amazon%20aws(47)
node.js(43)
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0(36)
typescript(33)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86(30)
html5(29)
php(24)
centos(24)
python(22)
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0(21)
mac(21)
mysql(19)
canvas(18)
opencv(17)
%E9%9B%91%E8%AB%87(16)
docker(16)
wordpress(15)
atcoder(14)
apache(12)
%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92(12)
%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9(12)
amazon%20s3(12)
red%20hat(12)
ubuntu(11)
github(10)
git(10)
vue.js(10)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86100%E6%9C%AC%E3%83%8E%E3%83%83%E3%82%AF(10)
mariadb(10)
aws%20cdk(9)
css3(8)
%E5%8F%AF%E8%A6%96%E5%8C%96(8)
%E5%B0%8F%E3%83%8D%E3%82%BF(8)
amazon%20lightsail(7)
react(7)
%E3%83%96%E3%83%AD%E3%82%B0(6)
cms(6)
oracle(6)
perl(6)
gitlab(6)
next.js(6)
prisma(6)
iam(5)
amazon%20ec2(5)
%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93(5)
aws%20amplify(5)
nestjs(5)
curl(4)
Author
githubzennqiita
ただの備忘録です。※このブログの内容は個人の見解であり、所属する組織等の見解ではないです。