1. 空木 -> false
  2. [10,5,15] から 5 -> true
  3. [10,5,15] から 10 -> true
  4. [10,5,15] から 12 -> false
  5. [10,5,15,3,7,null,18] から 7 -> true
  6. [10,5,15,3,7,null,18] から 4 -> false
  7. [10,5,15,3,7,null,18] から 18 -> true
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
BST から値を検索する

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

BST から値を検索する

1000 件から 1 件を探すのに、1000 回

ただ並んでいるだけの 1000 件から目的の値を探すなら、端から順に見ていくしかありません。最悪で 1000 回の比較、10 万件なら 10 万回です。件数が 10 倍になれば、待ち時間も 10 倍になります。

前回、新しい値の置き場所は 1 か所しかないという話をしました。裏を返すと、すでに入っている値を探すときも、通る道は 1 本だけです。しかもこの道は、1 回比べるごとに候補を半分に切り落とします。

半分ずつ捨てる

木を離れて、もっと単純な形で確かめます。昇順に並んだ配列から目的の値を探すとき、真ん中を 1 回見れば、左半分か右半分のどちらかを丸ごと捨てられます。

JavaScript

// 別題材 — 昇順に並んだ配列から探す let lo = 0; let hi = arr.length - 1; while (lo <= hi) { const mid = Math.floor((lo + hi) / 2); if (arr[mid] === target) return true; if (target < arr[mid]) hi = mid - 1; else lo = mid + 1; } return false;

候補は 1000 から 500、250、125 と減っていき、10 回で 1 件まで絞れます。1000 回が 10 回になりました。件数が 100 万件に増えても、20 回で終わります。

木には、その切れ目が最初から引いてある

配列では毎回 mid を計算しました。木では、その計算が要りません。今いるノードの値がそのまま切れ目で、左右どちらへ降りるかを決めた瞬間に、反対側の部分木は候補から丸ごと外れます。

diagram (will load when visible)

7 を探すときに残っている候補を書き出すと、こうなります。

見たノード進む先残る候補
10左5, 3, 7
5右7
7当たりなし

10 で左へ降りた時点で 15 と 18 は二度と見ません。そして 5 で右へ降りれば 3 も消えます。6 個の木が 3 回で片付きました。

無いと分かるのは、進んだ先が空だったときだけです。降りきる前に「見つからない」と答えてはいけません。渡された木が空のときも、最初の 1 歩でいきなり行き止まりなので、同じ答えになります。

半分にならない木もある

[1, 2, 3, 4, 5] をこの順で 1 つずつ入れていくと、右へ右へと伸びた 1 本の棒のような木ができます。分かれ道が 1 つも無いので、降りても候補は 1 つずつしか減りません。比較の回数は件数と同じで、端から順に見ていくのと変わらなくなります。

半分に減るのは、木が左右に散らばっているときだけです。同じ木でも、値を入れた順番しだいで速さがまるで変わります。

要件

  1. 配列 arr は BFS 順、欠損ノードは null (Python では None) で表される
  2. BST の不変条件を活かして左右どちらかの部分木にだけ進む (両方探索しない)
  3. 戻り値は真偽値 (true / false)

入出力例

bstSearch([], 5) → false bstSearch([10,5,15], 5) → true bstSearch([10,5,15], 10) → true bstSearch([10,5,15], 12) → false bstSearch([10,5,15,3,7,null,18], 7) → true bstSearch([10,5,15,3,7,null,18], 4) → false bstSearch([10,5,15,3,7,null,18], 18) → true

ヒント

配列をノードオブジェクトの木に組み立ててから検索すると書きやすい

反復版なら `while node is not None: ...` で進めるだけ

等しい場合 / 小さい場合 / 大きい場合の 3 分岐を漏れなく書く

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • BST の最小値と最大値

    BST の最小値と最大値を返す関数を実装する。BST では最小は左端、最大は右端という性質を活かす。

  • BST 妥当性チェック

    与えられた二分木が BST の不変条件を満たしているか判定する関数を実装する。

  • BST で k 番目に小さい値

    BST の in-order 走査が昇順になる性質を使い、k 番目に小さい値を返す関数を実装する。

  • BST から値を削除する

    BST から指定の値を削除し、削除後の in-order 走査結果を配列で返す関数を実装する。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 配列サイズ固定の同型データの集まり
  • None「値がない」ことを表す特別な値。
  • 戻り値呼び出し元への返答を表す点線矢印
main.py
学習モード
エディタを読み込んでいます

メモ

BST から値を検索する

⌘S で保存