二分探索木(Binary Search Tree)とは

二分探索木(Binary Search Tree)は、効率的なデータの挿入、検索、削除を可能にするデータ構造です。二分探索木は、各ノードが最大 2 つの子ノードを持ち、以下の性質を満たす特殊な木構造です。

  1. 左の子ノードの値は、親ノードの値よりも小さい(または等しい)。
  2. 右の子ノードの値は、親ノードの値よりも大きい。
    この性質により、二分探索木では効率的な探索が可能になります。要素の追加や検索、削除において、各操作は木の高さに比例する時間で実行されます。木がバランスしている場合、操作の時間計算量は O(log n)となります。

以下に、二分探索木の例を示します。

         8
       /   \
     3      10
   /  \       \
  1    6       14
      / \     /
     4   7   13

この二分探索木では、根ノードの値が 8 であり、左の子ノードの値は 3、右の子ノードの値は 10 です。さらに左の子ノードの左の子ノードは 1、左の子ノードの右の子ノードは 6 といった具合に、各ノードが左右に分岐していきます。

二分探索木では、要素の挿入や検索は再帰的な操作で行われます。挿入する要素は、木の適切な位置に追加されます。検索では、根ノードから始めて探している要素と比較し、左の子ノードまたは右の子ノードに進んでいきます。目的の要素が見つかるまで、再帰的に探索を続けます。

二分探索木の利点は、効率的なデータの挿入や検索が可能な点です。ただし、木のバランスが崩れてしまうと、操作の時間計算量が最悪の場合 O(n)となることがあります。バランスを保つためには、平衡二分探索木(AVL 木や赤黒木など)を使用することが推奨されます。

JavaScript で二分探索木(Binary Search Tree)を実装例

// ノードの定義
class Node {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
  }
}

// 二分探索木の定義
class BinarySearchTree {
  constructor() {
    this.root = null;
  }

  // 要素の挿入
  insert(value) {
    var newNode = new Node(value);

    if (this.root === null) {
      this.root = newNode;
    } else {
      this.insertNode(this.root, newNode);
    }
  }

  insertNode(node, newNode) {
    if (newNode.value < node.value) {
      if (node.left === null) {
        node.left = newNode;
      } else {
        this.insertNode(node.left, newNode);
      }
    } else {
      if (node.right === null) {
        node.right = newNode;
      } else {
        this.insertNode(node.right, newNode);
      }
    }
  }

  // 要素の検索
  search(value) {
    return this.searchNode(this.root, value);
  }

  searchNode(node, value) {
    if (node === null) {
      return false;
    }

    if (value < node.value) {
      return this.searchNode(node.left, value);
    } else if (value > node.value) {
      return this.searchNode(node.right, value);
    } else {
      return true;
    }
  }
}
// 使用例
var bst = new BinarySearchTree();
bst.insert(8);
bst.insert(3);
bst.insert(10);
bst.insert(1);
bst.insert(6);

console.log(bst.search(6)); // true
console.log(bst.search(9)); // false

この実装では、Node クラスと BinarySearchTree クラスを定義しています。Node クラスは二分探索木の各ノードを表し、value(ノードの値)、left(左の子ノードへの参照)、right(右の子ノードへの参照)のプロパティを持ちます。

BinarySearchTree クラスは二分探索木自体を表し、root プロパティが根ノードを指します。insert メソッドは新しい要素を挿入するためのもので、insertNode メソッドを再帰的に呼び出して適切な位置に新しいノードを挿入します。

search メソッドは指定された値を探索するためのもので、searchNode メソッドを再帰的に呼び出して探索を行います。指定された値が存在する場合は true を返し、存在しない場合は false を返します。