二分探索木(BST)

ランダムな二分探索木から始めて、値の挿入・検索・削除をステップごとに確認します。配列表現とハイライトされたC++コードも表示します。

すべてこのブラウザ内でシミュレートされ、サーバーには一切送信されません。

ステップなし

ステップなし

二分探索木

配列インデックス

60[0]45[1]85[2]68[5]21[3]55[4]32[8]

配列表現

インデックスiの子は2i+1と2i+2にあります。

  • 無関係
  • 通過済み
  • 比較中
  • 発見
  • 新規
  • 削除対象
  • 後続ノード

ステップなし

コード

#include <iostream>
using namespace std;
class Node { // ノードは値と2つの子へのポインタを保持します
private: // プライベート属性:メソッドだけが触れます
int value;
Node* left;
Node* right;
public:
Node(int v) : value(v), left(nullptr), right(nullptr) {}
int getValue() const { return value; }
Node* getLeft() const { return left; }
Node* getRight() const { return right; }
void setValue(int v) { value = v; }
void setLeft(Node* n) { left = n; }
void setRight(Node* n) { right = n; }
};
Node* insert(Node* root, int v) { // v を探索木に挿入し、根を返します
if (root == nullptr) // 空きの位置: 新しいノードはここに入ります
return new Node(v); // 新しいノードを作成します
if (v < root->getValue()) // 小さい値は左へ、大きい値は右へ進みます
root->setLeft(insert(root->getLeft(), v)); // 左の部分木を下ります
else
root->setRight(insert(root->getRight(), v)); // 右の部分木を下ります
return root;
}
int main() {
Node* root = buildTree(); // 表示中の木(構築済み)
root = insert(root, v); // main からの最初の呼び出し
return 0; // 操作の終了
}

このツールは、ランダムな二分探索木(BST)から始まり、手動で変更できます。1から99の値を入力して、挿入、検索、削除を押します。各操作は木の上でステップごとにアニメーション表示され、ノードは比較中、通過済み、新規、削除対象、後継といった役割で色分けされます。下には同じ木の配列表現も表示され、対応するC++コードの行も強調されます。BSTの仕組みを学ぶのに便利で、処理はブラウザー内で行われます。

使い方

  1. スライダーで木のサイズを設定するか、「新しい木を生成」を押して開始状態を変えます。
  2. 1から99の値を入力して、挿入、検索、削除を押します。アニメーションは自動で始まります。
  3. 前へ・次へのボタンで進めたり戻したり、または「再生」を押して速度を変更します。
  4. 色付きのノード、木の配列表現、強調されるC++コードの行を確認します。

よくある質問

二分探索木とは何ですか?どんな性質を保ちますか?
各ノードが最大2つの子を持ち、左の部分木の値がすべてそのノードより小さく、右の部分木の値がすべて大きい二分木です。この性質により、比較のたびに残りの経路の半分を除外できます。
BSTの挿入と検索はどう動き、コストはどれくらいですか?
どちらも根から始め、各ノードと値を比較します。小さければ左、大きければ右へ進みます。検索は値が見つかるかnullptrに達すると終了し、挿入はその空いた位置に新しいノードを作ります。コストは木の高さに比例し、平衡していれば対数、1本の鎖状なら線形です。
削除の3つのケースとは?なぜ中順後継を使うのですか?
葉ならそのまま削除し、子が1つならその子が代わりに入り、子が2つなら右の部分木の最小値である中順後継の値をコピーして、後継のノードを削除します。後継は順序で次の値なので、BSTの性質を保ったまま収まり、左の子がないため削除も簡単なケースになります。
木は配列にどう格納され、空きができるのはなぜですか?
ヒープ配置で、根はインデックス0、インデックスiの子は2i+1と2i+2に入ります。子がない位置は空のままで、木が偏るほど深さとともにインデックスが増えるため、空きが多くなります。

関連ツール